Handle local variables and function params in symbol table
This commit is contained in:
parent
9540dc70f2
commit
82de5c6e27
@ -126,6 +126,7 @@ impl<'a> Reducer<'a> {
|
|||||||
},
|
},
|
||||||
SymbolSpec::Func(_) => Expr::Sym(local_name.clone()),
|
SymbolSpec::Func(_) => Expr::Sym(local_name.clone()),
|
||||||
SymbolSpec::GlobalBinding => Expr::Sym(local_name.clone()), //TODO not sure if this is right, probably needs to eventually be fqsn
|
SymbolSpec::GlobalBinding => Expr::Sym(local_name.clone()), //TODO not sure if this is right, probably needs to eventually be fqsn
|
||||||
|
_ => Expr::UnimplementedSigilValue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use symbol_trie::SymbolTrie;
|
|||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
|
||||||
|
//TODO parameterize different types of ID
|
||||||
/// ID used for definitions
|
/// ID used for definitions
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Default)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone, Default)]
|
||||||
pub struct DefId {
|
pub struct DefId {
|
||||||
@ -199,7 +200,7 @@ impl SymbolTable {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Symbol {
|
pub struct Symbol {
|
||||||
pub local_name: Rc<String>,
|
pub local_name: Rc<String>, //TODO get rid of this, it can be computed from fqsn
|
||||||
fully_qualified_name: Fqsn,
|
fully_qualified_name: Fqsn,
|
||||||
pub spec: SymbolSpec,
|
pub spec: SymbolSpec,
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
@ -211,6 +212,15 @@ impl fmt::Display for Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO - I think I eventually want to draw a distinction between true global items
|
||||||
|
//i.e. global vars, and items whose definitions are scoped. Right now there's a sense
|
||||||
|
//in which Func, DataConstructor, RecordConstructor, and GlobalBinding are "globals",
|
||||||
|
//whereas LocalVarible and FunctionParam have local scope. But right now, they all
|
||||||
|
//get put into a common table, and all get DefId's from a common source.
|
||||||
|
//
|
||||||
|
//It would be good if individual functions could in parallel look up their own
|
||||||
|
//local vars without interfering with other lookups. Also some type definitions
|
||||||
|
//should be scoped in a similar way.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SymbolSpec {
|
pub enum SymbolSpec {
|
||||||
Func(Vec<TypeName>),
|
Func(Vec<TypeName>),
|
||||||
@ -225,6 +235,8 @@ pub enum SymbolSpec {
|
|||||||
type_name: TypeName,
|
type_name: TypeName,
|
||||||
},
|
},
|
||||||
GlobalBinding, //Only for global variables, not for function-local ones or ones within a `let` scope context
|
GlobalBinding, //Only for global variables, not for function-local ones or ones within a `let` scope context
|
||||||
|
LocalVariable,
|
||||||
|
FunctionParam(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for SymbolSpec {
|
impl fmt::Display for SymbolSpec {
|
||||||
@ -249,6 +261,8 @@ impl fmt::Display for SymbolSpec {
|
|||||||
index, type_name
|
index, type_name
|
||||||
),
|
),
|
||||||
GlobalBinding => write!(f, "GlobalBinding"),
|
GlobalBinding => write!(f, "GlobalBinding"),
|
||||||
|
LocalVariable => write!(f, "Local variable"),
|
||||||
|
FunctionParam(n) => write!(f, "Function param: {}", n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::symbol_table::{Fqsn, Scope, SymbolTable, DefId};
|
use crate::symbol_table::{Fqsn, Scope, SymbolTable, Symbol, SymbolSpec, DefId};
|
||||||
use crate::util::ScopeStack;
|
use crate::util::ScopeStack;
|
||||||
|
|
||||||
type FqsnPrefix = Vec<Scope>;
|
type FqsnPrefix = Vec<Scope>;
|
||||||
@ -82,8 +82,16 @@ impl<'a> ScopeResolver<'a> {
|
|||||||
self.symbol_table.id_to_symbol.insert(id.clone(), symbol.clone());
|
self.symbol_table.id_to_symbol.insert(id.clone(), symbol.clone());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(NameType::Param(n)) => (),
|
Some(NameType::Param(n)) => {
|
||||||
Some(NameType::LocalVariable) => (),
|
let spec = SymbolSpec::FunctionParam(*n);
|
||||||
|
let fqsn = Fqsn { scopes: vec![Scope::Name(local_name.clone())] };
|
||||||
|
self.symbol_table.add_symbol(id, fqsn, spec);
|
||||||
|
}
|
||||||
|
Some(NameType::LocalVariable) => {
|
||||||
|
let spec = SymbolSpec::LocalVariable;
|
||||||
|
let fqsn = Fqsn { scopes: vec![Scope::Name(local_name.clone())] };
|
||||||
|
self.symbol_table.add_symbol(id, fqsn, spec);
|
||||||
|
},
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -151,7 +159,7 @@ impl<'a> ASTVisitor for ScopeResolver<'a> {
|
|||||||
let param_names = signature.params.iter().map(|param| param.name.clone());
|
let param_names = signature.params.iter().map(|param| param.name.clone());
|
||||||
//TODO I'm 90% sure this is right, until I get to closures
|
//TODO I'm 90% sure this is right, until I get to closures
|
||||||
//let mut new_scope = self.lexical_scopes.new_scope(Some(ScopeType::Function { name: signature.name.clone() }));
|
//let mut new_scope = self.lexical_scopes.new_scope(Some(ScopeType::Function { name: signature.name.clone() }));
|
||||||
let mut new_scope = ScopeStack::new(None);
|
let mut new_scope = ScopeStack::new(Some(ScopeType::Function { name: signature.name.clone() }));
|
||||||
|
|
||||||
for (n, param) in param_names.enumerate().into_iter() {
|
for (n, param) in param_names.enumerate().into_iter() {
|
||||||
new_scope.insert(param, NameType::Param(n as u8));
|
new_scope.insert(param, NameType::Param(n as u8));
|
||||||
|
Loading…
Reference in New Issue
Block a user