Refactored scoping

This commit is contained in:
2026-04-16 09:59:07 +02:00
parent 8ed8eed5de
commit 819441bc29
2 changed files with 45 additions and 84 deletions
+15 -21
View File
@@ -124,31 +124,25 @@ impl TopLevelHirScope {
if let Some(tlss_rf) = tlss.structs.get(&symbol.0) { if let Some(tlss_rf) = tlss.structs.get(&symbol.0) {
let struct_ref = self.struct_ref(tlss, tlss_rf); let struct_ref = self.struct_ref(tlss, tlss_rf);
self.variables let var_ref = Arc::new(VarRef {
.insert(
symbol.0.clone(),
Arc::new(VarRef {
name: symbol.0.clone(), name: symbol.0.clone(),
var_type: struct_ref, var_type: struct_ref,
}), });
) self.variables.insert(symbol.0.clone(), var_ref.clone());
.unwrap()
.var_type var_ref.var_type.clone()
.clone()
} else { } else {
match symbol.0.as_str() { match symbol.0.as_str() {
"int" => self "int" => {
.variables let var_ref = Arc::new(VarRef {
.insert(
symbol.0.clone(),
Arc::new(VarRef {
name: symbol.0.clone(), name: symbol.0.clone(),
var_type: Arc::new(TypeRef::Int), var_type: Arc::new(TypeRef::Int),
}), });
)
.unwrap() self.variables.insert(symbol.0.clone(), var_ref.clone());
.var_type
.clone(), var_ref.var_type.clone()
}
_ => { _ => {
unimplemented!("{:?}", symbol) unimplemented!("{:?}", symbol)
@@ -158,7 +152,7 @@ impl TopLevelHirScope {
} }
} }
pub fn get_reference(&self, name: &String) -> Option<&Arc<VarRef>> { pub fn get_reference(&self, name: &String) -> Option<Arc<VarRef>> {
self.variables.get(name) self.variables.get(name).cloned()
} }
} }
+26 -59
View File
@@ -6,17 +6,10 @@ use std::{
use parser::ast::{self, ParamList, Postfix, Statement}; use parser::ast::{self, ParamList, Postfix, Statement};
use crate::{ use crate::{
hir::{FunctionRef, TopLevelHirScope, TypeRef, VarRef}, hir::{TopLevelHirScope, TypeRef, VarRef},
top_level::TopLevelSymbolScope, top_level::TopLevelSymbolScope,
}; };
#[derive(Clone, Debug)]
pub enum Reference {
Type(Arc<TypeRef>),
Var(Arc<VarRef>),
Func(Arc<FunctionRef>),
}
#[derive(Debug)] #[derive(Debug)]
pub enum Scope { pub enum Scope {
TopLevel(TopLevelHirScope), TopLevel(TopLevelHirScope),
@@ -29,7 +22,7 @@ impl Scope {
Arc::new(Self::TopLevel(TopLevelHirScope::from_tlss(&tl))) 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 { match self {
Scope::TopLevel(tl) => tl.get_reference(name), Scope::TopLevel(tl) => tl.get_reference(name),
Scope::Local(l) => l.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 self.variables
.lock() .lock()
.unwrap() .unwrap()
.get(name) .get(name)
.cloned() .cloned()
.map(Reference::Var)
.or_else(|| self.parent.get_reference(name)) .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>> { pub fn get_type_from_expr(self: &Arc<Self>, expr: &ast::Expression) -> Option<Arc<TypeRef>> {
match expr { match expr {
ast::Expression::IntLiteral(_) => { ast::Expression::IntLiteral(_) => self
self.parent.get_reference(&"int".to_string()).map(|r| { .parent
if let Reference::Type(tr) = &r { .get_reference(&"int".to_string())
tr.clone() .map(|r| r.var_type.clone()),
} else {
unimplemented!()
}
})
}
ast::Expression::FloatLiteral(_) => { ast::Expression::FloatLiteral(_) => self
self.parent.get_reference(&"float".to_string()).map(|r| { .parent
if let Reference::Type(tr) = &r { .get_reference(&"float".to_string())
tr.clone() .map(|r| r.var_type.clone()),
} else {
unimplemented!()
}
})
}
ast::Expression::BoolLiteral(_) => { ast::Expression::BoolLiteral(_) => self
self.parent.get_reference(&"bool".to_string()).map(|r| { .parent
if let Reference::Type(tr) = &r { .get_reference(&"bool".to_string())
tr.clone() .map(|r| r.var_type.clone()),
} else {
unimplemented!()
}
})
}
ast::Expression::StringLiteral(_) => { ast::Expression::StringLiteral(_) => self
self.parent.get_reference(&"string".to_string()).map(|r| { .parent
if let Reference::Type(tr) = &r { .get_reference(&"string".to_string())
tr.clone() .map(|r| r.var_type.clone()),
} else {
unimplemented!()
}
})
}
ast::Expression::Identifier(id) => match self.get_reference(id) { ast::Expression::Identifier(id) => self.get_reference(id).map(|r| r.var_type.clone()),
Some(Reference::Var(var_ref)) => Some(var_ref.var_type.clone()),
Some(Reference::Func(func_ref)) => func_ref.return_type.clone(),
_ => None,
},
ast::Expression::Postfix { initial, postfixes } => { ast::Expression::Postfix { initial, postfixes } => {
self.walk_postfixes(initial, postfixes) self.walk_postfixes(initial, postfixes)
} }
_ => unimplemented!(),
} }
} }
pub fn with_params(self: &Arc<Self>, param_list: &ParamList) { pub fn with_params(self: &Arc<Self>, param_list: &ParamList) {
for (param_name, type_expr) in &param_list.0 { for (param_name, type_expr) in &param_list.0 {
match type_expr { match type_expr {
parser::ast::TypeExpr::Identifier(id) => match self.parent.get_reference(id) { parser::ast::TypeExpr::Identifier(id) => {
Some(Reference::Type(type_ref)) => { if let Some(var_type) =
self.parent.get_reference(id).map(|r| r.var_type.clone())
{
self.variables.lock().unwrap().insert( self.variables.lock().unwrap().insert(
param_name.clone(), param_name.clone(),
Arc::new(VarRef { Arc::new(VarRef {
var_type: type_ref, var_type,
name: param_name.clone(), name: param_name.clone(),
}), }),
); );
} }
_ => unimplemented!(), }
},
} }
} }
} }