diff --git a/schala-lang/src/identifier.rs b/schala-lang/src/identifier.rs index 22299fa..95630f4 100644 --- a/schala-lang/src/identifier.rs +++ b/schala-lang/src/identifier.rs @@ -38,6 +38,7 @@ where T: IdKind } } +#[derive(Debug)] pub struct IdStore where T: IdKind { diff --git a/schala-lang/src/parsing/combinator.rs b/schala-lang/src/parsing/combinator.rs index a0a4f9c..5f2e8cc 100644 --- a/schala-lang/src/parsing/combinator.rs +++ b/schala-lang/src/parsing/combinator.rs @@ -11,8 +11,12 @@ use nom::{ }; use nom_locate::{position, LocatedSpan}; use std::rc::Rc; +use std::cell::RefCell; +use crate::identifier::{Id, IdStore}; -type Span<'a> = LocatedSpan<&'a str>; +type StoreRef = Rc>>; + +type Span<'a> = LocatedSpan<&'a str, StoreRef>; type ParseResult<'a, O> = IResult, O, VerboseError>>; use crate::ast::*; @@ -20,6 +24,10 @@ use crate::ast::*; fn rc_string(s: &str) -> Rc { Rc::new(s.to_string()) } +fn fresh_id(span: &Span) -> Id { + let mut table_handle = span.extra.borrow_mut(); + table_handle.fresh() +} fn tok<'a, O>(input_parser: impl Parser, O, VerboseError>>) -> impl FnMut(Span<'a>) -> IResult, O, VerboseError>> { @@ -91,18 +99,21 @@ fn block(input: Span) -> ParseResult { } fn statement(input: Span) -> ParseResult { - let pos: usize = position(input)?.1.location_offset(); + let (input, pos) = position(input)?; + let pos: usize = pos.location_offset(); + let id = fresh_id(&input); context("Parsing-statement", map(expression, move |expr| Statement { - id: Default::default(), + id, location: pos.into(), kind: StatementKind::Expression(expr), }))(input) } fn expression(input: Span) -> ParseResult { - map(pair(expression_kind, opt(type_anno)), |(kind, maybe_anno)| { - Expression::new(Default::default(), kind) + let id = fresh_id(&input); + map(pair(expression_kind, opt(type_anno)), move |(kind, maybe_anno)| { + Expression::new(id, kind) })(input) } @@ -143,10 +154,11 @@ fn identifier_expr(input: Span) -> ParseResult { } fn qualified_identifier(input: Span) -> ParseResult { + let id = fresh_id(&input); tok( map( separated_list1(tag("::"), map(identifier, |x| rc_string(x.fragment()))), - |items| QualifiedName { id: Default::default(), components: items } + move |items| QualifiedName { id, components: items } ))(input) } @@ -271,7 +283,12 @@ mod test { macro_rules! span { ($func:expr, $input:expr) => { - $func(Span::new($input)).map(|(span, x)| (*span.fragment(), x)) + { + let id_store: IdStore = IdStore::new(); + let span = Span::new_extra($input, + Rc::new(RefCell::new(id_store))); + $func(span).map(|(span, x)| (*span.fragment(), x)) + } }; }