diff --git a/compiler/src/ast.rs b/compiler/src/ast.rs index 16f20b3..e85272a 100644 --- a/compiler/src/ast.rs +++ b/compiler/src/ast.rs @@ -187,7 +187,7 @@ pub struct ArgDeclaration { pub ty: Option, } -#[derive(PartialEq,Debug)] +#[derive(PartialEq,Debug, Clone)] pub struct Abi { pub loc : crate::Location, pub identifier : String, diff --git a/compiler/src/inference.rs b/compiler/src/inference.rs index 2eed7ea..90673ed 100644 --- a/compiler/src/inference.rs +++ b/compiler/src/inference.rs @@ -146,7 +146,7 @@ impl Context { .map(|stmnt| self.assign_ids_stmnt(stmnt)) .collect(), ), - untyped_ast::ValueType::External => todo!(), + untyped_ast::ValueType::External => ast::ValueType::External, }; ast::ValueDeclaration { loc, @@ -156,6 +156,7 @@ impl Context { ty: decl_ty, value, generics: generictypes, + abi, id, } } @@ -482,7 +483,8 @@ impl Context { .reduce(|ty, arg| ty.fn_ty(&arg)); value.ty = fun.unwrap().fn_ty(&ty.unwrap()); //not sure if this the correct way to handle this. } - } + }, + ast::ValueType::External => (), } } @@ -889,6 +891,7 @@ impl Context { ty: v_ty, value, generics, + abi:_, id: _, } = decl; v_ty.replace_unkown_with(id, ty.clone()); @@ -908,6 +911,7 @@ impl Context { } } } + ast::ValueType::External=>(), } } @@ -938,6 +942,7 @@ impl Context { self.apply_substution_statement(sub, stmnt); } }, + ast::ValueType::External=>() } } @@ -1392,6 +1397,7 @@ mod tests { 2 )), generics: None, + abi:None, id: 0 } )] @@ -1446,6 +1452,7 @@ mod tests { } )), generics: None, + abi:None, id: 0 } )] @@ -1538,6 +1545,7 @@ let foo a = match a where } )), generics: None, + abi: None, id: 0, } )] @@ -1579,6 +1587,7 @@ let foo a = match a where } )), generics: None, + abi: None, id: 0 } )] @@ -1653,6 +1662,7 @@ for let foo x y : T -> T -> () = () ((1,4),"T".to_string()) ] }), + abi: None, id: 0 } )] @@ -1756,6 +1766,7 @@ let complex x = id: 2 }), generics: None, + abi: None, id: 0 }), super::ast::Declaration::Value(super::ast::ValueDeclaration { @@ -1875,6 +1886,7 @@ let complex x = ) ]), generics: None, + abi: None, id: 7 }), // super::ast::ValueDeclaration { @@ -1954,6 +1966,7 @@ let unit_unit _ : () -> () = () }, value: super::ast::ValueType::Expr(super::ast::Expr::ValueRead("x".to_string(), (5,33), 7)), generics: None, + abi: None, id: 5 }), int_int, @@ -1979,6 +1992,7 @@ let unit_unit _ : () -> () = () }, value: super::ast::ValueType::Expr(super::ast::Expr::UnitLiteral), generics: None, + abi: None, id: 0 }), int_unit, @@ -2004,6 +2018,7 @@ let unit_unit _ : () -> () = () }, value: super::ast::ValueType::Expr(super::ast::Expr::NumericLiteral { value: "0".to_string(), id: 4, ty: types::INT16 }), generics: None, + abi: None, id: 2 }), unit_int, @@ -2029,6 +2044,7 @@ let unit_unit _ : () -> () = () }, value: super::ast::ValueType::Expr(super::ast::Expr::UnitLiteral), generics: None, + abi: None, id: 8 }), unit_unit, @@ -2081,7 +2097,6 @@ let if_expr a b : bool -> int32 -> int32 = if a then b else 0 }.boxed(), loc:(1, 23) }, - id:0, value: super::ast::ValueType::Expr(super::ast::Expr::If(super::ast::IfExpr { cond: super::ast::Expr::ValueRead("a".to_string(), (1,46), 4).boxed(), true_branch: ( @@ -2097,7 +2112,9 @@ let if_expr a b : bool -> int32 -> int32 = if a then b else 0 id: 3, result: types::INT32 })), - generics:None + generics:None, + abi: None, + id:0, }), if_expr, ) @@ -2141,7 +2158,6 @@ let returns a : bool -> int32 = returns: types::INT32.boxed(), loc: (1,21) }, - generics:None, value:super::ast::ValueType::Function(vec![ super::ast::Statement::IfStatement(super::ast::IfBranching{ cond: super::ast::Expr::ValueRead("a".to_string(), (2,7), 2).boxed(), @@ -2160,6 +2176,8 @@ let returns a : bool -> int32 = (4,4) ) ]), + generics:None, + abi: None, id:0 }), returns, diff --git a/compiler/src/inference/ast.rs b/compiler/src/inference/ast.rs index 69f19cd..81714ca 100644 --- a/compiler/src/inference/ast.rs +++ b/compiler/src/inference/ast.rs @@ -46,6 +46,7 @@ pub(crate) struct ValueDeclaration { pub(crate) ty: ResolvedType, pub(crate) value: ValueType, pub(crate) generics: Option, + pub(crate) abi : Option, pub(crate) id: usize, } @@ -61,6 +62,7 @@ pub struct ArgDeclaration { pub(crate) enum ValueType { Expr(Expr), Function(Vec), + External, } #[derive(PartialEq, Debug)] diff --git a/compiler/src/typed_ast.rs b/compiler/src/typed_ast.rs index 79d4177..794a026 100644 --- a/compiler/src/typed_ast.rs +++ b/compiler/src/typed_ast.rs @@ -370,6 +370,7 @@ pub struct TypedValueDeclaration { pub value: TypedValueType, pub ty: ResolvedType, pub generictypes: Option, + pub abi : Option, pub is_curried: bool, } pub fn collect_args(t: &ResolvedType) -> Vec { @@ -395,6 +396,7 @@ impl TypedValueDeclaration { TypedValueType::Function(stmnts) => stmnts .into_iter() .for_each(|expr| expr.replace_types(&replaced)), + TypedValueType::External | TypedValueType::Err => (), } } @@ -412,6 +414,7 @@ impl TypedValueDeclaration { ty, value, generics, + abi, id: _, } = data; let mut known_values = known_values.clone(); @@ -441,6 +444,7 @@ impl TypedValueDeclaration { ty: if is_curried { value.get_ty() } else { ty }, value, generictypes : generics.map(ResolvedGenericsDecl::from), + abi, }) } fn lower_generics(&mut self, context: &mut LoweringContext) { @@ -454,6 +458,7 @@ impl TypedValueDeclaration { } } TypedValueType::Err => todo!(), + TypedValueType::External => (), } } } @@ -463,6 +468,7 @@ pub enum TypedValueType { Expr(TypedExpr), Function(Vec), Err, + External, } impl TypedValueType { @@ -518,7 +524,8 @@ impl TypedValueType { } else { Ok(TypedValueType::Function(output)) } - } + }, + ast::ValueType::External => Ok(TypedValueType::External), } } @@ -543,7 +550,8 @@ impl TypedValueType { } }, ), - Self::Err => todo!(), + Self::Err => types::ERROR, + Self::External => types::ERROR } } } @@ -620,6 +628,7 @@ impl TypedStatement { TypedValueType::Function(_) => { todo!("how to handle this one :/ function inside function"); } + TypedValueType::External | TypedValueType::Err => (), }, Self::Discard(expr, _) | Self::Return(expr, _) => expr.lower_generics(context), @@ -1788,6 +1797,7 @@ fn modify_declaration( stmnt.lower_generics(context); } } + TypedValueType::External | TypedValueType::Err => (), } to_lower @@ -2868,6 +2878,7 @@ let main _ : () -> () = id: 1 }), generics: None, + abi: None, id:0 }), &HashMap::new(), @@ -2885,6 +2896,7 @@ let main _ : () -> () = }), ty: types::INT32, generictypes: None, + abi: None, is_curried: false, }), "decl statement" @@ -2970,6 +2982,7 @@ let main _ : () -> () = (0, 0) )]), generics: None, + abi: None, id:0 }), &HashMap::new(), @@ -3000,6 +3013,7 @@ let main _ : () -> () = (0, 0) )]), generictypes: None, + abi: None, is_curried: false }), r#"let test a : int32 -> int32 = @@ -3096,6 +3110,7 @@ let main _ : () -> () = ], }), is_curried: false, + abi: None, }), generic, "generic" @@ -3120,6 +3135,7 @@ let main _ : () -> () = value: TypedValueType::Expr(TypedExpr::IntegerLiteral { value: "3".to_string(), size: types::IntWidth::ThirtyTwo }), ty: types::INT32, generictypes: None, + abi: None, is_curried: false, }), TypedStatement::FnCall(TypedFnCall { @@ -3155,6 +3171,7 @@ let main _ : () -> () = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), main, @@ -3285,6 +3302,7 @@ let first a : Tuple -> int32 = loc:(7,36) }, generictypes: None, + abi: None, is_curried: false, }), "post lowering function" @@ -3402,6 +3420,7 @@ let main x : int32 -> int32 = ], }), is_curried: false, + abi: None, }), generic, "generic should be untouched" @@ -3451,6 +3470,7 @@ let main x : int32 -> int32 = }, generictypes: None, is_curried: false, + abi: None, }), main, "main should have the value read changed" @@ -3476,6 +3496,7 @@ let main x : int32 -> int32 = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), generated, @@ -3608,6 +3629,7 @@ let statement_with_else_if a b : bool -> bool -> int32 = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), expr, @@ -3673,6 +3695,7 @@ let statement_with_else_if a b : bool -> bool -> int32 = } )]), generictypes: None, + abi: None, is_curried: false, }), stmnt, @@ -3855,6 +3878,7 @@ let as_statement a b : int32 -> int32 -> () = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), simple, @@ -3975,6 +3999,7 @@ let as_statement a b : int32 -> int32 -> () = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), nest_in_call, @@ -4112,6 +4137,7 @@ let as_statement a b : int32 -> int32 -> () = loc:(0,0) }, generictypes: None, + abi: None, is_curried: false, }), statement, diff --git a/llvm-codegen/src/code_gen.rs b/llvm-codegen/src/code_gen.rs index d72feec..3fbc7ea 100644 --- a/llvm-codegen/src/code_gen.rs +++ b/llvm-codegen/src/code_gen.rs @@ -358,6 +358,7 @@ impl<'ctx> CodeGen<'ctx> { } } TypedValueType::Err => unreachable!("how did an error kind get here"), + TypedValueType::External => unreachable!("The external linkage should not be compiled") } self.difunction = None; self.dilocals.clear(); @@ -1764,9 +1765,28 @@ impl<'ctx> CodeGen<'ctx> { pub(crate) fn create_define(&mut self, decl: &TypedDeclaration) { match decl { TypedDeclaration::Value(decl) => { - if decl.ty.is_function() { + if let Some(abi) = &decl.abi { + match abi.identifier.as_str() { + "C" => { + let (args,ret) = decl.ty.as_c_function(); + let ret = self.type_resolver.resolve_type_as_basic(ret); + let args = args.into_iter().map(|it| self.type_resolver.resolve_type_as_basic(it).into()).collect_vec(); + let fun = self.module.add_function(&decl.ident, ret.fn_type(&args, false), Some(inkwell::module::Linkage::External)); + + self.known_functions.insert(decl.ident.clone(), fun.as_global_value()); + }, + "intrinsic" => { + ()// do nothing here as this is handled in the code gen itself. eg `let (+) : int32 -> int32 -> int32` which should output an add signed instruction + } + _ => { + println!("unknown abi {}", abi.identifier) + } + } + } else if decl.ty.is_function() { let fun = self.create_curry_list(decl); self.known_functions.insert(decl.ident.clone(), fun); + } else { + //TODO! global values. } } TypedDeclaration::TypeDefinition(def) => match def { @@ -1973,7 +1993,10 @@ impl<'ctx> CodeGen<'ctx> { } #[cfg(debug_assertions)] let _ = self.module.print_to_file("./debug.llvm"); - for decl in ast.declarations { + for decl in ast.declarations.into_iter().filter(|it| match it { + TypedDeclaration::Value(TypedValueDeclaration { value, .. }) if value == &TypedValueType::External => false, + _ => true, + }) { self.compile_decl(decl); } let mut prev_len = self.needsdi.len();