Merge pull request #8 from mist-go/improved-type-checking

Improved type checking
This commit is contained in:
2026-04-16 08:47:24 +02:00
committed by GitHub
3 changed files with 65 additions and 20 deletions
+4 -4
View File
@@ -1,7 +1,7 @@
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
use crate::{ use crate::{
scope::Refrence, scope::Reference,
top_level::{FunctionSymbol, StructSymbol, TopLevelSymbolScope, TypeSymbol, VarSymbol}, top_level::{FunctionSymbol, StructSymbol, TopLevelSymbolScope, TypeSymbol, VarSymbol},
}; };
@@ -162,11 +162,11 @@ impl TopLevelHirScope {
} }
} }
pub fn get_refrence(&self, name: &String) -> Option<Refrence> { pub fn get_reference(&self, name: &String) -> Option<Reference> {
if let Some(r) = self.functions.get(name) { if let Some(r) = self.functions.get(name) {
Some(Refrence::Func(r.clone())) Some(Reference::Func(r.clone()))
} else if let Some(r) = self.types.get(name) { } else if let Some(r) = self.types.get(name) {
Some(Refrence::Type(r.clone())) Some(Reference::Type(r.clone()))
} else { } else {
None None
} }
+59 -16
View File
@@ -11,7 +11,7 @@ use crate::{
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Refrence { pub enum Reference {
Type(Arc<TypeRef>), Type(Arc<TypeRef>),
Var(Arc<VarRef>), Var(Arc<VarRef>),
Func(Arc<FunctionRef>), Func(Arc<FunctionRef>),
@@ -29,16 +29,10 @@ impl Scope {
Arc::new(Self::TopLevel(TopLevelHirScope::from_tlss(&tl))) Arc::new(Self::TopLevel(TopLevelHirScope::from_tlss(&tl)))
} }
pub fn get_refrence(&self, name: &String) -> Option<Refrence> { pub fn get_reference(&self, name: &String) -> Option<Reference> {
match self { match self {
Scope::TopLevel(tl) => tl.get_refrence(name), Scope::TopLevel(tl) => tl.get_reference(name),
Scope::Local(l) => l Scope::Local(l) => l.get_reference(name),
.variables
.lock()
.unwrap()
.get(name)
.cloned()
.map(Refrence::Var),
} }
} }
} }
@@ -57,17 +51,29 @@ impl LocalScope {
}) })
} }
pub fn get_reference(&self, name: &String) -> Option<Reference> {
self.variables
.lock()
.unwrap()
.get(name)
.cloned()
.map(Reference::Var)
.or_else(|| self.parent.get_reference(name))
}
pub fn with_block(self: &Arc<Self>, block: &mut parser::ast::Block) { pub fn with_block(self: &Arc<Self>, block: &mut parser::ast::Block) {
for statement in &mut block.0 { for statement in &mut block.0 {
match statement { match statement {
Statement::Block(b) => self.clone().with_block(b), Statement::Block(b) => self.clone().with_block(b),
Statement::VarDecl { kind, name, init } => { Statement::VarDecl { name, init, .. } => {
if let Some(init) = init { if let Some(init) = init {
let var_type = self.get_type_from_expr(init).unwrap();
self.variables.lock().unwrap().insert( self.variables.lock().unwrap().insert(
name.clone(), name.clone(),
Arc::new(VarRef { Arc::new(VarRef {
name: name.to_string(), name: name.to_string(),
var_type: self.get_type_from_expr(init).unwrap(), var_type,
}), }),
); );
} }
@@ -80,14 +86,51 @@ 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.parent.get_refrence(&"int".to_string()).map(|r| { self.parent.get_reference(&"int".to_string()).map(|r| {
if let Refrence::Type(tr) = &r { if let Reference::Type(tr) = &r {
tr.clone() tr.clone()
} else { } else {
unimplemented!() unimplemented!()
} }
}) })
} }
ast::Expression::FloatLiteral(_) => {
self.parent.get_reference(&"float".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| {
if let Reference::Type(tr) = &r {
tr.clone()
} else {
unimplemented!()
}
})
}
ast::Expression::StringLiteral(_) => {
self.parent.get_reference(&"string".to_string()).map(|r| {
if let Reference::Type(tr) = &r {
tr.clone()
} else {
unimplemented!()
}
})
}
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,
},
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@@ -95,8 +138,8 @@ impl LocalScope {
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_refrence(id) { parser::ast::TypeExpr::Identifier(id) => match self.parent.get_reference(id) {
Some(Refrence::Type(type_ref)) => { Some(Reference::Type(type_ref)) => {
self.variables.lock().unwrap().insert( self.variables.lock().unwrap().insert(
param_name.clone(), param_name.clone(),
Arc::new(VarRef { Arc::new(VarRef {
+2
View File
@@ -1,3 +1,5 @@
function add(a: int, b: int) { function add(a: int, b: int) {
let myVar = 10; let myVar = 10;
let test = myVar;
} }