Resolver - Store declaration tokens as references
This commit is contained in:
parent
34991d4b4b
commit
8741692fad
1 changed files with 41 additions and 18 deletions
|
@ -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)?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue