Refactored scoping
This commit is contained in:
+19
-25
@@ -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(
|
name: symbol.0.clone(),
|
||||||
symbol.0.clone(),
|
var_type: struct_ref,
|
||||||
Arc::new(VarRef {
|
});
|
||||||
name: symbol.0.clone(),
|
self.variables.insert(symbol.0.clone(), var_ref.clone());
|
||||||
var_type: struct_ref,
|
|
||||||
}),
|
var_ref.var_type.clone()
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.var_type
|
|
||||||
.clone()
|
|
||||||
} else {
|
} else {
|
||||||
match symbol.0.as_str() {
|
match symbol.0.as_str() {
|
||||||
"int" => self
|
"int" => {
|
||||||
.variables
|
let var_ref = Arc::new(VarRef {
|
||||||
.insert(
|
name: symbol.0.clone(),
|
||||||
symbol.0.clone(),
|
var_type: Arc::new(TypeRef::Int),
|
||||||
Arc::new(VarRef {
|
});
|
||||||
name: symbol.0.clone(),
|
|
||||||
var_type: Arc::new(TypeRef::Int),
|
self.variables.insert(symbol.0.clone(), var_ref.clone());
|
||||||
}),
|
|
||||||
)
|
var_ref.var_type.clone()
|
||||||
.unwrap()
|
}
|
||||||
.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
@@ -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 ¶m_list.0 {
|
for (param_name, type_expr) in ¶m_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!(),
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user