Refactored scoping
This commit is contained in:
+26
-59
@@ -6,17 +6,10 @@ use std::{
|
||||
use parser::ast::{self, ParamList, Postfix, Statement};
|
||||
|
||||
use crate::{
|
||||
hir::{FunctionRef, TopLevelHirScope, TypeRef, VarRef},
|
||||
hir::{TopLevelHirScope, TypeRef, VarRef},
|
||||
top_level::TopLevelSymbolScope,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Reference {
|
||||
Type(Arc<TypeRef>),
|
||||
Var(Arc<VarRef>),
|
||||
Func(Arc<FunctionRef>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Scope {
|
||||
TopLevel(TopLevelHirScope),
|
||||
@@ -29,7 +22,7 @@ impl Scope {
|
||||
Arc::new(Self::TopLevel(TopLevelHirScope::from_tlss(&tl)))
|
||||
}
|
||||
|
||||
pub fn get_reference(&self, name: &String) -> Option<Reference> {
|
||||
pub fn get_reference(&self, name: &String) -> Option<Arc<VarRef>> {
|
||||
match self {
|
||||
Scope::TopLevel(tl) => tl.get_reference(name),
|
||||
Scope::Local(l) => l.get_reference(name),
|
||||
@@ -51,13 +44,12 @@ impl LocalScope {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_reference(&self, name: &String) -> Option<Reference> {
|
||||
pub fn get_reference(&self, name: &String) -> Option<Arc<VarRef>> {
|
||||
self.variables
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(name)
|
||||
.cloned()
|
||||
.map(Reference::Var)
|
||||
.or_else(|| self.parent.get_reference(name))
|
||||
}
|
||||
|
||||
@@ -109,75 +101,50 @@ impl LocalScope {
|
||||
|
||||
pub fn get_type_from_expr(self: &Arc<Self>, expr: &ast::Expression) -> Option<Arc<TypeRef>> {
|
||||
match expr {
|
||||
ast::Expression::IntLiteral(_) => {
|
||||
self.parent.get_reference(&"int".to_string()).map(|r| {
|
||||
if let Reference::Type(tr) = &r {
|
||||
tr.clone()
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::Expression::IntLiteral(_) => self
|
||||
.parent
|
||||
.get_reference(&"int".to_string())
|
||||
.map(|r| r.var_type.clone()),
|
||||
|
||||
ast::Expression::FloatLiteral(_) => {
|
||||
self.parent.get_reference(&"float".to_string()).map(|r| {
|
||||
if let Reference::Type(tr) = &r {
|
||||
tr.clone()
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::Expression::FloatLiteral(_) => self
|
||||
.parent
|
||||
.get_reference(&"float".to_string())
|
||||
.map(|r| r.var_type.clone()),
|
||||
|
||||
ast::Expression::BoolLiteral(_) => {
|
||||
self.parent.get_reference(&"bool".to_string()).map(|r| {
|
||||
if let Reference::Type(tr) = &r {
|
||||
tr.clone()
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::Expression::BoolLiteral(_) => self
|
||||
.parent
|
||||
.get_reference(&"bool".to_string())
|
||||
.map(|r| r.var_type.clone()),
|
||||
|
||||
ast::Expression::StringLiteral(_) => {
|
||||
self.parent.get_reference(&"string".to_string()).map(|r| {
|
||||
if let Reference::Type(tr) = &r {
|
||||
tr.clone()
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
})
|
||||
}
|
||||
ast::Expression::StringLiteral(_) => self
|
||||
.parent
|
||||
.get_reference(&"string".to_string())
|
||||
.map(|r| r.var_type.clone()),
|
||||
|
||||
ast::Expression::Identifier(id) => match self.get_reference(id) {
|
||||
Some(Reference::Var(var_ref)) => Some(var_ref.var_type.clone()),
|
||||
Some(Reference::Func(func_ref)) => func_ref.return_type.clone(),
|
||||
_ => None,
|
||||
},
|
||||
ast::Expression::Identifier(id) => self.get_reference(id).map(|r| r.var_type.clone()),
|
||||
|
||||
ast::Expression::Postfix { initial, postfixes } => {
|
||||
self.walk_postfixes(initial, postfixes)
|
||||
}
|
||||
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_params(self: &Arc<Self>, param_list: &ParamList) {
|
||||
for (param_name, type_expr) in ¶m_list.0 {
|
||||
match type_expr {
|
||||
parser::ast::TypeExpr::Identifier(id) => match self.parent.get_reference(id) {
|
||||
Some(Reference::Type(type_ref)) => {
|
||||
parser::ast::TypeExpr::Identifier(id) => {
|
||||
if let Some(var_type) =
|
||||
self.parent.get_reference(id).map(|r| r.var_type.clone())
|
||||
{
|
||||
self.variables.lock().unwrap().insert(
|
||||
param_name.clone(),
|
||||
Arc::new(VarRef {
|
||||
var_type: type_ref,
|
||||
var_type,
|
||||
name: param_name.clone(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user