diff --git a/reid/lib/std.reid b/reid/lib/std.reid index 6a26b18..5708c95 100644 --- a/reid/lib/std.reid +++ b/reid/lib/std.reid @@ -1,6 +1,7 @@ extern fn puts(message: *char) -> i32; extern fn malloc(size: u64) -> *u8; +extern fn free(ptr: *u8); extern fn div(numerator: i32, denominator: i32) -> div_t; struct div_t { @@ -8,8 +9,8 @@ struct div_t { remainder: i32, } -pub fn print(message: *char) { - puts(message); +pub fn print(message: &String) { + puts(*message.inner); } pub fn int_div(numerator: i32, denominator: i32) -> div_t { @@ -20,6 +21,30 @@ pub fn allocate(size: u64) -> *u8 { malloc(size) } -fn main() -> u16 { - return 0; +struct String { + inner: *char, + length: u64, + max_length: u64, } + +pub fn new_string() -> String { + String { + inner: allocate(0), + length: 0, + } +} + +pub fn add_char(string: &mut String, c: char) { + if ((*string).length + 1) >= (*string).max_length { + free((*string).inner as *u8); + (*string).max_length = (*string).max_length + 4; + (*string).inner = allocate((*string).max_length) as *char; + } + (*string).inner[(*string).length] = c; + (*string).inner[((*string).length + 1)] = '\0'; + (*string).length = (*string).length + 1; +} + +pub fn free_string(string: &mut String) { + free((*string).inner as *u8); +} \ No newline at end of file diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index f7241b3..8038734 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -2,7 +2,7 @@ use std::{path::PathBuf, process}; use crate::{ ast::{self}, - mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType}, + mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType, TypeKey}, }; impl mir::Context { @@ -31,13 +31,13 @@ impl ast::Module { return_type: signature .return_type .clone() - .map(|r| r.0.into()) + .map(|r| r.0.into_mir(module_id)) .unwrap_or(mir::TypeKind::Void), parameters: signature .args .iter() .cloned() - .map(|p| (p.0, p.1.into())) + .map(|p| (p.0, p.1 .0.into_mir(module_id))) .collect(), kind: mir::FunctionDefinitionKind::Local( block.into_mir(module_id), @@ -54,13 +54,13 @@ impl ast::Module { return_type: signature .return_type .clone() - .map(|r| r.0.into()) + .map(|r| r.0.into_mir(module_id)) .unwrap_or(mir::TypeKind::Void), parameters: signature .args .iter() .cloned() - .map(|p| (p.0, p.1.into())) + .map(|p| (p.0, p.1 .0.into_mir(module_id))) .collect(), kind: mir::FunctionDefinitionKind::Extern(false), }; @@ -77,7 +77,7 @@ impl ast::Module { .map(|s| { StructField( s.name.clone(), - s.ty.clone().into(), + s.ty.clone().0.into_mir(module_id), s.range.as_meta(module_id), ) }) @@ -86,6 +86,7 @@ impl ast::Module { } }, meta: (*range).as_meta(module_id), + source_module: module_id, }; typedefs.push(def); } @@ -116,7 +117,7 @@ impl ast::Block { s_let .ty .clone() - .map(|t| t.0.into()) + .map(|t| t.0.into_mir(module_id)) .unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)), s_let.name.clone(), s_let.name_range.as_meta(module_id), @@ -256,9 +257,10 @@ impl ast::Expression { Box::new(expr.process(module_id)), ), }, - ast::ExpressionKind::CastTo(expression, ty) => { - mir::ExprKind::CastTo(Box::new(expression.process(module_id)), ty.0.clone().into()) - } + ast::ExpressionKind::CastTo(expression, ty) => mir::ExprKind::CastTo( + Box::new(expression.process(module_id)), + ty.0.clone().into_mir(module_id), + ), }; mir::Expression(kind, self.1.as_meta(module_id)) @@ -294,9 +296,9 @@ impl ast::Literal { } } -impl From for mir::TypeKind { - fn from(value: ast::TypeKind) -> Self { - match &value { +impl ast::TypeKind { + fn into_mir(&self, source_mod: SourceModuleId) -> mir::TypeKind { + match &self { ast::TypeKind::Bool => mir::TypeKind::Bool, ast::TypeKind::I8 => mir::TypeKind::I8, ast::TypeKind::I16 => mir::TypeKind::I16, @@ -309,14 +311,16 @@ impl From for mir::TypeKind { ast::TypeKind::U64 => mir::TypeKind::U64, ast::TypeKind::U128 => mir::TypeKind::U128, ast::TypeKind::Array(type_kind, length) => { - mir::TypeKind::Array(Box::new(mir::TypeKind::from(*type_kind.clone())), *length) + mir::TypeKind::Array(Box::new(type_kind.clone().into_mir(source_mod)), *length) + } + ast::TypeKind::Custom(name) => { + mir::TypeKind::CustomType(TypeKey(name.clone(), source_mod)) } - ast::TypeKind::Custom(name) => mir::TypeKind::CustomType(name.clone()), ast::TypeKind::Borrow(type_kind, mutable) => { - mir::TypeKind::Borrow(Box::new(mir::TypeKind::from(*type_kind.clone())), *mutable) + mir::TypeKind::Borrow(Box::new(type_kind.clone().into_mir(source_mod)), *mutable) } ast::TypeKind::Ptr(type_kind) => { - mir::TypeKind::UserPtr(Box::new(mir::TypeKind::from(*type_kind.clone()))) + mir::TypeKind::UserPtr(Box::new(type_kind.clone().into_mir(source_mod))) } ast::TypeKind::F16 => mir::TypeKind::F16, ast::TypeKind::F32B => mir::TypeKind::F32B, @@ -329,9 +333,3 @@ impl From for mir::TypeKind { } } } - -impl From for mir::TypeKind { - fn from(value: ast::Type) -> Self { - value.0.into() - } -} diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 7d01219..b7c9a14 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -18,8 +18,8 @@ use crate::{ error_raporting::ModuleMap, lexer::{FullToken, Position}, mir::{ - self, implement::TypeCategory, Metadata, NamedVariableRef, StructField, StructType, - TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral, + self, implement::TypeCategory, Metadata, NamedVariableRef, SourceModuleId, StructField, + StructType, TypeDefinition, TypeDefinitionKind, TypeKey, TypeKind, VagueLiteral, }, }; @@ -77,10 +77,11 @@ pub struct Scope<'ctx, 'a> { context: &'ctx Context, tokens: &'ctx Vec, module: &'ctx Module<'ctx>, + module_id: SourceModuleId, function: &'ctx StackFunction<'ctx>, block: Block<'ctx>, types: &'a HashMap, - type_values: &'a HashMap, + type_values: &'a HashMap, functions: &'a HashMap>, stack_values: HashMap, debug: Option>, @@ -154,6 +155,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { function: self.function, context: self.context, module: self.module, + module_id: self.module_id, functions: self.functions, types: self.types, type_values: self.type_values, @@ -170,8 +172,8 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { old_block } - fn get_typedef(&self, name: &String) -> Option<&TypeDefinition> { - self.type_values.get(name).and_then(|v| self.types.get(v)) + fn get_typedef(&self, key: &TypeKey) -> Option<&TypeDefinition> { + self.type_values.get(key).and_then(|v| self.types.get(v)) } } @@ -250,6 +252,7 @@ impl mir::Module { insert_debug!(&TypeKind::Char); for typedef in &self.typedefs { + let type_key = TypeKey(typedef.name.clone(), self.module_id); let type_value = match &typedef.kind { TypeDefinitionKind::Struct(StructType(fields)) => { module.custom_type(CustomTypeKind::NamedStruct(NamedStruct( @@ -265,8 +268,8 @@ impl mir::Module { } }; types.insert(type_value, typedef.clone()); - type_values.insert(typedef.name.clone(), type_value); - insert_debug!(&TypeKind::CustomType(typedef.name.clone())); + type_values.insert(type_key.clone(), type_value); + insert_debug!(&TypeKind::CustomType(type_key.clone())); } let mut functions = HashMap::new(); @@ -401,6 +404,7 @@ impl mir::Module { context, tokens, module: &module, + module_id: self.module_id, function, block: entry, functions: &functions, @@ -632,7 +636,10 @@ impl mir::Expression { .codegen(scope, state) .expect("rhs has no return value") .instr(); - let lhs_type = lhs_exp.return_type(&Default::default()).unwrap().1; + let lhs_type = lhs_exp + .return_type(&Default::default(), scope.module_id) + .unwrap() + .1; let instr = match ( binop, lhs_type.signed(), @@ -887,15 +894,15 @@ impl mir::Expression { let TypeKind::CodegenPtr(inner) = &struct_val.1 else { panic!("tried accessing non-pointer"); }; - let TypeKind::CustomType(name) = *inner.clone() else { + let TypeKind::CustomType(key) = *inner.clone() else { panic!("tried accessing non-custom-type"); }; let TypeDefinitionKind::Struct(struct_ty) = - scope.get_typedef(&name).unwrap().kind.clone(); + scope.get_typedef(&key).unwrap().kind.clone(); let idx = struct_ty.find_index(field).unwrap(); - let gep_n = format!("{}.{}.gep", name, field); - let load_n = format!("{}.{}.load", name, field); + let gep_n = format!("{}.{}.gep", key.0, field); + let load_n = format!("{}.{}.load", key.0, field); let value = scope .block @@ -933,7 +940,8 @@ impl mir::Expression { } } mir::ExprKind::Struct(name, items) => { - let struct_ty = Type::CustomType(*scope.type_values.get(name)?); + let type_key = TypeKey(name.clone(), scope.module_id); + let struct_ty = Type::CustomType(*scope.type_values.get(&type_key)?); let load_n = format!("{}.load", name); @@ -968,7 +976,7 @@ impl mir::Expression { Some(StackValue( StackValueKind::Literal(struct_val), - TypeKind::CustomType(name.clone()), + TypeKind::CustomType(type_key), )) } mir::ExprKind::Borrow(varref, mutable) => { @@ -1209,7 +1217,7 @@ impl mir::Literal { impl TypeKind { fn get_type( &self, - type_vals: &HashMap, + type_vals: &HashMap, typedefs: &HashMap, ) -> Type { match &self { @@ -1271,7 +1279,7 @@ impl TypeKind { scope: DebugProgramValue, debug_info: &DebugInformation, debug_types: &HashMap, - type_values: &HashMap, + type_values: &HashMap, types: &HashMap, tokens: &Vec, ) -> DebugTypeValue { @@ -1312,8 +1320,8 @@ impl TypeKind { length: *len, }) } - TypeKind::CustomType(name) => { - let typedef = types.get(type_values.get(name).unwrap()).unwrap(); + TypeKind::CustomType(key) => { + let typedef = types.get(type_values.get(key).unwrap()).unwrap(); match &typedef.kind { TypeDefinitionKind::Struct(struct_type) => { @@ -1339,7 +1347,7 @@ impl TypeKind { } { DebugTypeData::Struct(DebugStructType { - name: name.clone(), + name: key.0.clone(), scope, location: typedef.meta.into_debug(tokens).unwrap(), size_bits, diff --git a/reid/src/lexer.rs b/reid/src/lexer.rs index 0b91ed4..03f0e47 100644 --- a/reid/src/lexer.rs +++ b/reid/src/lexer.rs @@ -366,6 +366,7 @@ fn escape_char(c: &char) -> char { 't' => '\t', 'n' => '\n', 'r' => '\r', + '0' => '\0', _ => *c, } } diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index 74267da..28cc797 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -345,7 +345,7 @@ impl Display for TypeKind { Display::fmt(len, f)?; f.write_char(']') } - TypeKind::CustomType(name) => write!(f, "{}", name), + TypeKind::CustomType(TypeKey(name, mod_id)) => write!(f, "{}:{}", mod_id, name), TypeKind::Borrow(type_kind, false) => { write!(f, "&")?; Display::fmt(type_kind, f) diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index c4556b4..524915d 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -122,12 +122,12 @@ impl TypeKind { TypeKind::U128 => false, TypeKind::Void => false, TypeKind::Char => false, - TypeKind::Array(_, _) => false, - TypeKind::CustomType(_) => false, - TypeKind::CodegenPtr(_) => false, - TypeKind::Vague(_) => false, - TypeKind::Borrow(_, _) => false, - TypeKind::UserPtr(_) => false, + TypeKind::Array(..) => false, + TypeKind::CustomType(..) => false, + TypeKind::CodegenPtr(..) => false, + TypeKind::Vague(..) => false, + TypeKind::Borrow(..) => false, + TypeKind::UserPtr(..) => false, TypeKind::F16 => true, TypeKind::F32B => true, TypeKind::F32 => true, @@ -154,10 +154,10 @@ impl TypeKind { TypeKind::Void => 0, TypeKind::Char => 8, TypeKind::Array(type_kind, len) => type_kind.size_of() * len, - TypeKind::CustomType(_) => 32, + TypeKind::CustomType(..) => 32, TypeKind::CodegenPtr(_) => 64, TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), - TypeKind::Borrow(_, _) => 64, + TypeKind::Borrow(..) => 64, TypeKind::UserPtr(_) => 64, TypeKind::F16 => 16, TypeKind::F32B => 16, @@ -185,7 +185,7 @@ impl TypeKind { TypeKind::Void => 0, TypeKind::Char => 8, TypeKind::Array(type_kind, _) => type_kind.alignment(), - TypeKind::CustomType(_) => 32, + TypeKind::CustomType(..) => 32, TypeKind::CodegenPtr(_) => 64, TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), TypeKind::Borrow(_, _) => 64, @@ -230,7 +230,7 @@ impl TypeKind { TypeKind::Void => TypeCategory::Other, TypeKind::Bool => TypeCategory::Other, TypeKind::Array(_, _) => TypeCategory::Other, - TypeKind::CustomType(_) => TypeCategory::Other, + TypeKind::CustomType(..) => TypeCategory::Other, TypeKind::Borrow(_, _) => TypeCategory::Other, TypeKind::UserPtr(_) => TypeCategory::Other, TypeKind::CodegenPtr(_) => TypeCategory::Other, @@ -278,7 +278,7 @@ impl Block { let mut early_return = None; for statement in &self.statements { - let ret = statement.return_type(&Default::default()); + let ret = statement.return_type(&Default::default(), SourceModuleId(0)); if let Ok((ReturnKind::Hard, _)) = ret { early_return = Some(statement); } @@ -302,11 +302,15 @@ impl Block { .unwrap_or(self.meta) } - pub fn return_type(&self, refs: &TypeRefs) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { + pub fn return_type( + &self, + refs: &TypeRefs, + mod_id: SourceModuleId, + ) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { let mut early_return = None; for statement in &self.statements { - let ret = statement.return_type(refs); + let ret = statement.return_type(refs, mod_id); if let Ok((ReturnKind::Hard, _)) = ret { early_return = early_return.or(ret.ok()); } @@ -319,7 +323,7 @@ impl Block { self.return_expression .as_ref() .ok_or(ReturnTypeOther::NoBlockReturn(self.meta)) - .and_then(|(kind, stmt)| Ok((*kind, stmt.return_type(refs)?.1))) + .and_then(|(kind, stmt)| Ok((*kind, stmt.return_type(refs, mod_id)?.1))) } pub fn backing_var(&self) -> Option<&NamedVariableRef> { @@ -337,19 +341,23 @@ impl Block { } impl Statement { - pub fn return_type(&self, refs: &TypeRefs) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { + pub fn return_type( + &self, + refs: &TypeRefs, + mod_id: SourceModuleId, + ) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { use StmtKind::*; match &self.0 { Let(var, _, expr) => if_hard( - expr.return_type(refs)?, + expr.return_type(refs, mod_id)?, Err(ReturnTypeOther::Let(var.2 + expr.1)), ), Set(lhs, rhs) => if_hard( - rhs.return_type(refs)?, + rhs.return_type(refs, mod_id)?, Err(ReturnTypeOther::Set(lhs.1 + rhs.1)), ), Import(_) => todo!(), - Expression(expression) => expression.return_type(refs), + Expression(expression) => expression.return_type(refs, mod_id), } } @@ -364,22 +372,26 @@ impl Statement { } impl Expression { - pub fn return_type(&self, refs: &TypeRefs) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { + pub fn return_type( + &self, + refs: &TypeRefs, + mod_id: SourceModuleId, + ) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { use ExprKind::*; match &self.0 { Literal(lit) => Ok((ReturnKind::Soft, lit.as_type())), Variable(var) => var.return_type(), BinOp(_, then_e, else_e) => { - let then_r = then_e.return_type(refs)?; - let else_r = else_e.return_type(refs)?; + let then_r = then_e.return_type(refs, mod_id)?; + let else_r = else_e.return_type(refs, mod_id)?; Ok(pick_return(then_r, else_r)) } - Block(block) => block.return_type(refs), + Block(block) => block.return_type(refs, mod_id), FunctionCall(fcall) => fcall.return_type(), - If(expr) => expr.return_type(refs), + If(expr) => expr.return_type(refs, mod_id), Indexed(expression, _, _) => { - let expr_type = expression.return_type(refs)?; + let expr_type = expression.return_type(refs, mod_id)?; if let TypeKind::Array(elem_ty, _) = expr_type.1.resolve_weak(refs) { Ok((ReturnKind::Soft, *elem_ty)) } else { @@ -390,7 +402,7 @@ impl Expression { let first = expressions .iter() .next() - .map(|e| e.return_type(refs)) + .map(|e| e.return_type(refs, mod_id)) .unwrap_or(Ok((ReturnKind::Soft, TypeKind::Void)))?; Ok(( ReturnKind::Soft, @@ -398,7 +410,10 @@ impl Expression { )) } Accessed(_, type_kind, _) => Ok((ReturnKind::Soft, type_kind.clone())), - Struct(name, _) => Ok((ReturnKind::Soft, TypeKind::CustomType(name.clone()))), + Struct(name, _) => Ok(( + ReturnKind::Soft, + TypeKind::CustomType(TypeKey(name.clone(), mod_id)), + )), Borrow(var, mutable) => { let ret_type = var.return_type()?; Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) @@ -410,7 +425,7 @@ impl Expression { _ => Err(ReturnTypeOther::DerefNonBorrow(var.2)), } } - CastTo(expr, type_kind) => match expr.return_type(refs) { + CastTo(expr, type_kind) => match expr.return_type(refs, mod_id) { Ok(ret_type) => match ret_type { (ReturnKind::Hard, ty) => Ok((ReturnKind::Hard, ty)), _ => Ok((ReturnKind::Soft, type_kind.clone())), @@ -468,10 +483,14 @@ impl Expression { } impl IfExpression { - pub fn return_type(&self, refs: &TypeRefs) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { - let then_r = self.1.return_type(refs)?; + pub fn return_type( + &self, + refs: &TypeRefs, + mod_id: SourceModuleId, + ) -> Result<(ReturnKind, TypeKind), ReturnTypeOther> { + let then_r = self.1.return_type(refs, mod_id)?; if let Some(else_b) = &self.2 { - let else_r = else_b.return_type(refs)?; + let else_r = else_b.return_type(refs, mod_id)?; let kind = if then_r.0 == ReturnKind::Hard && else_r.0 == ReturnKind::Hard { ReturnKind::Hard diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index 3484c21..bb5125b 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -11,7 +11,7 @@ use crate::{ compile_module, error_raporting::{ModuleMap, ReidError}, lexer::FullToken, - mir::{TypeDefinition, TypeKind}, + mir::{SourceModuleId, TypeDefinition, TypeKey, TypeKind}, parse_module, }; @@ -195,7 +195,6 @@ impl<'map> Pass for LinkerPass<'map> { let func_name = unsafe { path.get_unchecked(1) }; let imported_mod_name = imported.0.name.clone(); - let imported_mod_typedefs = imported.0.typedefs.clone(); let Some(func) = imported .0 @@ -213,6 +212,8 @@ impl<'map> Pass for LinkerPass<'map> { continue; }; + let func_name = func.name.clone(); + if !func.is_pub { state.ok::<_, Infallible>( Err(ErrorKind::FunctionIsPrivate( @@ -244,14 +245,12 @@ impl<'map> Pass for LinkerPass<'map> { } } - fn import_type(base: &String, ty: &TypeKind) -> (TypeKind, Vec) { + fn import_type(base: &String, ty: &TypeKind) -> (TypeKind, Vec) { let mut imported_types = Vec::new(); let ty = match &ty { - TypeKind::CustomType(name) => { - imported_types.push(name.clone()); - - let name = format!("{}::{}", base, name); - TypeKind::CustomType(name) + TypeKind::CustomType(key) => { + imported_types.push(key.clone()); + TypeKind::CustomType(key.clone()) } _ => ty.clone(), }; @@ -272,27 +271,28 @@ impl<'map> Pass for LinkerPass<'map> { fn find_inner_types( typedef: &TypeDefinition, - mut seen: HashSet, - ) -> Vec { + mut seen: HashSet, + mod_id: SourceModuleId, + ) -> Vec { match &typedef.kind { crate::mir::TypeDefinitionKind::Struct(struct_type) => { let typenames = struct_type .0 .iter() - .filter(|t| matches!(t.1, TypeKind::CustomType(_))) + .filter(|t| matches!(t.1, TypeKind::CustomType(..))) .map(|t| match &t.1 { - TypeKind::CustomType(t) => t, + TypeKind::CustomType(TypeKey(t, _)) => t, _ => panic!(), }) .cloned() .collect::>(); for typename in typenames { - if seen.contains(&typename) { + if seen.contains(&TypeKey(typename.clone(), mod_id)) { continue; } - let inner = find_inner_types(typedef, seen.clone()); - seen.insert(typename); + let inner = find_inner_types(typedef, seen.clone(), mod_id); + seen.insert(TypeKey(typename, mod_id)); seen.extend(inner); } @@ -304,28 +304,30 @@ impl<'map> Pass for LinkerPass<'map> { let mut seen = HashSet::new(); seen.extend(imported_types.clone()); - for typename in imported_types.clone() { + let imported_mod_id = imported.0.module_id; + let imported_mod_typedefs = &mut imported.0.typedefs; + + for typekey in imported_types.clone() { let typedef = imported_mod_typedefs .iter() - .find(|ty| ty.name == typename) + .find(|ty| TypeKey(ty.name.clone(), imported_mod_id) == typekey) .unwrap(); - let inner = find_inner_types(typedef, seen.clone()); + let inner = find_inner_types(typedef, seen.clone(), imported_mod_id); seen.extend(inner); } - for typename in seen.into_iter() { - let mut typedef = imported_mod_typedefs + for typekey in seen.into_iter() { + let typedef = imported_mod_typedefs .iter() - .find(|ty| ty.name == typename) + .find(|ty| TypeKey(ty.name.clone(), imported_mod_id) == typekey) .unwrap() .clone(); - typedef.name = format!("{}::{}", imported_mod_name, typedef.name); - importer_module.0.typedefs.push(typedef); + importer_module.0.typedefs.push(typedef.clone()); } importer_module.0.functions.push(FunctionDefinition { - name: func.name.clone(), + name: func_name, is_pub: false, is_imported: false, return_type: return_type, diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index e4e152b..77af85c 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -18,7 +18,7 @@ pub mod typeinference; pub mod typerefs; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] -pub struct SourceModuleId(u32); +pub struct SourceModuleId(pub u32); impl SourceModuleId { pub fn increment(&mut self) -> SourceModuleId { @@ -77,6 +77,9 @@ impl TokenRange { } } +#[derive(Hash, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct TypeKey(pub String, pub SourceModuleId); + #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum TypeKind { Bool, @@ -100,7 +103,7 @@ pub enum TypeKind { F128PPC, Char, Array(Box, u64), - CustomType(String), + CustomType(TypeKey), Borrow(Box, bool), UserPtr(Box), CodegenPtr(Box), @@ -335,6 +338,7 @@ pub struct TypeDefinition { pub name: String, pub kind: TypeDefinitionKind, pub meta: Metadata, + pub source_module: SourceModuleId, } #[derive(Debug, Clone)] diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index cddc1c5..0180cb2 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -90,16 +90,16 @@ impl State { } #[derive(Clone, Debug)] -pub struct Storage(HashMap); +pub struct Storage(HashMap); -impl Default for Storage { +impl Default for Storage { fn default() -> Self { Self(Default::default()) } } -impl Storage { - pub fn set(&mut self, key: String, value: T) -> Result { +impl Storage { + pub fn set(&mut self, key: Key, value: T) -> Result { if let Some(_) = self.0.get(&key) { Err(()) } else { @@ -108,16 +108,16 @@ impl Storage { } } - pub fn get(&self, key: &String) -> Option<&T> { + pub fn get(&self, key: &Key) -> Option<&T> { self.0.get(key) } } #[derive(Clone, Default, Debug)] pub struct Scope { - pub function_returns: Storage, - pub variables: Storage, - pub types: Storage, + pub function_returns: Storage, + pub variables: Storage, + pub types: Storage, /// Hard Return type of this scope, if inside a function pub return_type_hint: Option, pub data: Data, @@ -134,12 +134,20 @@ impl Scope { } } - pub fn get_struct_type(&self, name: &String) -> Option<&StructType> { - let ty = self.types.get(&name)?; - match ty { + pub fn get_struct_type(&self, key: &TypeKey) -> Option<&StructType> { + let ty = self.types.get(&key)?; + match &ty.kind { TypeDefinitionKind::Struct(struct_ty) => Some(struct_ty), } } + + pub fn find_type(&self, name: &String) -> Option<&TypeKey> { + self.types + .0 + .iter() + .find(|(TypeKey(n, _), _)| n == name) + .map(|(key, _)| key) + } } #[derive(Clone, Debug)] @@ -158,14 +166,20 @@ pub struct PassState<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> state: &'st mut State, pub scope: &'sc mut Scope, inner: Vec>, + pub module_id: Option, } impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, 'sc, Data, TError> { - fn from(state: &'st mut State, scope: &'sc mut Scope) -> Self { + fn from( + state: &'st mut State, + scope: &'sc mut Scope, + module_id: Option, + ) -> Self { PassState { state, scope, inner: Vec::new(), + module_id: module_id, } } @@ -203,6 +217,7 @@ impl<'st, 'sc, Data: Clone + Default, TError: STDError + Clone> PassState<'st, ' state: self.state, scope, inner: Vec::new(), + module_id: self.module_id, } } } @@ -261,7 +276,7 @@ impl Context { pub fn pass(&mut self, pass: &mut T) -> Result, ReidError> { let mut state = State::new(); let mut scope = Scope::default(); - pass.context(self, PassState::from(&mut state, &mut scope))?; + pass.context(self, PassState::from(&mut state, &mut scope, None))?; for module in &mut self.modules { module.pass(pass, &mut state, &mut scope.inner())?; } @@ -277,10 +292,13 @@ impl Module { scope: &mut Scope, ) -> PassResult { for typedef in &self.typedefs { - let kind = match &typedef.kind { - TypeDefinitionKind::Struct(fields) => TypeDefinitionKind::Struct(fields.clone()), - }; - scope.types.set(typedef.name.clone(), kind).ok(); + scope + .types + .set( + TypeKey(typedef.name.clone(), self.module_id), + typedef.clone(), + ) + .ok(); } for function in &self.functions { @@ -296,10 +314,10 @@ impl Module { .ok(); } - pass.module(self, PassState::from(state, scope))?; + pass.module(self, PassState::from(state, scope, Some(self.module_id)))?; for function in &mut self.functions { - function.pass(pass, state, &mut scope.inner())?; + function.pass(pass, state, &mut scope.inner(), self.module_id)?; } Ok(()) } @@ -311,6 +329,7 @@ impl FunctionDefinition { pass: &mut T, state: &mut State, scope: &mut Scope, + mod_id: SourceModuleId, ) -> PassResult { for param in &self.parameters { scope @@ -325,12 +344,12 @@ impl FunctionDefinition { .ok(); } - pass.function(self, PassState::from(state, scope))?; + pass.function(self, PassState::from(state, scope, Some(mod_id)))?; match &mut self.kind { FunctionDefinitionKind::Local(block, _) => { scope.return_type_hint = Some(self.return_type.clone()); - block.pass(pass, state, scope)?; + block.pass(pass, state, scope, mod_id)?; } FunctionDefinitionKind::Extern(_) => {} }; @@ -344,14 +363,15 @@ impl Block { pass: &mut T, state: &mut State, scope: &mut Scope, + mod_id: SourceModuleId, ) -> PassResult { let mut scope = scope.inner(); for statement in &mut self.statements { - statement.pass(pass, state, &mut scope)?; + statement.pass(pass, state, &mut scope, mod_id)?; } - pass.block(self, PassState::from(state, &mut scope)) + pass.block(self, PassState::from(state, &mut scope, Some(mod_id))) } } @@ -361,21 +381,22 @@ impl Statement { pass: &mut T, state: &mut State, scope: &mut Scope, + mod_id: SourceModuleId, ) -> PassResult { match &mut self.0 { StmtKind::Let(_, _, expression) => { - expression.pass(pass, state, scope)?; + expression.pass(pass, state, scope, mod_id)?; } StmtKind::Set(_, expression) => { - expression.pass(pass, state, scope)?; + expression.pass(pass, state, scope, mod_id)?; } StmtKind::Import(_) => {} // Never exists at this stage StmtKind::Expression(expression) => { - expression.pass(pass, state, scope)?; + expression.pass(pass, state, scope, mod_id)?; } } - pass.stmt(self, PassState::from(state, scope))?; + pass.stmt(self, PassState::from(state, scope, Some(mod_id)))?; match &mut self.0 { StmtKind::Let(variable_reference, mutable, _) => { @@ -404,8 +425,9 @@ impl Expression { pass: &mut T, state: &mut State, scope: &mut Scope, + mod_id: SourceModuleId, ) -> PassResult { - pass.expr(self, PassState::from(state, scope))?; + pass.expr(self, PassState::from(state, scope, Some(mod_id)))?; Ok(()) } } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 811bbe5..1db8b6f 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -42,8 +42,8 @@ pub enum ErrorKind { TriedIndexingNonIndexable(TypeKind), #[error("Index {0} out of bounds ({1})")] IndexOutOfBounds(u64, u64), - #[error("No such type {0} could be found")] - NoSuchType(String), + #[error("No such type {0} could be found in module {1}")] + NoSuchType(String, SourceModuleId), #[error("Attempted to access field of non-struct type of {0}")] TriedAccessingNonStruct(TypeKind), #[error("No such struct-field on type {0}")] @@ -85,7 +85,13 @@ impl<'t> Pass for TypeCheck<'t> { fn module(&mut self, module: &mut Module, mut state: TypecheckPassState) -> PassResult { let mut defmap = HashMap::new(); for typedef in &module.typedefs { - let TypeDefinition { name, kind, meta } = &typedef; + let TypeDefinition { + name, + kind, + meta, + source_module, + } = &typedef; + match kind { TypeDefinitionKind::Struct(StructType(fields)) => { let mut fieldmap = HashMap::new(); @@ -132,7 +138,7 @@ fn check_typedefs_for_recursion<'a, 'b>( match &typedef.kind { TypeDefinitionKind::Struct(StructType(fields)) => { for field_ty in fields.iter().map(|StructField(_, ty, _)| ty) { - if let TypeKind::CustomType(name) = field_ty { + if let TypeKind::CustomType(TypeKey(name, _)) = field_ty { if seen.contains(name) { state.ok::<_, Infallible>( Err(ErrorKind::RecursiveTypeDefinition( @@ -319,7 +325,9 @@ impl Block { StmtKind::Expression(expression) => { let res = expression.typecheck(&mut state, &typerefs, None); state.or_else(res, TypeKind::Void, expression.1); - if let Ok((kind, _)) = expression.return_type(typerefs) { + if let Ok((kind, _)) = + expression.return_type(typerefs, state.module_id.unwrap()) + { Some((kind, expression)) } else { None @@ -605,11 +613,11 @@ impl Expression { let expr_ty = state.or_else(expr_res, TypeKind::Vague(Vague::Unknown), expression.1); - if let TypeKind::CustomType(struct_name) = expr_ty { + if let TypeKind::CustomType(key) = expr_ty { let struct_type = state .scope - .get_struct_type(&struct_name) - .ok_or(ErrorKind::NoSuchType(struct_name.clone()))?; + .get_struct_type(&key) + .ok_or(ErrorKind::NoSuchType(key.0.clone(), key.1))?; if let Some(expr_field_ty) = struct_type.get_field_ty(&field_name) { // Make sure they are the same let true_ty = state.or_else( @@ -628,10 +636,11 @@ impl Expression { } } ExprKind::Struct(struct_name, items) => { + let type_key = TypeKey(struct_name.clone(), state.module_id.unwrap()); let struct_def = state .scope - .get_struct_type(struct_name) - .ok_or(ErrorKind::NoSuchType(struct_name.clone()))? + .get_struct_type(&type_key) + .ok_or(ErrorKind::NoSuchType(struct_name.clone(), type_key.1))? .clone(); for (field_name, field_expr) in items { // Get expected type, or error if field does not exist @@ -654,7 +663,7 @@ impl Expression { // Make sure both are the same type, report error if not state.ok(expr_ty.collapse_into(&expr_ty), field_expr.1); } - Ok(TypeKind::CustomType(struct_name.clone())) + Ok(TypeKind::CustomType(type_key)) } ExprKind::Borrow(var_ref, mutable) => { let scope_var = state.scope.variables.get(&var_ref.1).cloned(); diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index e154941..dfef2f1 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -14,7 +14,7 @@ use super::{ typecheck::ErrorKind, typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, Block, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, IfExpression, Module, - ReturnKind, StmtKind, + ReturnKind, StmtKind, TypeKey, TypeKind::*, VagueType::*, }; @@ -138,7 +138,7 @@ impl Block { // Fetch the declared return type let (kind, ty) = self - .return_type(inner_refs.types) + .return_type(inner_refs.types, state.module_id.unwrap()) .ok() .unwrap_or((ReturnKind::Soft, Void)); let mut ret_type_ref = outer_refs.from_type(&ty).unwrap(); @@ -320,11 +320,11 @@ impl Expression { // need for further resolution. let kind = expr_ty.resolve_weak().unwrap(); match kind { - CustomType(name) => { + CustomType(key) => { let struct_ty = state .scope - .get_struct_type(&name) - .ok_or(ErrorKind::NoSuchType(name.clone()))?; + .get_struct_type(&key) + .ok_or(ErrorKind::NoSuchType(key.0.clone(), key.1))?; match struct_ty.get_field_ty(&field_name) { Some(field_ty) => { let mut elem_ty = type_refs.from_type(&type_kind).unwrap(); @@ -339,10 +339,14 @@ impl Expression { } } ExprKind::Struct(struct_name, fields) => { + let type_key = TypeKey(struct_name.clone(), state.module_id.unwrap()); let expected_struct_ty = state .scope - .get_struct_type(&struct_name) - .ok_or(ErrorKind::NoSuchType(struct_name.clone()))? + .get_struct_type(&type_key) + .ok_or(ErrorKind::NoSuchType( + struct_name.clone(), + state.module_id.unwrap(), + ))? .clone(); for field in fields { if let Some(expected_field_ty) = expected_struct_ty.get_field_ty(&field.0) { @@ -361,7 +365,7 @@ impl Expression { } } Ok(type_refs - .from_type(&TypeKind::CustomType(struct_name.clone())) + .from_type(&TypeKind::CustomType(type_key.clone())) .unwrap()) } ExprKind::Borrow(var, mutable) => { diff --git a/reid_src/hello_world.reid b/reid_src/hello_world.reid index aedbe0e..eb2b8d5 100644 --- a/reid_src/hello_world.reid +++ b/reid_src/hello_world.reid @@ -1,8 +1,17 @@ import std::print; +import std::new_string; +import std::add_char; +import std::free_string; fn main() -> i32 { - let test = "hello world"; - print(test); + let mut test = new_string(); + add_char(&mut test, 'h'); + add_char(&mut test, 'e'); + add_char(&mut test, 'l'); + add_char(&mut test, 'l'); + add_char(&mut test, 'o'); + + print(&test); return 0; }