Resolver - Store declaration tokens as references

This commit is contained in:
Emmanuel BENOîT 2023-01-07 11:55:41 +01:00
parent 34991d4b4b
commit 8741692fad

View file

@ -41,23 +41,23 @@ enum SymKind {
/// General information about a symbol. /// General information about a symbol.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct SymInfo { struct SymInfo<'a> {
decl: Token, decl: &'a Token,
kind: SymKind, kind: SymKind,
state: SymState, state: SymState,
} }
/// The state of the resolver. /// The state of the resolver.
#[derive(Default)] #[derive(Default)]
struct ResolverState { struct ResolverState<'a> {
/// The stack of scopes. Each scope maps symbols to information which /// The stack of scopes. Each scope maps symbols to information which
/// includes the kind of symbol it is and its current state. /// includes the kind of symbol it is and its current state.
scopes: Vec<HashMap<String, SymInfo>>, scopes: Vec<HashMap<String, SymInfo<'a>>>,
/// The result of the resolver pass. /// The result of the resolver pass.
resolved: ResolvedVariables, resolved: ResolvedVariables,
} }
impl ResolverState { impl<'a> ResolverState<'a> {
/// Execute some function with a new scope. The scope will be disposed /// Execute some function with a new scope. The scope will be disposed
/// of after the function has been executed. /// of after the function has been executed.
fn with_scope<F>(&mut self, f: F) -> ResolverResult fn with_scope<F>(&mut self, f: F) -> ResolverResult
@ -88,7 +88,10 @@ impl ResolverState {
/// Try to declare a symbol. If the scope already contains a declaration /// Try to declare a symbol. If the scope already contains a declaration
/// for the same name, return an error. /// for the same name, return an error.
fn declare(&mut self, name: &Token, kind: SymKind) -> ResolverResult { fn declare<'b>(&mut self, name: &'b Token, kind: SymKind) -> ResolverResult
where
'b: 'a,
{
assert!(!self.scopes.is_empty()); assert!(!self.scopes.is_empty());
let idx = self.scopes.len() - 1; let idx = self.scopes.len() - 1;
let scope = &mut self.scopes[idx]; let scope = &mut self.scopes[idx];
@ -102,7 +105,7 @@ impl ResolverState {
scope.insert( scope.insert(
name.lexeme.clone(), name.lexeme.clone(),
SymInfo { SymInfo {
decl: name.clone(), decl: name,
kind, kind,
state: SymState::Declared, state: SymState::Declared,
}, },
@ -188,11 +191,14 @@ impl ResolverState {
} }
/// Process a function declaration. /// Process a function declaration.
fn resolve_function( fn resolve_function<'a, 'b>(
rs: &mut ResolverState, rs: &mut ResolverState<'a>,
params: &[Token], params: &'b [Token],
body: &Vec<ast::StmtNode>, body: &'b Vec<ast::StmtNode>,
) -> ResolverResult { ) -> ResolverResult
where
'b: 'a,
{
for param in params { for param in params {
rs.declare(param, SymKind::Variable)?; rs.declare(param, SymKind::Variable)?;
rs.define(param); rs.define(param);
@ -205,17 +211,25 @@ fn resolve_function(
/// Helper trait used to visit the various AST nodes with the resolver. /// Helper trait used to visit the various AST nodes with the resolver.
trait VarResolver { trait VarResolver {
/// Try to resolve local variables under some AST node. /// Try to resolve local variables under some AST node.
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult; fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b;
} }
impl VarResolver for ast::ProgramNode { impl VarResolver for ast::ProgramNode {
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult { fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b,
{
self.0.resolve(rs) self.0.resolve(rs)
} }
} }
impl VarResolver for Vec<ast::StmtNode> { impl VarResolver for Vec<ast::StmtNode> {
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult { fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b,
{
for stmt in self.iter() { for stmt in self.iter() {
stmt.resolve(rs)?; stmt.resolve(rs)?;
} }
@ -224,7 +238,10 @@ impl VarResolver for Vec<ast::StmtNode> {
} }
impl VarResolver for ast::StmtNode { impl VarResolver for ast::StmtNode {
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult { fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b,
{
match self { match self {
ast::StmtNode::Block(stmts) => rs.with_scope(|rs| stmts.resolve(rs)), ast::StmtNode::Block(stmts) => rs.with_scope(|rs| stmts.resolve(rs)),
@ -295,7 +312,10 @@ impl VarResolver for ast::StmtNode {
} }
impl VarResolver for ast::ExprNode { impl VarResolver for ast::ExprNode {
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult { fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b,
{
match self { match self {
ast::ExprNode::Variable { name, id } => rs.resolve_use(id, name), ast::ExprNode::Variable { name, id } => rs.resolve_use(id, name),
@ -331,7 +351,10 @@ impl VarResolver for ast::ExprNode {
} }
impl VarResolver for Vec<ast::ExprNode> { impl VarResolver for Vec<ast::ExprNode> {
fn resolve(&self, rs: &mut ResolverState) -> ResolverResult { fn resolve<'a, 'b>(&'a self, rs: &mut ResolverState<'b>) -> ResolverResult
where
'a: 'b,
{
for expr in self.iter() { for expr in self.iter() {
expr.resolve(rs)?; expr.resolve(rs)?;
} }