Get fresh IDs from span

This commit is contained in:
Greg Shuflin 2021-11-17 12:45:42 -08:00
parent 222e0aad08
commit f1ffeb155a
2 changed files with 25 additions and 7 deletions

View File

@ -38,6 +38,7 @@ where T: IdKind
} }
} }
#[derive(Debug)]
pub struct IdStore<T> pub struct IdStore<T>
where T: IdKind where T: IdKind
{ {

View File

@ -11,8 +11,12 @@ use nom::{
}; };
use nom_locate::{position, LocatedSpan}; use nom_locate::{position, LocatedSpan};
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell;
use crate::identifier::{Id, IdStore};
type Span<'a> = LocatedSpan<&'a str>; type StoreRef = Rc<RefCell<IdStore<ASTItem>>>;
type Span<'a> = LocatedSpan<&'a str, StoreRef>;
type ParseResult<'a, O> = IResult<Span<'a>, O, VerboseError<Span<'a>>>; type ParseResult<'a, O> = IResult<Span<'a>, O, VerboseError<Span<'a>>>;
use crate::ast::*; use crate::ast::*;
@ -20,6 +24,10 @@ use crate::ast::*;
fn rc_string(s: &str) -> Rc<String> { fn rc_string(s: &str) -> Rc<String> {
Rc::new(s.to_string()) Rc::new(s.to_string())
} }
fn fresh_id(span: &Span) -> Id<ASTItem> {
let mut table_handle = span.extra.borrow_mut();
table_handle.fresh()
}
fn tok<'a, O>(input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>) -> impl FnMut(Span<'a>) fn tok<'a, O>(input_parser: impl Parser<Span<'a>, O, VerboseError<Span<'a>>>) -> impl FnMut(Span<'a>)
-> IResult<Span<'a>, O, VerboseError<Span<'a>>> { -> IResult<Span<'a>, O, VerboseError<Span<'a>>> {
@ -91,18 +99,21 @@ fn block(input: Span) -> ParseResult<Block> {
} }
fn statement(input: Span) -> ParseResult<Statement> { fn statement(input: Span) -> ParseResult<Statement> {
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", context("Parsing-statement",
map(expression, move |expr| Statement { map(expression, move |expr| Statement {
id: Default::default(), id,
location: pos.into(), location: pos.into(),
kind: StatementKind::Expression(expr), kind: StatementKind::Expression(expr),
}))(input) }))(input)
} }
fn expression(input: Span) -> ParseResult<Expression> { fn expression(input: Span) -> ParseResult<Expression> {
map(pair(expression_kind, opt(type_anno)), |(kind, maybe_anno)| { let id = fresh_id(&input);
Expression::new(Default::default(), kind) map(pair(expression_kind, opt(type_anno)), move |(kind, maybe_anno)| {
Expression::new(id, kind)
})(input) })(input)
} }
@ -143,10 +154,11 @@ fn identifier_expr(input: Span) -> ParseResult<ExpressionKind> {
} }
fn qualified_identifier(input: Span) -> ParseResult<QualifiedName> { fn qualified_identifier(input: Span) -> ParseResult<QualifiedName> {
let id = fresh_id(&input);
tok( tok(
map( map(
separated_list1(tag("::"), map(identifier, |x| rc_string(x.fragment()))), separated_list1(tag("::"), map(identifier, |x| rc_string(x.fragment()))),
|items| QualifiedName { id: Default::default(), components: items } move |items| QualifiedName { id, components: items }
))(input) ))(input)
} }
@ -271,7 +283,12 @@ mod test {
macro_rules! span { macro_rules! span {
($func:expr, $input:expr) => { ($func:expr, $input:expr) => {
$func(Span::new($input)).map(|(span, x)| (*span.fragment(), x)) {
let id_store: IdStore<ASTItem> = IdStore::new();
let span = Span::new_extra($input,
Rc::new(RefCell::new(id_store)));
$func(span).map(|(span, x)| (*span.fragment(), x))
}
}; };
} }