From 3864160f64b831e975164d460eb6dc4bf9ad4bca Mon Sep 17 00:00:00 2001 From: chronium Date: Wed, 3 Mar 2021 21:52:56 +0200 Subject: [PATCH 01/18] The One With Modules I --- comp-be/src/codegen/module.rs | 57 +++++++++++++------- comp-be/src/codegen/unit/mod.rs | 3 ++ comp-be/src/codegen/unit/module.rs | 55 +++++++++++++++++++ main.aat | 8 --- parser/src/ast.rs | 4 ++ parser/src/lexer/mod.rs | 10 ++-- parser/src/lexer/tests.rs | 4 +- parser/src/lexer/token.rs | 4 ++ parser/src/lib.rs | 36 ++++++++++++- parser/src/parser/mod.rs | 20 ++++--- parser/src/parser/pass/type_resolution.rs | 1 + parser/src/tests.rs | 64 +++++++++++++++++++++++ 12 files changed, 225 insertions(+), 41 deletions(-) create mode 100644 comp-be/src/codegen/unit/module.rs diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 6508900..19bd23b 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -15,7 +15,7 @@ use crate::{ mangle_v1::NameMangler, unit::{ alloc_variable, declare_and_compile_function, declare_function, init_record, - store_value, Slot, + store_value, ModuleUnit, Slot, }, CompileError, Scope, ValueTypePair, }, @@ -45,13 +45,13 @@ pub struct AatbeModule { llvm_module: Module, name: String, scope_stack: Vec, - typectx: TypeContext, compile_errors: Vec, record_templates: HashMap, function_templates: HashMap, stdlib_path: Option, internal_functions: HashMap>, compilation_units: HashMap, + root_module: ModuleUnit, } impl AatbeModule { @@ -65,6 +65,8 @@ impl AatbeModule { internal_functions.insert(String::from("len"), Rc::new(AatbeModule::internal_len)); internal_functions.insert(String::from("box"), Rc::new(AatbeModule::internal_box)); + let ast = box base_cu.ast().clone(); + let mut compilation_units = HashMap::new(); compilation_units.insert(name.clone(), base_cu); @@ -73,13 +75,13 @@ impl AatbeModule { llvm_module, name, scope_stack: vec![], - typectx: TypeContext::new(), compile_errors: vec![], record_templates: HashMap::new(), function_templates: HashMap::new(), stdlib_path, internal_functions, compilation_units, + root_module: ModuleUnit::new(ast), } } @@ -96,8 +98,8 @@ impl AatbeModule { .ast() .clone(); - self.decl_pass(&main_ast); - self.codegen_pass(&main_ast); + self.decl_pass(); + self.codegen_pass(); self.exit_scope(); } @@ -131,8 +133,9 @@ impl AatbeModule { } } - pub fn decl_pass(&mut self, ast: &AST) { - match ast { + pub fn decl_pass(&mut self) { + self.root_module.decl(); + /*match ast { AST::Constant { .. } | AST::Global { .. } => {} AST::Record(name, None, types) => { let rec = Record::new(self, name, types); @@ -184,13 +187,17 @@ impl AatbeModule { AST::Typedef { type_names: None, .. } => self.gen_newtype_ctors(&ast), + AST::Module(name, ast) => { + self.root_module.push(name, ModuleUnit::new(ast.clone())); + } _ => panic!("cannot decl {:?}", ast), - } + }*/ } #[allow(unused_unsafe)] pub fn gen_variants(&mut self, typedef: &AST) { - match typedef { + todo!() + /*match typedef { AST::Typedef { name, type_names: None, @@ -329,11 +336,12 @@ impl AatbeModule { }); } _ => unreachable!(), - } + }*/ } pub fn gen_newtype_ctors(&mut self, typedef: &AST) { - match typedef { + todo!() + /*match typedef { AST::Typedef { name, type_names: None, @@ -381,7 +389,7 @@ impl AatbeModule { } } _ => unreachable!(), - } + }*/ } pub fn get_interior_pointer(&self, parts: Vec) -> Option { @@ -593,12 +601,13 @@ impl AatbeModule { ret } Expression::Atom(atom) => self.codegen_atom(atom), - _ => panic!(format!("ICE: codegen_expr {:?}", expr)), + _ => panic!("ICE: codegen_expr {:?}", expr), } } - pub fn codegen_pass(&mut self, ast: &AST) -> Option { - match ast { + pub fn codegen_pass(&mut self) -> Option { + self.root_module.codegen() + /*match ast { AST::Constant { ty: PrimitiveType::NamedType { name, ty: _ }, export, @@ -626,8 +635,13 @@ impl AatbeModule { AST::Import(..) => None, AST::Record(..) => None, AST::Typedef { .. } => None, + AST::Module(name, _) => self + .root_module + .get_mut(name) + .expect(format!("ICE: Module codegen but none found").as_str()) + .codegen(), _ => panic!("cannot codegen {:?}", ast), - } + }*/ } pub fn start_scope(&mut self) { @@ -926,7 +940,8 @@ impl AatbeModule { } pub fn propagate_types_in_record(&mut self, name: &String, types: Vec) { - let rec = format!( + todo!() + /*let rec = format!( "{}[{}]", name, types @@ -973,7 +988,7 @@ impl AatbeModule { .get_record(&rec) .unwrap() .set_body(self, &fields); - } + }*/ } pub fn fdir(&self) -> PathBuf { @@ -1003,11 +1018,13 @@ impl AatbeModule { } pub fn typectx_ref(&self) -> &TypeContext { - &self.typectx + todo!() + //&self.typectx } pub fn typectx_ref_mut(&mut self) -> &mut TypeContext { - &mut self.typectx + todo!() + //&mut self.typectx } pub fn add_error(&mut self, error: CompileError) { diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index fea2d57..b1a035e 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -11,6 +11,9 @@ pub use function::{ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; +pub mod module; +pub use module::ModuleUnit; + #[derive(Debug, Clone)] pub enum Mutability { Immutable, diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs new file mode 100644 index 0000000..f2d8200 --- /dev/null +++ b/comp-be/src/codegen/unit/module.rs @@ -0,0 +1,55 @@ +use std::collections::HashMap; + +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::AST; + +use crate::ty::TypeContext; + +pub struct ModuleUnit { + modules: HashMap, + ast: Box, + typectx: TypeContext, +} + +impl ModuleUnit { + pub fn new(ast: Box) -> Self { + Self { + modules: HashMap::new(), + ast, + typectx: TypeContext::new(), + } + } + + pub fn push(&mut self, name: &String, module: ModuleUnit) -> Option { + self.modules.insert(name.clone(), module) + } + + pub fn get_mut(&mut self, name: &String) -> Option<&mut Self> { + self.modules.get_mut(name) + } + + pub fn decl(&mut self) { + match self.ast { + box AST::File(ref nodes) => nodes + .iter() + .fold(Some(()), |_, ast| Some(decl(ast))) + .unwrap(), + _ => todo!("{:?}", self.ast), + } + } + + pub fn codegen(&mut self) -> Option { + match self.ast { + box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| codegen(n)), + _ => todo!("{:?}", self.ast), + } + } +} + +pub fn decl(ast: &AST) { + todo!() +} + +pub fn codegen(ast: &AST) -> Option { + todo!() +} diff --git a/main.aat b/main.aat index b8a2580..8b13789 100644 --- a/main.aat +++ b/main.aat @@ -1,9 +1 @@ -fn foo i: i32* -> () = {} -@entry -fn main() -> () = { - val i = 32 - val fa = [i] - - foo fa as [i32] -} diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 09c063e..251f3b0 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -1,5 +1,7 @@ use std::fmt; +type ModPath = Vec; + #[derive(Debug, PartialEq, Clone)] pub enum AST { File(Vec), @@ -22,6 +24,7 @@ pub enum AST { export: bool, value: Box, }, + Module(String, Box), } #[derive(Debug, PartialEq, Clone)] @@ -144,6 +147,7 @@ pub enum PrimitiveType { }, Symbol(String), Box(Box), + Path(ModPath), } impl PrimitiveType { diff --git a/parser/src/lexer/mod.rs b/parser/src/lexer/mod.rs index 1a957b9..946830d 100644 --- a/parser/src/lexer/mod.rs +++ b/parser/src/lexer/mod.rs @@ -239,9 +239,13 @@ impl<'c> Lexer<'c> { ',' => { symbol!(tokens, Symbol::Comma, pos); } - ':' => { - symbol!(tokens, Symbol::Colon, pos); - } + ':' => match self.chars.peek() { + Some(':') => { + self.advance(); + symbol!(tokens, Symbol::Doubly, pos) + } + _ => symbol!(tokens, Symbol::Colon, pos), + }, '%' => { symbol!(tokens, Symbol::Modulo, pos); } diff --git a/parser/src/lexer/tests.rs b/parser/src/lexer/tests.rs index 65a689a..b82c6ca 100644 --- a/parser/src/lexer/tests.rs +++ b/parser/src/lexer/tests.rs @@ -150,7 +150,7 @@ mod lexer_tests { #[test] fn keyword_identifier() { let mut lexer = Lexer::new( - "fn extern var val if else use true false main record.test bool rec global ret while until type is exp", + "fn extern var val if else use true false main record.test bool rec global ret while until type is exp module", ); let mut tokens = lexer.lex().into_iter(); @@ -199,6 +199,8 @@ mod lexer_tests { assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Is)); sep!(tokens); assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Exp)); + sep!(tokens); + assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Module)); } #[test] diff --git a/parser/src/lexer/token.rs b/parser/src/lexer/token.rs index 99b0711..886fe04 100644 --- a/parser/src/lexer/token.rs +++ b/parser/src/lexer/token.rs @@ -60,6 +60,7 @@ pub enum Symbol { Dot, DoDot, GoDot, + Doubly, } impl From for String { @@ -82,6 +83,7 @@ impl From for String { Symbol::And => String::from("&&"), Symbol::Xor => String::from("^"), Symbol::Modulo => String::from("%"), + Symbol::Doubly => String::from("::"), _ => panic!("Symbol to str {:?}", sym), } } @@ -114,6 +116,7 @@ pub enum Keyword { Type, Is, Exp, + Module, } #[derive(Debug, Eq, PartialEq, Clone, Copy)] @@ -252,6 +255,7 @@ impl FromStr for Keyword { "type" => Ok(Self::Type), "is" => Ok(Self::Is), "exp" => Ok(Self::Exp), + "module" => Ok(Self::Module), _ => Err(()), } } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 582947c..6eab97e 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -64,7 +64,25 @@ impl Parser { sym!(RBracket, self); Some(PrimitiveType::GenericTypeRef(tyref, types)) } else { - Some(PrimitiveType::TypeRef(tyref)) + if matches!(self.peek_symbol(Symbol::Doubly), Some(true)) { + let mut res = vec![tyref]; + self.next(); + loop { + match self.peek_ident() { + None => break, + Some(ty) => { + self.next(); + res.push(ty); + if matches!(self.peek_symbol(Symbol::Doubly), Some(true)) { + self.next(); + } + } + } + } + Some(PrimitiveType::Path(res)) + } else { + Some(PrimitiveType::TypeRef(tyref)) + } } } None => None, @@ -335,4 +353,20 @@ impl Parser { }, })) } + + fn parse_module(&mut self) -> ParseResult { + if kw!(bool Module, self) { + let name = ident!(required self); + sym!(required LCurly, self); + if sym!(bool RCurly, self) { + Ok(AST::Module(name, box AST::File(vec![]))) + } else { + let res = Ok(AST::Module(name, box self.parse()?)); + sym!(required RCurly, self); + res + } + } else { + Err(ParseError::Continue) + } + } } diff --git a/parser/src/parser/mod.rs b/parser/src/parser/mod.rs index 659dc96..cb5db7a 100644 --- a/parser/src/parser/mod.rs +++ b/parser/src/parser/mod.rs @@ -133,14 +133,18 @@ impl Parser { None => break Err(ParseError::InvalidEOF), }; - res.push( - capture!(res parse_use, self) - .or_else(|_| capture!(res parse_function, self)) - .or_else(|_| capture!(res parse_record, self)) - .or_else(|_| capture!(res parse_const_global, self)) - .or_else(|_| capture!(res parse_typedef, self)) - .unwrap_or_else(|r| panic!("{:?} {:?}", r, self.peek())), - ); + let result = capture!(res parse_use, self) + .or_else(|_| capture!(res parse_function, self)) + .or_else(|_| capture!(res parse_record, self)) + .or_else(|_| capture!(res parse_const_global, self)) + .or_else(|_| capture!(res parse_typedef, self)) + .or_else(|_| capture!(res parse_module, self)); + + match result { + Err(ParseError::Continue) => break Ok(()), + Err(err) => panic!("{:?} {:?}", err, self.peek()), + Ok(ast) => res.push(ast), + }; }?; Ok(pass::type_resolution(&self.variants, &AST::File(res))) diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 0c21eb3..8e78ebf 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -27,6 +27,7 @@ pub fn type_resolution(variants: &Vec, ast: &AST) -> AST { types.clone(), fields.iter().map(|f| resolve_prim(variants, f)).collect(), ), + AST::Module(_, _) => ast.clone(), _ => panic!("unhandled {:?}", ast), } } diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 3372c2f..327e55b 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -874,4 +874,68 @@ type Complex = u8 | u16 | Comp @str ]) ); } + + #[test] + fn empty_module() { + let pt = parse_test!( + " +module mod { + +}", + "Parse Module" + ); + + assert_eq!( + pt, + AST::File(vec![AST::Module("mod".to_string(), box AST::File(vec![]))]) + ); + } + + #[test] + fn module() { + let pt = parse_test!( + " +module mod { + + type Opaque + +}", + "Parse Module" + ); + + assert_eq!( + pt, + AST::File(vec![AST::Module( + "mod".to_string(), + box AST::File(vec![AST::Typedef { + name: String::from("Opaque"), + type_names: None, + variants: None, + }]) + )]) + ); + } + + #[test] + fn module_path() { + let pt = parse_test!( + " +type Newtype = mod::test::next +", + "Typedef tests" + ); + + assert_eq!( + pt, + AST::File(vec![AST::Typedef { + name: String::from("Newtype"), + type_names: None, + variants: Some(vec![TypeKind::Newtype(PrimitiveType::Path(vec![ + "mod".to_string(), + "test".to_string(), + "next".to_string(), + ]))]), + },]) + ); + } } From 7fad56c3591ba72940f71eaf1860eb7a0aacc6e2 Mon Sep 17 00:00:00 2001 From: chronium Date: Thu, 4 Mar 2021 00:54:09 +0200 Subject: [PATCH 02/18] The One With Modules II --- comp-be/src/codegen/atom.rs | 9 +- comp-be/src/codegen/builder/cast.rs | 93 ++++++++----------- comp-be/src/codegen/builder/core.rs | 121 +++++++++++-------------- comp-be/src/codegen/builder/ty.rs | 51 +++++------ comp-be/src/codegen/call.rs | 15 +-- comp-be/src/codegen/conditional.rs | 10 +- comp-be/src/codegen/expr/const_expr.rs | 5 +- comp-be/src/codegen/mangle_v1.rs | 50 +++++----- comp-be/src/codegen/module.rs | 52 +++++------ comp-be/src/codegen/unit/comp/mod.rs | 6 ++ comp-be/src/codegen/unit/decl/expr.rs | 17 ++++ comp-be/src/codegen/unit/decl/mod.rs | 12 +++ comp-be/src/codegen/unit/function.rs | 31 ++++--- comp-be/src/codegen/unit/mod.rs | 8 +- comp-be/src/codegen/unit/module.rs | 103 ++++++++++++++++----- comp-be/src/codegen/unit/variable.rs | 14 +-- comp-be/src/lib.rs | 3 +- comp-be/src/ty/aggregate.rs | 12 +-- comp-be/src/ty/mod.rs | 51 +++++------ comp-be/src/ty/record.rs | 22 ++--- comp-be/src/ty/variant.rs | 12 +-- main.aat | 3 +- 22 files changed, 383 insertions(+), 317 deletions(-) create mode 100644 comp-be/src/codegen/unit/comp/mod.rs create mode 100644 comp-be/src/codegen/unit/decl/expr.rs create mode 100644 comp-be/src/codegen/unit/decl/mod.rs diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index 69cd4c0..8d6f48b 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -14,7 +14,8 @@ use parser::ast::{AtomKind, Boolean, FloatSize, PrimitiveType}; impl AatbeModule { pub fn codegen_atom(&mut self, atom: &AtomKind) -> Option { - match atom { + todo!() + /*match atom { AtomKind::Cast(box val, ty) => { let val = self.codegen_atom(val)?; match (val.prim(), ty) { @@ -228,7 +229,7 @@ impl AatbeModule { Some(op::not(self, value)) } AtomKind::Parenthesized(expr) => self.codegen_expr(expr), - AtomKind::Array(exprs) => { + /*AtomKind::Array(exprs) => { let values = exprs .iter() .filter_map(|expr| self.codegen_expr(expr)) @@ -273,7 +274,7 @@ impl AatbeModule { ) .into(), ) - } + }*/ AtomKind::Is(box val, ty) => match val { AtomKind::Ident(val) => { let var_ref = self.get_var(val).expect("").clone(); @@ -327,6 +328,6 @@ impl AatbeModule { ), }, _ => panic!("ICE codegen_atom {:?}", atom), - } + }*/ } } diff --git a/comp-be/src/codegen/builder/cast.rs b/comp-be/src/codegen/builder/cast.rs index d368fa9..074e9fb 100644 --- a/comp-be/src/codegen/builder/cast.rs +++ b/comp-be/src/codegen/builder/cast.rs @@ -1,132 +1,113 @@ use crate::{ - codegen::{AatbeModule, ValueTypePair}, + codegen::{unit::ModuleContext, ValueTypePair}, ty::variant::VariantType, ty::LLVMTyInCtx, }; use llvm_sys_wrapper::{LLVMTypeRef, LLVMValueRef}; use parser::ast::PrimitiveType; -pub fn zext(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn zext(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_zext(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder.build_zext(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn trunc(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn trunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_trunc(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder.build_trunc(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn ftrunc(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftrunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_fp_trunc(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_fp_trunc(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn itop(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn itop(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_int_to_ptr(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_int_to_ptr(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn ptoi(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ptoi(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_ptr_to_int(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_ptr_to_int(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn stof(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn stof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_si_to_fp(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_si_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn utof(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn utof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_ui_to_fp(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_ui_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn ftos(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftos(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_fp_to_si(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_fp_to_si(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn ftou(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftou(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_fp_to_ui(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder + .build_fp_to_ui(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } -pub fn bitcast(module: &AatbeModule, val: ValueTypePair, ty: &dyn LLVMTyInCtx) -> LLVMValueRef { - module - .llvm_builder_ref() - .build_bitcast(*val, ty.llvm_ty_in_ctx(module)) +pub fn bitcast(ctx: &ModuleContext, val: ValueTypePair, ty: &dyn LLVMTyInCtx) -> LLVMValueRef { + ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)) } -pub fn bitcast_ty(module: &AatbeModule, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn bitcast_ty(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_bitcast(*val, ty.llvm_ty_in_ctx(module)), + ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)), ty, ) .into() } pub fn child_to_parent( - module: &AatbeModule, + ctx: &ModuleContext, val: ValueTypePair, parent: &VariantType, ) -> LLVMValueRef { - module.llvm_builder_ref().build_load( - module.llvm_builder_ref().build_bitcast( - *val, - module - .llvm_context_ref() - .PointerType(parent.llvm_ty_in_ctx(module)), - ), - ) + ctx.llvm_builder.build_load(ctx.llvm_builder.build_bitcast( + *val, + ctx.llvm_context.PointerType(parent.llvm_ty_in_ctx(ctx)), + )) } -pub fn bitcast_to(module: &AatbeModule, val: LLVMValueRef, ty: LLVMTypeRef) -> LLVMValueRef { - module.llvm_builder_ref().build_bitcast(val, ty) +pub fn bitcast_to(ctx: &ModuleContext, val: LLVMValueRef, ty: LLVMTypeRef) -> LLVMValueRef { + ctx.llvm_builder.build_bitcast(val, ty) } diff --git a/comp-be/src/codegen/builder/core.rs b/comp-be/src/codegen/builder/core.rs index 3e66346..57098d7 100644 --- a/comp-be/src/codegen/builder/core.rs +++ b/comp-be/src/codegen/builder/core.rs @@ -1,169 +1,150 @@ use crate::{ - codegen::{unit::function::Func, AatbeModule, ValueTypePair}, + codegen::{ + unit::{function::Func, ModuleContext}, + ValueTypePair, + }, ty::{LLVMTyInCtx, TypeKind}, }; use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMTypeRef, LLVMValueRef}; use parser::ast::{IntSize, PrimitiveType}; -pub fn load(module: &AatbeModule, pointer: LLVMValueRef) -> LLVMValueRef { - module.llvm_builder_ref().build_load(pointer) +pub fn load(ctx: &ModuleContext, pointer: LLVMValueRef) -> LLVMValueRef { + ctx.llvm_builder.build_load(pointer) } -pub fn load_ty(module: &AatbeModule, pointer: LLVMValueRef, ty: TypeKind) -> ValueTypePair { - (module.llvm_builder_ref().build_load(pointer), ty).into() +pub fn load_ty(ctx: &ModuleContext, pointer: LLVMValueRef, ty: TypeKind) -> ValueTypePair { + (ctx.llvm_builder.build_load(pointer), ty).into() } -pub fn load_prim(module: &AatbeModule, pointer: LLVMValueRef, ty: PrimitiveType) -> ValueTypePair { - (module.llvm_builder_ref().build_load(pointer), ty).into() +pub fn load_prim(ctx: &ModuleContext, pointer: LLVMValueRef, ty: PrimitiveType) -> ValueTypePair { + (ctx.llvm_builder.build_load(pointer), ty).into() } -pub fn store(module: &AatbeModule, value: LLVMValueRef, pointer: LLVMValueRef) -> LLVMValueRef { - module.llvm_builder_ref().build_store(value, pointer) +pub fn store(ctx: &ModuleContext, value: LLVMValueRef, pointer: LLVMValueRef) -> LLVMValueRef { + ctx.llvm_builder.build_store(value, pointer) } -pub fn struct_gep(module: &AatbeModule, pointer: LLVMValueRef, index: u32) -> LLVMValueRef { - module.llvm_builder_ref().build_struct_gep(pointer, index) +pub fn struct_gep(ctx: &ModuleContext, pointer: LLVMValueRef, index: u32) -> LLVMValueRef { + ctx.llvm_builder.build_struct_gep(pointer, index) } pub fn struct_gep_with_name( - module: &AatbeModule, + ctx: &ModuleContext, pointer: LLVMValueRef, index: u32, name: &str, ) -> LLVMValueRef { - module - .llvm_builder_ref() + ctx.llvm_builder .build_struct_gep_with_name(pointer, index, name) } pub fn inbounds_gep( - module: &AatbeModule, + ctx: &ModuleContext, pointer: LLVMValueRef, indices: &mut Vec, ) -> LLVMValueRef { - module - .llvm_builder_ref() + ctx.llvm_builder .build_inbounds_gep(pointer, indices.as_mut_slice()) } -pub fn alloca(module: &AatbeModule, ty: LLVMTypeRef) -> LLVMValueRef { - module.llvm_builder_ref().build_alloca(ty) +pub fn alloca(ctx: &ModuleContext, ty: LLVMTypeRef) -> LLVMValueRef { + ctx.llvm_builder.build_alloca(ty) } -pub fn alloca_with_name(module: &AatbeModule, ty: LLVMTypeRef, name: &str) -> LLVMValueRef { - module.llvm_builder_ref().build_alloca_with_name(ty, name) +pub fn alloca_with_name(ctx: &ModuleContext, ty: LLVMTypeRef, name: &str) -> LLVMValueRef { + ctx.llvm_builder.build_alloca_with_name(ty, name) } -pub fn alloca_ty(module: &AatbeModule, ty: &PrimitiveType) -> LLVMValueRef { - module - .llvm_builder_ref() - .build_alloca(ty.llvm_ty_in_ctx(module)) +pub fn alloca_ty(ctx: &ModuleContext, ty: &PrimitiveType) -> LLVMValueRef { + ctx.llvm_builder.build_alloca(ty.llvm_ty_in_ctx(ctx)) } -pub fn alloca_with_name_ty(module: &AatbeModule, ty: &PrimitiveType, name: &str) -> LLVMValueRef { - module - .llvm_builder_ref() - .build_alloca_with_name(ty.llvm_ty_in_ctx(module), name) +pub fn alloca_with_name_ty(ctx: &ModuleContext, ty: &PrimitiveType, name: &str) -> LLVMValueRef { + ctx.llvm_builder + .build_alloca_with_name(ty.llvm_ty_in_ctx(ctx), name) } -pub fn call(module: &AatbeModule, func: &Func, call_args: &mut Vec) -> ValueTypePair { +pub fn call(ctx: &ModuleContext, func: &Func, call_args: &mut Vec) -> ValueTypePair { ( - module - .llvm_builder_ref() + ctx.llvm_builder .build_call(func.as_ref(), call_args.as_mut()), func.ret_ty(), ) .into() } -pub fn extract_i8(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits8), ) .into() } -pub fn extract_i16(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits16), ) .into() } -pub fn extract_i32(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits32), ) .into() } -pub fn extract_i64(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits64), ) .into() } -pub fn extract_u8(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits8), ) .into() } -pub fn extract_u16(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits16), ) .into() } -pub fn extract_u32(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits32), ) .into() } -pub fn extract_u64(module: &AatbeModule, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( - module - .llvm_builder_ref() - .build_extract_value(agg_val, index), + ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits64), ) .into() } -pub fn ret(module: &AatbeModule, val: ValueTypePair) -> ValueTypePair { - (module.llvm_builder_ref().build_ret(*val), val.prim()).into() +pub fn ret(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { + (ctx.llvm_builder.build_ret(*val), val.prim()).into() } -pub fn ret_void(module: &AatbeModule) { - module.llvm_builder_ref().build_ret_void(); +pub fn ret_void(ctx: &ModuleContext) { + ctx.llvm_builder.build_ret_void(); } -pub fn pos_at_end(module: &AatbeModule, bb: LLVMBasicBlockRef) { - module.llvm_builder_ref().position_at_end(bb); +pub fn pos_at_end(ctx: &ModuleContext, bb: LLVMBasicBlockRef) { + ctx.llvm_builder.position_at_end(bb); } diff --git a/comp-be/src/codegen/builder/ty.rs b/comp-be/src/codegen/builder/ty.rs index dfcd94a..7628bca 100644 --- a/comp-be/src/codegen/builder/ty.rs +++ b/comp-be/src/codegen/builder/ty.rs @@ -1,51 +1,44 @@ -use crate::{codegen::AatbeModule, ty::LLVMTyInCtx}; +use crate::{codegen::unit::ModuleContext, ty::LLVMTyInCtx}; use llvm_sys_wrapper::LLVMTypeRef; -pub fn pointer(module: &AatbeModule, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { - module - .llvm_context_ref() - .PointerType(ty.llvm_ty_in_ctx(module)) +pub fn pointer(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { + ctx.llvm_context.PointerType(ty.llvm_ty_in_ctx(ctx)) } -pub fn slice_type(module: &AatbeModule, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { - module - .llvm_context_ref() - .StructType(&mut vec![slice_ptr(module, ty), i32(module)], false) +pub fn slice_type(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { + ctx.llvm_context + .StructType(&mut vec![slice_ptr(ctx, ty), i32(ctx)], false) .as_ref() } -pub fn pointer_to(module: &AatbeModule, ty: LLVMTypeRef) -> LLVMTypeRef { - module.llvm_context_ref().PointerType(ty) +pub fn pointer_to(ctx: &ModuleContext, ty: LLVMTypeRef) -> LLVMTypeRef { + ctx.llvm_context.PointerType(ty) } -pub fn array(module: &AatbeModule, ty: &dyn LLVMTyInCtx, count: u32) -> LLVMTypeRef { - module - .llvm_context_ref() - .ArrayType(ty.llvm_ty_in_ctx(module), count) +pub fn array(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx, count: u32) -> LLVMTypeRef { + ctx.llvm_context.ArrayType(ty.llvm_ty_in_ctx(ctx), count) } -pub fn slice(module: &AatbeModule, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { - module - .llvm_context_ref() - .ArrayType(ty.llvm_ty_in_ctx(module), 0) +pub fn slice(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { + ctx.llvm_context.ArrayType(ty.llvm_ty_in_ctx(ctx), 0) } -pub fn slice_ptr(module: &AatbeModule, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { - pointer_to(module, slice(module, ty)) +pub fn slice_ptr(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { + pointer_to(ctx, slice(ctx, ty)) } -pub fn i8(module: &AatbeModule) -> LLVMTypeRef { - module.llvm_context_ref().Int8Type() +pub fn i8(ctx: &ModuleContext) -> LLVMTypeRef { + ctx.llvm_context.Int8Type() } -pub fn i16(module: &AatbeModule) -> LLVMTypeRef { - module.llvm_context_ref().Int16Type() +pub fn i16(ctx: &ModuleContext) -> LLVMTypeRef { + ctx.llvm_context.Int16Type() } -pub fn i32(module: &AatbeModule) -> LLVMTypeRef { - module.llvm_context_ref().Int32Type() +pub fn i32(ctx: &ModuleContext) -> LLVMTypeRef { + ctx.llvm_context.Int32Type() } -pub fn i64(module: &AatbeModule) -> LLVMTypeRef { - module.llvm_context_ref().Int64Type() +pub fn i64(ctx: &ModuleContext) -> LLVMTypeRef { + ctx.llvm_context.Int64Type() } diff --git a/comp-be/src/codegen/call.rs b/comp-be/src/codegen/call.rs index b257eec..ab3dbbc 100644 --- a/comp-be/src/codegen/call.rs +++ b/comp-be/src/codegen/call.rs @@ -11,7 +11,8 @@ use parser::ast::{AtomKind, Expression, PrimitiveType}; impl AatbeModule { pub fn codegen_call(&mut self, call_expr: &Expression) -> Option { - match call_expr { + todo!() + /*match call_expr { // TODO: generics Expression::Call { name, @@ -134,7 +135,7 @@ impl AatbeModule { Some(core::call(self, func.unwrap(), &mut call_args)) } _ => unreachable!(), - } + }*/ } pub fn internal_len( @@ -142,7 +143,8 @@ impl AatbeModule { values: &Vec, _name: String, ) -> Option { - if values.len() != 1 { + todo!() + /*if values.len() != 1 { return None; } let arr = module.codegen_expr(&values[0])?; @@ -157,7 +159,7 @@ impl AatbeModule { }); None } - } + }*/ } pub fn internal_box( @@ -165,7 +167,8 @@ impl AatbeModule { values: &Vec, _name: String, ) -> Option { - if values.len() != 1 { + todo!("internal_box") + /*if values.len() != 1 { return None; } @@ -184,6 +187,6 @@ impl AatbeModule { core::inbounds_gep(module, ptr, &mut vec![*value::s64(module, 0)]), ); - Some((ptr, PrimitiveType::Box(box val_ty.clone())).into()) + Some((ptr, PrimitiveType::Box(box val_ty.clone())).into())*/ } } diff --git a/comp-be/src/codegen/conditional.rs b/comp-be/src/codegen/conditional.rs index 3d7178e..3fb1a69 100644 --- a/comp-be/src/codegen/conditional.rs +++ b/comp-be/src/codegen/conditional.rs @@ -13,7 +13,8 @@ use llvm_sys_wrapper::Phi; impl AatbeModule { pub fn codegen_if(&mut self, if_expr: &Expression) -> Option { - match if_expr { + todo!("{:?}", if_expr); + /*match if_expr { Expression::If { cond_expr, then_expr, @@ -101,11 +102,12 @@ impl AatbeModule { } } _ => unreachable!(), - } + }*/ } pub fn codegen_basic_loop(&mut self, basic_loop: &Expression) -> Option { - match basic_loop { + todo!() + /*match basic_loop { Expression::Loop { loop_type, cond_expr, @@ -141,6 +143,6 @@ impl AatbeModule { None } _ => unreachable!(), - } + }*/ } } diff --git a/comp-be/src/codegen/expr/const_expr.rs b/comp-be/src/codegen/expr/const_expr.rs index f4840ae..613db08 100644 --- a/comp-be/src/codegen/expr/const_expr.rs +++ b/comp-be/src/codegen/expr/const_expr.rs @@ -48,7 +48,7 @@ fn fold_expression(module: &AatbeModule, expr: &Expression) -> Option Option { - match ast { + /*match ast { AST::Global { ty: PrimitiveType::NamedType { @@ -114,5 +114,6 @@ pub fn fold_constant(module: &mut AatbeModule, ast: &AST) -> Option { value: *val, }), _ => unreachable!(), - } + }*/ + todo!("{:?}", ast) } diff --git a/comp-be/src/codegen/mangle_v1.rs b/comp-be/src/codegen/mangle_v1.rs index e6802a5..f17d592 100644 --- a/comp-be/src/codegen/mangle_v1.rs +++ b/comp-be/src/codegen/mangle_v1.rs @@ -2,12 +2,14 @@ use crate::codegen::AatbeModule; use parser::ast::{AtomKind, Expression, FloatSize, FunctionType, IntSize, PrimitiveType}; +use super::unit::ModuleContext; + pub trait NameMangler { - fn mangle(&self, module: &AatbeModule) -> String; + fn mangle(&self, ctx: &ModuleContext) -> String; } impl NameMangler for Expression { - fn mangle(&self, module: &AatbeModule) -> String { + fn mangle(&self, ctx: &ModuleContext) -> String { match self { Expression::Function { name, @@ -31,7 +33,7 @@ impl NameMangler for Expression { } else { String::default() }, - ty.mangle(module), + ty.mangle(ctx), ) } else { name.clone() @@ -49,27 +51,27 @@ impl NameMangler for Expression { } impl NameMangler for AtomKind { - fn mangle(&self, module: &AatbeModule) -> String { + fn mangle(&self, ctx: &ModuleContext) -> String { match self { AtomKind::StringLiteral(lit) => format!("{:?}", lit), AtomKind::Ident(id) => id.clone(), AtomKind::SymbolLiteral(sym) => format!(":{}", sym), - AtomKind::Floating(val, ty) => format!("{:?}{}", val, ty.mangle(module)), - AtomKind::Integer(val, ty) => format!("{:?}{}", val, ty.mangle(module)), + AtomKind::Floating(val, ty) => format!("{:?}{}", val, ty.mangle(ctx)), + AtomKind::Integer(val, ty) => format!("{:?}{}", val, ty.mangle(ctx)), AtomKind::Access(arr) => arr.join("."), - AtomKind::Parenthesized(val) => format!("{}", val.mangle(module)), - AtomKind::Ref(val) => format!("&{}", val.mangle(module)), + AtomKind::Parenthesized(val) => format!("{}", val.mangle(ctx)), + AtomKind::Ref(val) => format!("&{}", val.mangle(ctx)), _ => panic!("ICE mangle {:?}", self), } } } impl NameMangler for FunctionType { - fn mangle(&self, module: &AatbeModule) -> String { + fn mangle(&self, ctx: &ModuleContext) -> String { let params_mangled = self .params .iter() - .map(|p| p.mangle(module)) + .map(|p| p.mangle(ctx)) .filter(|m| !m.is_empty()) .collect::>() .join("."); @@ -82,35 +84,35 @@ impl NameMangler for FunctionType { } impl NameMangler for PrimitiveType { - fn mangle(&self, module: &AatbeModule) -> String { + fn mangle(&self, ctx: &ModuleContext) -> String { match self { PrimitiveType::TypeRef(ty) => ty.clone(), - PrimitiveType::Function(ty) => ty.mangle(module), + PrimitiveType::Function(ty) => ty.mangle(ctx), // TODO: Handle Unit PrimitiveType::Unit => String::new(), PrimitiveType::NamedType { name: _, ty: Some(ty), - } => ty.mangle(module), + } => ty.mangle(ctx), PrimitiveType::Str => String::from("s"), - PrimitiveType::Int(size) => format!("i{}", size.mangle(module)), - PrimitiveType::UInt(size) => format!("u{}", size.mangle(module)), - PrimitiveType::Float(size) => format!("f{}", size.mangle(module)), + PrimitiveType::Int(size) => format!("i{}", size.mangle(ctx)), + PrimitiveType::UInt(size) => format!("u{}", size.mangle(ctx)), + PrimitiveType::Float(size) => format!("f{}", size.mangle(ctx)), PrimitiveType::Bool => String::from("b"), PrimitiveType::Char => String::from("c"), - PrimitiveType::Ref(r) => format!("R{}", r.mangle(module)), - PrimitiveType::Pointer(p) => format!("P{}", p.mangle(module)), - PrimitiveType::Array { ty, len: _ } => format!("A{}", ty.mangle(module)), - PrimitiveType::Slice { ty } => format!("S{}", ty.mangle(module)), + PrimitiveType::Ref(r) => format!("R{}", r.mangle(ctx)), + PrimitiveType::Pointer(p) => format!("P{}", p.mangle(ctx)), + PrimitiveType::Array { ty, len: _ } => format!("A{}", ty.mangle(ctx)), + PrimitiveType::Slice { ty } => format!("S{}", ty.mangle(ctx)), PrimitiveType::Symbol(name) => format!("N{}", name), - PrimitiveType::VariantType(name) => format!( + /*PrimitiveType::VariantType(name) => format!( "{}", module .typectx_ref() .get_variant(name) .expect(format!("Cannot find variant {}", name).as_str()) .parent_name - ), + ),*/ PrimitiveType::Variant { parent, .. } => parent.clone(), _ => panic!("Cannot name mangle {:?}", self), } @@ -118,7 +120,7 @@ impl NameMangler for PrimitiveType { } impl NameMangler for IntSize { - fn mangle(&self, _module: &AatbeModule) -> String { + fn mangle(&self, _ctx: &ModuleContext) -> String { match self { IntSize::Bits8 => String::from("8"), IntSize::Bits16 => String::from("16"), @@ -129,7 +131,7 @@ impl NameMangler for IntSize { } impl NameMangler for FloatSize { - fn mangle(&self, _module: &AatbeModule) -> String { + fn mangle(&self, _ctx: &ModuleContext) -> String { match self { FloatSize::Bits32 => String::from("32"), FloatSize::Bits64 => String::from("64"), diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 19bd23b..f875c16 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -51,7 +51,6 @@ pub struct AatbeModule { stdlib_path: Option, internal_functions: HashMap>, compilation_units: HashMap, - root_module: ModuleUnit, } impl AatbeModule { @@ -81,7 +80,6 @@ impl AatbeModule { stdlib_path, internal_functions, compilation_units, - root_module: ModuleUnit::new(ast), } } @@ -98,10 +96,17 @@ impl AatbeModule { .ast() .clone(); - self.decl_pass(); - self.codegen_pass(); + let mut root_module = ModuleUnit::new( + box main_ast, + &self.llvm_context, + &self.llvm_module, + &self.llvm_builder_ref(), + ); + + root_module.decl(); + root_module.codegen(); - self.exit_scope(); + //self.exit_scope(); } pub fn parse_import(&mut self, module: &String) -> io::Result { @@ -119,22 +124,8 @@ impl AatbeModule { CompilationUnit::new(path) } - pub fn decl_expr(&mut self, expr: &Expression) { - match expr { - Expression::Function { type_names, .. } if type_names.len() == 0 => { - declare_function(self, expr) - } - Expression::Function { name, .. } => { - if !self.function_templates.contains_key(name) { - self.function_templates.insert(name.clone(), expr.clone()); - } - } - _ => panic!("Top level {:?} unsupported", expr), - } - } + pub fn decl_pass(&mut self, root_module: &mut ModuleUnit) { - pub fn decl_pass(&mut self) { - self.root_module.decl(); /*match ast { AST::Constant { .. } | AST::Global { .. } => {} AST::Record(name, None, types) => { @@ -421,7 +412,8 @@ impl AatbeModule { } pub fn codegen_expr(&mut self, expr: &Expression) -> Option { - match expr { + todo!() + /*match expr { Expression::Ret(box _value) => { let val = self.codegen_expr(_value)?; @@ -466,7 +458,7 @@ impl AatbeModule { Some(core::ret(self, val)) } } - Expression::RecordInit { + /*Expression::RecordInit { record, types, values, @@ -512,7 +504,7 @@ impl AatbeModule { ) .into(), ) - } + }*/ Expression::Assign { lval, value } => match value { box Expression::RecordInit { record, @@ -602,11 +594,11 @@ impl AatbeModule { } Expression::Atom(atom) => self.codegen_atom(atom), _ => panic!("ICE: codegen_expr {:?}", expr), - } + }*/ } - pub fn codegen_pass(&mut self) -> Option { - self.root_module.codegen() + pub fn codegen_pass(&mut self, root_module: &mut ModuleUnit) -> Option { + todo!() /*match ast { AST::Constant { ty: PrimitiveType::NamedType { name, ty: _ }, @@ -828,7 +820,7 @@ impl AatbeModule { } } - pub fn propagate_types_in_function( + /*pub fn propagate_types_in_function( &mut self, name: &String, types: Vec, @@ -937,7 +929,7 @@ impl AatbeModule { } else { None } - } + }*/ pub fn propagate_types_in_record(&mut self, name: &String, types: Vec) { todo!() @@ -1010,11 +1002,11 @@ impl AatbeModule { } pub fn llvm_module_ref(&self) -> &Module { - &self.llvm_module + todo!() //&self.llvm_module } pub fn llvm_context_ref(&self) -> &Context { - &self.llvm_context + todo!() //&self.llvm_context } pub fn typectx_ref(&self) -> &TypeContext { diff --git a/comp-be/src/codegen/unit/comp/mod.rs b/comp-be/src/codegen/unit/comp/mod.rs new file mode 100644 index 0000000..23504da --- /dev/null +++ b/comp-be/src/codegen/unit/comp/mod.rs @@ -0,0 +1,6 @@ +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::AST; + +pub fn comp(ast: &AST) -> Option { + todo!("{:?}", ast) +} diff --git a/comp-be/src/codegen/unit/decl/expr.rs b/comp-be/src/codegen/unit/decl/expr.rs new file mode 100644 index 0000000..669427e --- /dev/null +++ b/comp-be/src/codegen/unit/decl/expr.rs @@ -0,0 +1,17 @@ +use parser::ast::Expression; + +use crate::codegen::unit::{declare_function, ModuleContext}; + +pub fn decl(expr: &Expression, ctx: &mut ModuleContext) { + match expr { + Expression::Function { type_names, .. } if type_names.len() == 0 => { + declare_function(ctx, expr) + } + Expression::Function { name, .. } => { + if !ctx.function_templates.contains_key(name) { + ctx.function_templates.insert(name.clone(), expr.clone()); + } + } + _ => panic!("Top level {:?} unsupported", expr), + } +} diff --git a/comp-be/src/codegen/unit/decl/mod.rs b/comp-be/src/codegen/unit/decl/mod.rs new file mode 100644 index 0000000..1cdbf32 --- /dev/null +++ b/comp-be/src/codegen/unit/decl/mod.rs @@ -0,0 +1,12 @@ +mod expr; + +use parser::ast::AST; + +use super::ModuleContext; + +pub fn decl(ast: &AST, ctx: &mut ModuleContext) { + match ast { + AST::Expr(expr) => expr::decl(expr, ctx), + _ => todo!("{:?}", ast), + } +} diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index e0449a2..35fc11e 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,7 +3,7 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{Mutability, Slot}, + unit::{FuncType, Mutability, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -17,6 +17,8 @@ use parser::ast::{Expression, FunctionType, PrimitiveType}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; +use super::ModuleContext; + #[derive(Debug)] pub struct Func { ty: FunctionType, @@ -118,7 +120,7 @@ impl Func { } } -pub fn declare_function(module: &mut AatbeModule, function: &Expression) { +pub fn declare_function(ctx: &mut ModuleContext, function: &Expression) { match function { Expression::Function { ty, @@ -127,15 +129,15 @@ pub fn declare_function(module: &mut AatbeModule, function: &Expression) { name, .. } if type_names.len() == 0 => { - let func = module - .llvm_module_ref() - .get_or_add_function(&function.mangle(module), ty.llvm_ty_in_ctx(module)); + let func = ctx + .llvm_module + .get_or_add_function(&function.mangle(&ctx), ty.llvm_ty_in_ctx(&ctx)); let func = Func::new(ty.clone(), name.clone(), func); if !export { - module.add_function(&name, func); + (ctx.register_function)(&name, func, FuncType::Local); } else { - module.export_function(&name, func); + (ctx.register_function)(&name, func, FuncType::Export); } } _ => unimplemented!("{:?}", function), @@ -146,7 +148,8 @@ pub fn declare_and_compile_function( module: &mut AatbeModule, func: &Expression, ) -> Option { - match func { + todo!() + /*match func { Expression::Function { ty, body, name, .. } => match ty { FunctionType { ret_ty: _, @@ -197,11 +200,12 @@ pub fn declare_and_compile_function( } }, _ => unreachable!(), - } + }*/ } pub fn codegen_function(module: &mut AatbeModule, function: &Expression) { - match function { + todo!() + /*match function { Expression::Function { attributes, name, @@ -222,11 +226,12 @@ pub fn codegen_function(module: &mut AatbeModule, function: &Expression) { } } _ => unreachable!(), - } + }*/ } pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) { - match function { + todo!() + /*match function { Expression::Function { name: fname, ty, .. } => { @@ -302,7 +307,7 @@ pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) }; } _ => unreachable!(), - } + }*/ } fn has_return_type(func: &FunctionType) -> bool { diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index b1a035e..5ef73e6 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -12,7 +12,13 @@ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; pub mod module; -pub use module::ModuleUnit; +pub use module::{FuncType, ModuleContext, ModuleUnit}; + +pub mod decl; +pub use decl::decl; + +pub mod comp; +pub use comp::comp; #[derive(Debug, Clone)] pub enum Mutability { diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index f2d8200..7ae1585 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -1,26 +1,77 @@ -use std::collections::HashMap; +use std::{ + collections::HashMap, + rc::{Rc, Weak}, +}; -use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::AST; +use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; +use parser::ast::{Expression, AST}; -use crate::ty::TypeContext; +use crate::{ + codegen::unit::{comp, decl}, + ty::TypeContext, +}; -pub struct ModuleUnit { - modules: HashMap, +use super::function::Func; + +pub enum FuncType { + Local, + Export, +} + +pub struct ModuleContext<'ctx> { + pub llvm_context: &'ctx Context, + pub llvm_module: &'ctx Module, + pub llvm_builder: &'ctx Builder, + pub function_templates: HashMap, + pub register_function: &'ctx mut dyn FnMut(&String, Func, FuncType) -> (), +} + +impl<'ctx> ModuleContext<'ctx> { + pub fn new( + llvm_context: &'ctx Context, + llvm_module: &'ctx Module, + llvm_builder: &'ctx Builder, + register_function: &'ctx mut dyn FnMut(&String, Func, FuncType) -> (), + ) -> Self { + Self { + llvm_context, + llvm_module, + llvm_builder, + function_templates: HashMap::new(), + register_function, + } + } +} + +pub struct ModuleUnit<'ctx> { + modules: HashMap>, ast: Box, typectx: TypeContext, + llvm_context: &'ctx Context, + llvm_module: &'ctx Module, + llvm_builder: &'ctx Builder, } -impl ModuleUnit { - pub fn new(ast: Box) -> Self { +impl<'ctx> ModuleUnit<'ctx> { + pub fn new( + ast: Box, + llvm_context: &'ctx Context, + llvm_module: &'ctx Module, + llvm_builder: &'ctx Builder, + ) -> Self { Self { modules: HashMap::new(), ast, typectx: TypeContext::new(), + llvm_context, + llvm_module, + llvm_builder, } } - pub fn push(&mut self, name: &String, module: ModuleUnit) -> Option { + fn register_function(&mut self, name: &String, func: Func, func_type: FuncType) {} + + pub fn push(&mut self, name: &String, module: ModuleUnit<'ctx>) -> Option> { self.modules.insert(name.clone(), module) } @@ -29,27 +80,37 @@ impl ModuleUnit { } pub fn decl(&mut self) { - match self.ast { + let ast = self.ast.clone(); + let llvm_context = self.llvm_context; + let llvm_module = self.llvm_module; + let llvm_builder = self.llvm_builder; + let register_function = &mut |name: &String, func: Func, func_type: FuncType| { + self.register_function(name, func, func_type) + }; + let mut ctx = + ModuleContext::new(llvm_context, llvm_module, llvm_builder, register_function); + match ast { box AST::File(ref nodes) => nodes .iter() - .fold(Some(()), |_, ast| Some(decl(ast))) + .fold(Some(()), |_, ast| Some(decl(ast, &mut ctx))) .unwrap(), _ => todo!("{:?}", self.ast), } } pub fn codegen(&mut self) -> Option { - match self.ast { - box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| codegen(n)), + let ast = self.ast.clone(); + let llvm_context = self.llvm_context; + let llvm_module = self.llvm_module; + let llvm_builder = self.llvm_builder; + let register_function = &mut |name: &String, func: Func, func_type: FuncType| { + self.register_function(name, func, func_type) + }; + let mut ctx = + ModuleContext::new(llvm_context, llvm_module, llvm_builder, register_function); + match ast { + box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| comp(n)), _ => todo!("{:?}", self.ast), } } } - -pub fn decl(ast: &AST) { - todo!() -} - -pub fn codegen(ast: &AST) -> Option { - todo!() -} diff --git a/comp-be/src/codegen/unit/variable.rs b/comp-be/src/codegen/unit/variable.rs index d5f3add..f58d7ed 100644 --- a/comp-be/src/codegen/unit/variable.rs +++ b/comp-be/src/codegen/unit/variable.rs @@ -107,9 +107,10 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option if value.is_none() { let ty = ty.as_ref().expect("ICE: Ty none for none value"); - let val_ref = module - .llvm_builder_ref() - .build_alloca_with_name(ty.llvm_ty_in_ctx(module), name.as_ref()); + let val_ref = module.llvm_builder_ref().build_alloca_with_name( + todo!(), /*ty.llvm_ty_in_ctx(module)*/ + name.as_ref(), + ); module.push_in_scope( name, @@ -137,7 +138,7 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option let var_ref = module .llvm_builder_ref() - .build_alloca_with_name(ty.llvm_ty_in_ctx(module), name.as_ref()); + .build_alloca_with_name(todo!() /*ty.llvm_ty_in_ctx(module)*/, name.as_ref()); module.push_in_scope( name, @@ -236,7 +237,8 @@ pub fn init_record( lval: &LValue, rec: &Expression, ) -> Option { - fn get_lval(module: &mut AatbeModule, lvalue: &LValue) -> Option { + todo!() + /*fn get_lval(module: &mut AatbeModule, lvalue: &LValue) -> Option { match lvalue { LValue::Ident(name) => match module.get_var(name) { None => panic!("Cannot find variable {}", name), @@ -325,7 +327,7 @@ pub fn init_record( } }), _ => unreachable!(), - } + }*/ } pub fn store_value( diff --git a/comp-be/src/lib.rs b/comp-be/src/lib.rs index 8ffc12a..1f44c7b 100644 --- a/comp-be/src/lib.rs +++ b/comp-be/src/lib.rs @@ -6,7 +6,8 @@ option_expect_none, or_patterns, bindings_after_at, - type_alias_impl_trait + type_alias_impl_trait, + in_band_lifetimes )] pub mod codegen; diff --git a/comp-be/src/ty/aggregate.rs b/comp-be/src/ty/aggregate.rs index 5d20d0e..1edc58e 100644 --- a/comp-be/src/ty/aggregate.rs +++ b/comp-be/src/ty/aggregate.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{AatbeModule, ValueTypePair}, + codegen::{unit::ModuleContext, AatbeModule, ValueTypePair}, ty::TypeResult, }; @@ -8,28 +8,28 @@ use llvm_sys_wrapper::LLVMValueRef; pub trait Aggregate { fn gep_indexed_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult; fn gep_named_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult; fn gep_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult { if let Ok(index) = name.parse::() { - self.gep_indexed_field(module, index, aggregate_ref) + self.gep_indexed_field(ctx, index, aggregate_ref) } else { - self.gep_named_field(module, name, aggregate_ref) + self.gep_named_field(ctx, name, aggregate_ref) } } } diff --git a/comp-be/src/ty/mod.rs b/comp-be/src/ty/mod.rs index 3c35dbc..d9d995f 100644 --- a/comp-be/src/ty/mod.rs +++ b/comp-be/src/ty/mod.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{AatbeModule, ValueTypePair}, + codegen::{unit::ModuleContext, AatbeModule, ValueTypePair}, fmt::AatbeFmt, ty::variant::{Variant, VariantType}, }; @@ -7,7 +7,7 @@ use parser::ast::{FloatSize, FunctionType, IntSize, PrimitiveType}; use llvm_sys_wrapper::{LLVMFunctionType, LLVMTypeRef, LLVMValueRef}; -use std::{collections::HashMap, fmt}; +use std::{borrow::Borrow, collections::HashMap, fmt}; pub mod aggregate; pub mod infer; @@ -65,10 +65,10 @@ impl fmt::Debug for TypedefKind { } impl LLVMTyInCtx for TypeKind { - fn llvm_ty_in_ctx(&self, module: &AatbeModule) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef { match self { - TypeKind::RecordType(record) => record.llvm_ty_in_ctx(module), - TypeKind::Primitive(primitive) => primitive.llvm_ty_in_ctx(module), + TypeKind::RecordType(record) => record.llvm_ty_in_ctx(ctx), + TypeKind::Primitive(primitive) => primitive.llvm_ty_in_ctx(ctx), TypeKind::Typedef(TypedefKind::Opaque(ty)) => *ty, TypeKind::Typedef(TypedefKind::Newtype(ty, _)) => *ty, TypeKind::Typedef(TypedefKind::VariantType(VariantType { ty, .. })) => *ty, @@ -212,7 +212,8 @@ impl TypeContext { fields: Vec, reference: LLVMValueRef, ) -> TypeResult { - match fields.as_slice() { + todo!() + /*match fields.as_slice() { [field] => ty.gep_field(module, field, reference), [field, subfields @ ..] => { let field = ty.gep_field(module, field, reference)?; @@ -224,33 +225,33 @@ impl TypeContext { self.gep_fields(module, ty, subfields.to_vec(), *field) } [] => unreachable!(), - } + }*/ } } pub trait LLVMTyInCtx { - fn llvm_ty_in_ctx(&self, module: &AatbeModule) -> LLVMTypeRef; + fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef; } impl LLVMTyInCtx for FunctionType { - fn llvm_ty_in_ctx(&self, module: &AatbeModule) -> LLVMTypeRef { - let ret = self.ret_ty.llvm_ty_in_ctx(module); + fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef { + let ret = self.ret_ty.llvm_ty_in_ctx(ctx); let mut varargs = false; let ext = self.ext; let mut param_types = self .params .iter() .filter_map(|t| match t { - PrimitiveType::TypeRef(name) => { + /*PrimitiveType::TypeRef(name) => { Some(module.typectx_ref().get_type(name)?.llvm_ty_in_ctx(module)) - } + }*/ PrimitiveType::Symbol(_) => None, PrimitiveType::Unit => None, PrimitiveType::Varargs => { varargs = true; None } - PrimitiveType::NamedType { + /*PrimitiveType::NamedType { ty: Some(box PrimitiveType::Slice { ty: box ty }), .. } @@ -262,8 +263,8 @@ impl LLVMTyInCtx for FunctionType { .llvm_context_ref() .PointerType(ty.llvm_ty_in_ctx(module)), ) - } - _ => Some(t.llvm_ty_in_ctx(module)), + }*/ + _ => Some(t.llvm_ty_in_ctx(ctx)), }) .collect::>(); @@ -279,21 +280,21 @@ impl LLVMTyInCtx for FunctionType { } impl LLVMTyInCtx for PrimitiveType { - fn llvm_ty_in_ctx(&self, module: &AatbeModule) -> LLVMTypeRef { - let ctx = module.llvm_context_ref(); + fn llvm_ty_in_ctx(&self, mctx: &ModuleContext) -> LLVMTypeRef { + let ctx = mctx.llvm_context; match self { PrimitiveType::Slice { ty } => ctx .StructType( &mut vec![ - ctx.PointerType(ctx.ArrayType(ty.llvm_ty_in_ctx(module), 0)), + ctx.PointerType(ctx.ArrayType(ty.llvm_ty_in_ctx(mctx), 0)), ctx.Int32Type(), ], false, ) .as_ref(), - PrimitiveType::Array { ty, len } => ctx.ArrayType(ty.llvm_ty_in_ctx(module), *len), - PrimitiveType::Ref(r) => ctx.PointerType(r.llvm_ty_in_ctx(module)), + PrimitiveType::Array { ty, len } => ctx.ArrayType(ty.llvm_ty_in_ctx(mctx), *len), + PrimitiveType::Ref(r) => ctx.PointerType(r.llvm_ty_in_ctx(mctx)), PrimitiveType::Unit => ctx.VoidType(), PrimitiveType::Bool => ctx.Int1Type(), PrimitiveType::Int(IntSize::Bits8) | PrimitiveType::UInt(IntSize::Bits8) => { @@ -315,8 +316,8 @@ impl LLVMTyInCtx for PrimitiveType { PrimitiveType::NamedType { name: _, ty: Some(ty), - } => ty.llvm_ty_in_ctx(module), - PrimitiveType::TypeRef(name) => module + } => ty.llvm_ty_in_ctx(mctx), + /*PrimitiveType::TypeRef(name) => module .typectx_ref() .llvm_ty_in_ctx(name) .expect(format!("Type {} is not declared", name).as_str()) @@ -365,10 +366,8 @@ impl LLVMTyInCtx for PrimitiveType { .get_parent_for_variant(variant) .expect("ICE") .ty - } - PrimitiveType::Box(box val) => module - .llvm_context_ref() - .PointerType(val.llvm_ty_in_ctx(module)), + }*/ + PrimitiveType::Box(box val) => ctx.PointerType(val.llvm_ty_in_ctx(mctx)), _ => panic!("ICE: llvm_ty_in_ctx {:?}", self), } } diff --git a/comp-be/src/ty/record.rs b/comp-be/src/ty/record.rs index 7534987..0d43953 100644 --- a/comp-be/src/ty/record.rs +++ b/comp-be/src/ty/record.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, AatbeModule, ValueTypePair}, + codegen::{builder::core, unit::ModuleContext, AatbeModule, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; use parser::ast::PrimitiveType; @@ -35,10 +35,10 @@ impl Record { } } - pub fn set_body(&self, module: &AatbeModule, types: &Vec) { + pub fn set_body(&self, ctx: &ModuleContext, types: &Vec) { let mut types = types .iter() - .map(|ty| ty.llvm_ty_in_ctx(module)) + .map(|ty| ty.llvm_ty_in_ctx(ctx)) .collect::>(); self.inner.set_body(&mut types, false); @@ -57,12 +57,12 @@ impl Record { impl Aggregate for Record { fn gep_indexed_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult { Ok(( - core::struct_gep(module, aggregate_ref, index), + core::struct_gep(ctx, aggregate_ref, index), self.types .get(&index) .ok_or(TypeError::RecordIndexOOB(self.name.clone(), index))? @@ -73,7 +73,7 @@ impl Aggregate for Record { fn gep_named_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult { @@ -84,7 +84,7 @@ impl Aggregate for Record { )), Some(index) => { let ty = self.types.get(index).cloned().unwrap(); - let gep = core::struct_gep(module, aggregate_ref, *index); + let gep = core::struct_gep(ctx, aggregate_ref, *index); Ok((gep, ty).into()) } } @@ -92,7 +92,7 @@ impl Aggregate for Record { } pub fn store_named_field( - module: &AatbeModule, + ctx: &ModuleContext, struct_ref: LLVMValueRef, rec_name: &String, rec: &Record, @@ -104,7 +104,7 @@ pub fn store_named_field( .expect(format!("Cannot find field {:?} in {:?}\0", name, rec.name).as_str()); let gep = core::struct_gep_with_name( - module, + ctx, struct_ref, index.0, format!("{}.{}\0", rec_name, name).as_str(), @@ -113,13 +113,13 @@ pub fn store_named_field( if value.prim() != &index.1 { Err(index.1) } else { - module.llvm_builder_ref().build_store(*value, gep); + core::store(ctx, *value, gep); Ok(()) } } impl LLVMTyInCtx for &Record { - fn llvm_ty_in_ctx(&self, _module: &AatbeModule) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _ctx: &ModuleContext) -> LLVMTypeRef { self.inner.as_ref() } } diff --git a/comp-be/src/ty/variant.rs b/comp-be/src/ty/variant.rs index 8467bc4..043811c 100644 --- a/comp-be/src/ty/variant.rs +++ b/comp-be/src/ty/variant.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, AatbeModule, ValueTypePair}, + codegen::{builder::core, unit::ModuleContext, AatbeModule, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; @@ -21,7 +21,7 @@ impl VariantType { } impl LLVMTyInCtx for VariantType { - fn llvm_ty_in_ctx(&self, _: &AatbeModule) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _: &ModuleContext) -> LLVMTypeRef { self.ty } } @@ -36,7 +36,7 @@ pub struct Variant { } impl LLVMTyInCtx for Variant { - fn llvm_ty_in_ctx(&self, _: &AatbeModule) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _: &ModuleContext) -> LLVMTypeRef { self.ty } } @@ -54,7 +54,7 @@ impl VariantType { impl Aggregate for Variant { fn gep_indexed_field( &self, - module: &AatbeModule, + ctx: &ModuleContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult { @@ -64,7 +64,7 @@ impl Aggregate for Variant { Err(TypeError::VariantOOB(self.name.clone(), index)) } Some(types) => Ok(( - core::struct_gep(module, aggregate_ref, index + 1), + core::struct_gep(ctx, aggregate_ref, index + 1), types[index as usize].clone(), ) .into()), @@ -73,7 +73,7 @@ impl Aggregate for Variant { fn gep_named_field( &self, - _module: &AatbeModule, + _ctx: &ModuleContext, name: &String, _aggregate_ref: LLVMValueRef, ) -> TypeResult { diff --git a/main.aat b/main.aat index 8b13789..12b4e7a 100644 --- a/main.aat +++ b/main.aat @@ -1 +1,2 @@ - +@entry +fn main () -> () = {} From 77b1b06b0f9742ceea7265d2098b70561268fb5e Mon Sep 17 00:00:00 2001 From: chronium Date: Thu, 4 Mar 2021 20:44:01 +0200 Subject: [PATCH 03/18] The One With Modules III --- comp-be/src/codegen/builder/branch.rs | 10 +-- comp-be/src/codegen/builder/op.rs | 18 +++--- comp-be/src/codegen/builder/value.rs | 84 ++++++++++++-------------- comp-be/src/codegen/expr/compare.rs | 32 +++++----- comp-be/src/codegen/expr/const_expr.rs | 26 ++++---- comp-be/src/codegen/expr/eqne.rs | 20 +++--- comp-be/src/codegen/expr/math.rs | 38 ++++++------ comp-be/src/codegen/expr/mod.rs | 49 +++++++-------- comp-be/src/codegen/mod.rs | 5 +- comp-be/src/codegen/module.rs | 46 ++++++-------- comp-be/src/codegen/scope.rs | 25 ++++---- comp-be/src/codegen/unit/function.rs | 14 ++++- comp-be/src/codegen/unit/mod.rs | 2 +- comp-be/src/codegen/unit/module.rs | 84 ++++++++++++++++++-------- comp-be/src/codegen/unit/variable.rs | 30 +++++---- comp-be/src/ty/infer.rs | 8 +-- 16 files changed, 266 insertions(+), 225 deletions(-) diff --git a/comp-be/src/codegen/builder/branch.rs b/comp-be/src/codegen/builder/branch.rs index acd75bb..8356ca4 100644 --- a/comp-be/src/codegen/builder/branch.rs +++ b/comp-be/src/codegen/builder/branch.rs @@ -1,17 +1,17 @@ -use crate::codegen::AatbeModule; +use crate::codegen::unit::ModuleContext; use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMValueRef}; -pub fn branch(module: &AatbeModule, block: LLVMBasicBlockRef) -> LLVMValueRef { - module.llvm_builder_ref().build_br(block) +pub fn branch(module: &ModuleContext, block: LLVMBasicBlockRef) -> LLVMValueRef { + module.llvm_builder.build_br(block) } pub fn cond_branch( - module: &AatbeModule, + module: &ModuleContext, cond: LLVMValueRef, then_block: LLVMBasicBlockRef, else_block: LLVMBasicBlockRef, ) -> LLVMValueRef { module - .llvm_builder_ref() + .llvm_builder .build_cond_br(cond, then_block, else_block) } diff --git a/comp-be/src/codegen/builder/op.rs b/comp-be/src/codegen/builder/op.rs index 0f1d127..0a46dbc 100644 --- a/comp-be/src/codegen/builder/op.rs +++ b/comp-be/src/codegen/builder/op.rs @@ -1,22 +1,22 @@ -use crate::codegen::{AatbeModule, ValueTypePair}; +use crate::codegen::{unit::ModuleContext, ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; use parser::ast::PrimitiveType; -pub fn neg(module: &AatbeModule, val: ValueTypePair) -> ValueTypePair { - (module.llvm_builder_ref().build_neg(*val), val.prim()).into() +pub fn neg(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { + (ctx.llvm_builder.build_neg(*val), val.prim()).into() } -pub fn fneg(module: &AatbeModule, val: ValueTypePair) -> ValueTypePair { - (module.llvm_builder_ref().build_fneg(*val), val.prim()).into() +pub fn fneg(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { + (ctx.llvm_builder.build_fneg(*val), val.prim()).into() } -pub fn not(module: &AatbeModule, val: ValueTypePair) -> ValueTypePair { - (module.llvm_builder_ref().build_not(*val), val.prim()).into() +pub fn not(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { + (ctx.llvm_builder.build_not(*val), val.prim()).into() } -pub fn ieq(module: &AatbeModule, lhs: LLVMValueRef, rhs: LLVMValueRef) -> ValueTypePair { +pub fn ieq(ctx: &ModuleContext, lhs: LLVMValueRef, rhs: LLVMValueRef) -> ValueTypePair { ( - module.llvm_builder_ref().build_icmp_eq(lhs, rhs), + ctx.llvm_builder.build_icmp_eq(lhs, rhs), PrimitiveType::Bool, ) .into() diff --git a/comp-be/src/codegen/builder/value.rs b/comp-be/src/codegen/builder/value.rs index 11a0a30..16e4e7d 100644 --- a/comp-be/src/codegen/builder/value.rs +++ b/comp-be/src/codegen/builder/value.rs @@ -1,140 +1,136 @@ -use crate::codegen::{AatbeModule, ValueTypePair}; +use crate::codegen::{unit::ModuleContext, ValueTypePair}; use llvm_sys_wrapper::{LLVMValueRef, Struct}; use parser::ast::{FloatSize, IntSize, PrimitiveType}; -pub fn t(module: &AatbeModule) -> ValueTypePair { - (module.llvm_context_ref().SInt1(1), PrimitiveType::Bool).into() +pub fn t(ctx: &ModuleContext) -> ValueTypePair { + (ctx.llvm_context.SInt1(1), PrimitiveType::Bool).into() } -pub fn f(module: &AatbeModule) -> ValueTypePair { - (module.llvm_context_ref().SInt1(0), PrimitiveType::Bool).into() +pub fn f(ctx: &ModuleContext) -> ValueTypePair { + (ctx.llvm_context.SInt1(0), PrimitiveType::Bool).into() } -pub fn char(module: &AatbeModule, c: char) -> ValueTypePair { - ( - module.llvm_context_ref().SInt8(c as u64), - PrimitiveType::Char, - ) - .into() +pub fn char(ctx: &ModuleContext, c: char) -> ValueTypePair { + (ctx.llvm_context.SInt8(c as u64), PrimitiveType::Char).into() } -pub fn s8(module: &AatbeModule, value: i8) -> ValueTypePair { +pub fn s8(ctx: &ModuleContext, value: i8) -> ValueTypePair { ( - module.llvm_context_ref().SInt8(value as u64), + ctx.llvm_context.SInt8(value as u64), PrimitiveType::Int(IntSize::Bits8), ) .into() } -pub fn s16(module: &AatbeModule, value: i16) -> ValueTypePair { +pub fn s16(ctx: &ModuleContext, value: i16) -> ValueTypePair { ( - module.llvm_context_ref().SInt16(value as u64), + ctx.llvm_context.SInt16(value as u64), PrimitiveType::Int(IntSize::Bits16), ) .into() } -pub fn s32(module: &AatbeModule, value: i32) -> ValueTypePair { +pub fn s32(ctx: &ModuleContext, value: i32) -> ValueTypePair { ( - module.llvm_context_ref().SInt32(value as u64), + ctx.llvm_context.SInt32(value as u64), PrimitiveType::Int(IntSize::Bits32), ) .into() } -pub fn s64(module: &AatbeModule, value: i64) -> ValueTypePair { +pub fn s64(ctx: &ModuleContext, value: i64) -> ValueTypePair { ( - module.llvm_context_ref().SInt64(value as u64), + ctx.llvm_context.SInt64(value as u64), PrimitiveType::Int(IntSize::Bits64), ) .into() } -pub fn u8(module: &AatbeModule, value: u8) -> ValueTypePair { +pub fn u8(ctx: &ModuleContext, value: u8) -> ValueTypePair { ( - module.llvm_context_ref().UInt8(value as u64), + ctx.llvm_context.UInt8(value as u64), PrimitiveType::UInt(IntSize::Bits8), ) .into() } -pub fn u16(module: &AatbeModule, value: u16) -> ValueTypePair { +pub fn u16(ctx: &ModuleContext, value: u16) -> ValueTypePair { ( - module.llvm_context_ref().UInt16(value as u64), + ctx.llvm_context.UInt16(value as u64), PrimitiveType::UInt(IntSize::Bits16), ) .into() } -pub fn u32(module: &AatbeModule, value: u32) -> ValueTypePair { +pub fn u32(ctx: &ModuleContext, value: u32) -> ValueTypePair { ( - module.llvm_context_ref().UInt32(value as u64), + ctx.llvm_context.UInt32(value as u64), PrimitiveType::UInt(IntSize::Bits32), ) .into() } -pub fn u64(module: &AatbeModule, value: u64) -> ValueTypePair { +pub fn u64(ctx: &ModuleContext, value: u64) -> ValueTypePair { ( - module.llvm_context_ref().UInt64(value), + ctx.llvm_context.UInt64(value), PrimitiveType::UInt(IntSize::Bits64), ) .into() } pub fn slice( - module: &AatbeModule, + ctx: &ModuleContext, pointer: LLVMValueRef, ty: PrimitiveType, len: u32, ) -> ValueTypePair { ( - Struct::new_const_struct(&mut [pointer, *u32(module, len)], false), + Struct::new_const_struct(&mut [pointer, *u32(ctx, len)], false), PrimitiveType::Slice { ty: box ty }, ) .into() } -pub fn sint(module: &AatbeModule, size: IntSize, value: u64) -> ValueTypePair { +pub fn sint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { ( match size { - IntSize::Bits8 => module.llvm_context_ref().SInt8(value), - IntSize::Bits16 => module.llvm_context_ref().SInt16(value), - IntSize::Bits32 => module.llvm_context_ref().SInt32(value), - IntSize::Bits64 => module.llvm_context_ref().SInt64(value), + IntSize::Bits8 => ctx.llvm_context.SInt8(value), + IntSize::Bits16 => ctx.llvm_context.SInt16(value), + IntSize::Bits32 => ctx.llvm_context.SInt32(value), + IntSize::Bits64 => ctx.llvm_context.SInt64(value), }, PrimitiveType::Int(size), ) .into() } -pub fn uint(module: &AatbeModule, size: IntSize, value: u64) -> ValueTypePair { +pub fn uint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { ( match size { - IntSize::Bits8 => module.llvm_context_ref().UInt8(value), - IntSize::Bits16 => module.llvm_context_ref().UInt16(value), - IntSize::Bits32 => module.llvm_context_ref().UInt32(value), - IntSize::Bits64 => module.llvm_context_ref().UInt64(value), + IntSize::Bits8 => ctx.llvm_context.UInt8(value), + IntSize::Bits16 => ctx.llvm_context.UInt16(value), + IntSize::Bits32 => ctx.llvm_context.UInt32(value), + IntSize::Bits64 => ctx.llvm_context.UInt64(value), }, PrimitiveType::UInt(size), ) .into() } -pub fn floating(module: &AatbeModule, size: FloatSize, value: f64) -> ValueTypePair { +pub fn floating(ctx: &ModuleContext, size: FloatSize, value: f64) -> ValueTypePair { ( match size { - FloatSize::Bits32 => module.llvm_context_ref().Float(value), - FloatSize::Bits64 => module.llvm_context_ref().Double(value), + FloatSize::Bits32 => ctx.llvm_context.Float(value), + FloatSize::Bits64 => ctx.llvm_context.Double(value), }, PrimitiveType::Float(size), ) .into() } -pub fn str(module: &AatbeModule, string: &str) -> ValueTypePair { +pub fn str(ctx: &ModuleContext, string: &str) -> ValueTypePair { ( - module.llvm_builder_ref().build_global_string_ptr(string), + ctx.llvm_builder.build_global_string_ptr(string), PrimitiveType::Str, ) .into() diff --git a/comp-be/src/codegen/expr/compare.rs b/comp-be/src/codegen/expr/compare.rs index c68073e..ff0f703 100644 --- a/comp-be/src/codegen/expr/compare.rs +++ b/comp-be/src/codegen/expr/compare.rs @@ -1,20 +1,20 @@ -use crate::codegen::{AatbeModule, ValueTypePair}; +use crate::codegen::{unit::ModuleContext, ValueTypePair}; use parser::ast::PrimitiveType; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_compare_float( - module: &AatbeModule, + module: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "<" => module.llvm_builder_ref().build_fcmp_ult(lhs, rhs), - ">" => module.llvm_builder_ref().build_fcmp_ugt(lhs, rhs), - "<=" => module.llvm_builder_ref().build_fcmp_ule(lhs, rhs), - ">=" => module.llvm_builder_ref().build_fcmp_uge(lhs, rhs), + "<" => module.llvm_builder.build_fcmp_ult(lhs, rhs), + ">" => module.llvm_builder.build_fcmp_ugt(lhs, rhs), + "<=" => module.llvm_builder.build_fcmp_ule(lhs, rhs), + ">=" => module.llvm_builder.build_fcmp_uge(lhs, rhs), _ => panic!("ICE codegen_compare_float unhandled op {}", op), }, PrimitiveType::Bool, @@ -23,17 +23,17 @@ pub fn codegen_compare_float( } pub fn codegen_compare_signed( - module: &AatbeModule, + module: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "<" => module.llvm_builder_ref().build_icmp_slt(lhs, rhs), - ">" => module.llvm_builder_ref().build_icmp_sgt(lhs, rhs), - "<=" => module.llvm_builder_ref().build_icmp_sle(lhs, rhs), - ">=" => module.llvm_builder_ref().build_icmp_sge(lhs, rhs), + "<" => module.llvm_builder.build_icmp_slt(lhs, rhs), + ">" => module.llvm_builder.build_icmp_sgt(lhs, rhs), + "<=" => module.llvm_builder.build_icmp_sle(lhs, rhs), + ">=" => module.llvm_builder.build_icmp_sge(lhs, rhs), _ => panic!("ICE codegen_compare_signed unhandled op {}", op), }, PrimitiveType::Bool, @@ -42,17 +42,17 @@ pub fn codegen_compare_signed( } pub fn codegen_compare_unsigned( - module: &AatbeModule, + module: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "<" => module.llvm_builder_ref().build_icmp_ult(lhs, rhs), - ">" => module.llvm_builder_ref().build_icmp_ugt(lhs, rhs), - "<=" => module.llvm_builder_ref().build_icmp_ule(lhs, rhs), - ">=" => module.llvm_builder_ref().build_icmp_uge(lhs, rhs), + "<" => module.llvm_builder.build_icmp_ult(lhs, rhs), + ">" => module.llvm_builder.build_icmp_ugt(lhs, rhs), + "<=" => module.llvm_builder.build_icmp_ule(lhs, rhs), + ">=" => module.llvm_builder.build_icmp_uge(lhs, rhs), _ => panic!("ICE codegen_compare_unsigned unhandled op {}", op), }, PrimitiveType::Bool, diff --git a/comp-be/src/codegen/expr/const_expr.rs b/comp-be/src/codegen/expr/const_expr.rs index 613db08..3c99648 100644 --- a/comp-be/src/codegen/expr/const_expr.rs +++ b/comp-be/src/codegen/expr/const_expr.rs @@ -1,7 +1,7 @@ use crate::{ codegen::{ builder::value, - unit::{Mutability, Slot}, + unit::{ModuleContext, Mutability, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -9,40 +9,40 @@ use crate::{ }; use parser::ast::{AtomKind, Expression, PrimitiveType, AST}; -pub fn const_atom(module: &AatbeModule, atom: &AtomKind) -> Option { +pub fn const_atom(ctx: &ModuleContext, atom: &AtomKind) -> Option { match atom { - AtomKind::StringLiteral(string) => Some(value::str(module, string.as_ref())), - AtomKind::CharLiteral(ch) => Some(value::char(module, *ch)), + AtomKind::StringLiteral(string) => Some(value::str(ctx, string.as_ref())), + AtomKind::CharLiteral(ch) => Some(value::char(ctx, *ch)), AtomKind::Integer(val, PrimitiveType::Int(size)) => { - Some(value::sint(module, size.clone(), *val)) + Some(value::sint(ctx, size.clone(), *val)) } AtomKind::Integer(val, PrimitiveType::UInt(size)) => { - Some(value::uint(module, size.clone(), *val)) + Some(value::uint(ctx, size.clone(), *val)) } AtomKind::Floating(val, PrimitiveType::Float(size)) => { - Some(value::floating(module, size.clone(), *val)) + Some(value::floating(ctx, size.clone(), *val)) } AtomKind::Cast(box AtomKind::Integer(val, _), PrimitiveType::Char) => { - Some(value::char(module, *val as u8 as char)) + Some(value::char(ctx, *val as u8 as char)) } AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::Int(size))) if op == &String::from("-") => { - Some(value::sint(module, size.clone(), (-(*val as i64)) as u64)) + Some(value::sint(ctx, size.clone(), (-(*val as i64)) as u64)) } AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::UInt(size))) if op == &String::from("-") => { - Some(value::uint(module, size.clone(), (-(*val as i64)) as u64)) + Some(value::uint(ctx, size.clone(), (-(*val as i64)) as u64)) } - AtomKind::Parenthesized(box atom) => fold_expression(module, atom), + AtomKind::Parenthesized(box atom) => fold_expression(ctx, atom), _ => panic!("ICE fold_atom {:?}", atom), } } -fn fold_expression(module: &AatbeModule, expr: &Expression) -> Option { +fn fold_expression(ctx: &ModuleContext, expr: &Expression) -> Option { match expr { - Expression::Atom(atom) => const_atom(module, atom), + Expression::Atom(atom) => const_atom(ctx, atom), _ => panic!("ICE fold_expression {:?}", expr), } } diff --git a/comp-be/src/codegen/expr/eqne.rs b/comp-be/src/codegen/expr/eqne.rs index e16668e..37617ff 100644 --- a/comp-be/src/codegen/expr/eqne.rs +++ b/comp-be/src/codegen/expr/eqne.rs @@ -1,18 +1,18 @@ -use crate::codegen::{AatbeModule, ValueTypePair}; +use crate::codegen::{unit::ModuleContext, ValueTypePair}; use parser::ast::PrimitiveType; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_eq_ne( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "==" => module.llvm_builder_ref().build_icmp_eq(lhs, rhs), - "!=" => module.llvm_builder_ref().build_icmp_ne(lhs, rhs), + "==" => ctx.llvm_builder.build_icmp_eq(lhs, rhs), + "!=" => ctx.llvm_builder.build_icmp_ne(lhs, rhs), _ => panic!("ICE codegen_eq_ne unhandled op {}", op), }, PrimitiveType::Bool, @@ -21,15 +21,15 @@ pub fn codegen_eq_ne( } pub fn codegen_boolean( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "&&" => module.llvm_builder_ref().build_and(lhs, rhs), - "||" => module.llvm_builder_ref().build_or(lhs, rhs), + "&&" => ctx.llvm_builder.build_and(lhs, rhs), + "||" => ctx.llvm_builder.build_or(lhs, rhs), _ => panic!("ICE codegen_eq_ne unhandled op {}", op), }, PrimitiveType::Bool, @@ -38,15 +38,15 @@ pub fn codegen_boolean( } pub fn codegen_eq_ne_float( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> ValueTypePair { ( match op.as_str() { - "==" => module.llvm_builder_ref().build_fcmp_ueq(lhs, rhs), - "!=" => module.llvm_builder_ref().build_fcmp_une(lhs, rhs), + "==" => ctx.llvm_builder.build_fcmp_ueq(lhs, rhs), + "!=" => ctx.llvm_builder.build_fcmp_une(lhs, rhs), _ => panic!("ICE codegen_eq_ne_float unhandled op {}", op), }, PrimitiveType::Bool, diff --git a/comp-be/src/codegen/expr/math.rs b/comp-be/src/codegen/expr/math.rs index e8ab19d..4ebfcf5 100644 --- a/comp-be/src/codegen/expr/math.rs +++ b/comp-be/src/codegen/expr/math.rs @@ -1,10 +1,10 @@ -use crate::codegen::{AatbeModule, ValueTypePair}; +use crate::codegen::{unit::ModuleContext, ValueTypePair}; use parser::ast::{FloatSize, IntSize, PrimitiveType}; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_float_ops( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -12,11 +12,11 @@ pub fn codegen_float_ops( ) -> ValueTypePair { ( match op.as_str() { - "+" => module.llvm_builder_ref().build_fadd(lhs, rhs), - "-" => module.llvm_builder_ref().build_fsub(lhs, rhs), - "*" => module.llvm_builder_ref().build_fmul(lhs, rhs), - "/" => module.llvm_builder_ref().build_fdiv(lhs, rhs), - "%" => module.llvm_builder_ref().build_frem(lhs, rhs), + "+" => ctx.llvm_builder.build_fadd(lhs, rhs), + "-" => ctx.llvm_builder.build_fsub(lhs, rhs), + "*" => ctx.llvm_builder.build_fmul(lhs, rhs), + "/" => ctx.llvm_builder.build_fdiv(lhs, rhs), + "%" => ctx.llvm_builder.build_frem(lhs, rhs), _ => panic!("ICE codegen_float_ops unhandled op {}", op), }, PrimitiveType::Float(float_size), @@ -25,7 +25,7 @@ pub fn codegen_float_ops( } pub fn codegen_signed_ops( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -33,11 +33,11 @@ pub fn codegen_signed_ops( ) -> ValueTypePair { ( match op.as_str() { - "+" => module.llvm_builder_ref().build_add(lhs, rhs), - "-" => module.llvm_builder_ref().build_sub(lhs, rhs), - "*" => module.llvm_builder_ref().build_mul(lhs, rhs), - "/" => module.llvm_builder_ref().build_sdiv(lhs, rhs), - "%" => module.llvm_builder_ref().build_srem(lhs, rhs), + "+" => ctx.llvm_builder.build_add(lhs, rhs), + "-" => ctx.llvm_builder.build_sub(lhs, rhs), + "*" => ctx.llvm_builder.build_mul(lhs, rhs), + "/" => ctx.llvm_builder.build_sdiv(lhs, rhs), + "%" => ctx.llvm_builder.build_srem(lhs, rhs), _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), }, PrimitiveType::Int(int_size), @@ -46,7 +46,7 @@ pub fn codegen_signed_ops( } pub fn codegen_unsigned_ops( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -54,11 +54,11 @@ pub fn codegen_unsigned_ops( ) -> ValueTypePair { ( match op.as_str() { - "+" => module.llvm_builder_ref().build_add(lhs, rhs), - "-" => module.llvm_builder_ref().build_sub(lhs, rhs), - "*" => module.llvm_builder_ref().build_mul(lhs, rhs), - "/" => module.llvm_builder_ref().build_udiv(lhs, rhs), - "%" => module.llvm_builder_ref().build_urem(lhs, rhs), + "+" => ctx.llvm_builder.build_add(lhs, rhs), + "-" => ctx.llvm_builder.build_sub(lhs, rhs), + "*" => ctx.llvm_builder.build_mul(lhs, rhs), + "/" => ctx.llvm_builder.build_udiv(lhs, rhs), + "%" => ctx.llvm_builder.build_urem(lhs, rhs), _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), }, int_size, diff --git a/comp-be/src/codegen/expr/mod.rs b/comp-be/src/codegen/expr/mod.rs index 7e672b2..e8b9f9f 100644 --- a/comp-be/src/codegen/expr/mod.rs +++ b/comp-be/src/codegen/expr/mod.rs @@ -10,7 +10,7 @@ use math::{codegen_float_ops, codegen_signed_ops, codegen_unsigned_ops}; pub mod const_expr; use crate::{ - codegen::{AatbeModule, CompileError, GenRes, ValueTypePair}, + codegen::{unit::ModuleContext, CompileError, GenRes, ValueTypePair}, fmt::AatbeFmt, }; use parser::ast::{Expression, FloatSize, IntSize, PrimitiveType}; @@ -18,74 +18,75 @@ use parser::ast::{Expression, FloatSize, IntSize, PrimitiveType}; use llvm_sys_wrapper::LLVMValueRef; fn dispatch_bool( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, ) -> Option { match op.as_str() { - "==" | "!=" => Some(codegen_eq_ne(module, op, lhs, rhs)), - "&&" | "||" => Some(codegen_boolean(module, op, lhs, rhs)), + "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), + "&&" | "||" => Some(codegen_boolean(ctx, op, lhs, rhs)), _ => None, } } fn dispatch_signed( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, int_size: IntSize, ) -> Option { match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_signed_ops(module, op, lhs, rhs, int_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_signed(module, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne(module, op, lhs, rhs)), + "+" | "-" | "*" | "/" | "%" => Some(codegen_signed_ops(ctx, op, lhs, rhs, int_size)), + ">" | "<" | ">=" | "<=" => Some(codegen_compare_signed(ctx, op, lhs, rhs)), + "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), _ => None, } } fn dispatch_float( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, float_size: FloatSize, ) -> Option { match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_float_ops(module, op, lhs, rhs, float_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_float(module, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne_float(module, op, lhs, rhs)), + "+" | "-" | "*" | "/" | "%" => Some(codegen_float_ops(ctx, op, lhs, rhs, float_size)), + ">" | "<" | ">=" | "<=" => Some(codegen_compare_float(ctx, op, lhs, rhs)), + "==" | "!=" => Some(codegen_eq_ne_float(ctx, op, lhs, rhs)), _ => None, } } fn dispatch_unsigned( - module: &AatbeModule, + ctx: &ModuleContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, int_size: PrimitiveType, ) -> Option { match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_unsigned_ops(module, op, lhs, rhs, int_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_unsigned(module, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne(module, op, lhs, rhs)), + "+" | "-" | "*" | "/" | "%" => Some(codegen_unsigned_ops(ctx, op, lhs, rhs, int_size)), + ">" | "<" | ">=" | "<=" => Some(codegen_compare_unsigned(ctx, op, lhs, rhs)), + "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), _ => None, } } pub fn codegen_binary( - module: &mut AatbeModule, + module: &mut ModuleContext, op: &String, lhs_expr: &Expression, rhs_expr: &Expression, ) -> GenRes { - let lhs = module.codegen_expr(lhs_expr).ok_or(CompileError::Handled)?; + todo!() + /*let lhs = module.codegen_expr(lhs_expr).ok_or(CompileError::Handled)?; let rhs = module.codegen_expr(rhs_expr).ok_or(CompileError::Handled)?; match (lhs.prim(), rhs.prim()) { - (PrimitiveType::Bool, PrimitiveType::Bool) => match dispatch_bool(module, op, *lhs, *rhs) { + (PrimitiveType::Bool, PrimitiveType::Bool) => match dispatch_bool(ctx, op, *lhs, *rhs) { Some(res) => Ok(res), None => Err(CompileError::OpMismatch { op: op.clone(), @@ -94,7 +95,7 @@ pub fn codegen_binary( }), }, (PrimitiveType::Char, PrimitiveType::Char) => { - match dispatch_unsigned(module, op, *lhs, *rhs, PrimitiveType::Char) { + match dispatch_unsigned(ctx, op, *lhs, *rhs, PrimitiveType::Char) { Some(res) => Ok(res), None => Err(CompileError::OpMismatch { op: op.clone(), @@ -104,7 +105,7 @@ pub fn codegen_binary( } } (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { - match dispatch_unsigned(module, op, *lhs, *rhs, PrimitiveType::UInt(lsz.clone())) { + match dispatch_unsigned(ctx, op, *lhs, *rhs, PrimitiveType::UInt(lsz.clone())) { Some(res) => Ok(res), None => Err(CompileError::OpMismatch { op: op.clone(), @@ -114,7 +115,7 @@ pub fn codegen_binary( } } (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { - match dispatch_signed(module, op, *lhs, *rhs, lsz.clone()) { + match dispatch_signed(ctx, op, *lhs, *rhs, lsz.clone()) { Some(res) => Ok(res), None => Err(CompileError::OpMismatch { op: op.clone(), @@ -124,7 +125,7 @@ pub fn codegen_binary( } } (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { - match dispatch_float(module, op, *lhs, *rhs, lsz.clone()) { + match dispatch_float(ctx, op, *lhs, *rhs, lsz.clone()) { Some(res) => Ok(res), None => Err(CompileError::OpMismatch { op: op.clone(), @@ -138,5 +139,5 @@ pub fn codegen_binary( types: (lhs.prim().fmt(), rhs.prim().fmt()), values: (lhs_expr.fmt(), rhs_expr.fmt()), }), - } + }*/ } diff --git a/comp-be/src/codegen/mod.rs b/comp-be/src/codegen/mod.rs index ce59a2c..d511459 100644 --- a/comp-be/src/codegen/mod.rs +++ b/comp-be/src/codegen/mod.rs @@ -141,7 +141,8 @@ impl ValueTypePair { } pub fn indexable(&self, module: &AatbeModule) -> Option { - match &self { + todo!() + /*match &self { ValueTypePair(val, TypeKind::Primitive(prim)) => match prim { prim @ (PrimitiveType::Str | PrimitiveType::Array { .. }) => { Some((*val, prim).into()) @@ -153,7 +154,7 @@ impl ValueTypePair { _ => None, }, _ => None, - } + }*/ } } diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index f875c16..4f875c1 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -44,7 +44,6 @@ pub struct AatbeModule { llvm_context: Context, llvm_module: Module, name: String, - scope_stack: Vec, compile_errors: Vec, record_templates: HashMap, function_templates: HashMap, @@ -73,7 +72,6 @@ impl AatbeModule { llvm_context, llvm_module, name, - scope_stack: vec![], compile_errors: vec![], record_templates: HashMap::new(), function_templates: HashMap::new(), @@ -85,10 +83,6 @@ impl AatbeModule { pub fn compile(&mut self) { let base_cu = self.compilation_units.get(&self.name).unwrap(); - self.scope_stack.push(Scope::with_builder_and_fdir( - Builder::new_in_context(self.llvm_context.as_ref()), - base_cu.path().clone(), - )); let main_ast = self .compilation_units .get(&self.name.clone()) @@ -96,20 +90,21 @@ impl AatbeModule { .ast() .clone(); - let mut root_module = ModuleUnit::new( + ModuleUnit::new( + base_cu.path().clone(), box main_ast, &self.llvm_context, &self.llvm_module, - &self.llvm_builder_ref(), - ); - - root_module.decl(); - root_module.codegen(); + ) + .in_root_scope(|root_module| { + root_module.decl(); + root_module.codegen(); + }); //self.exit_scope(); } - pub fn parse_import(&mut self, module: &String) -> io::Result { + /*pub fn parse_import(&mut self, module: &String) -> io::Result { let mut path = self.fdir().with_file_name(module); path.set_extension("aat"); if !path.exists() { @@ -122,7 +117,7 @@ impl AatbeModule { } CompilationUnit::new(path) - } + }*/ pub fn decl_pass(&mut self, root_module: &mut ModuleUnit) { @@ -383,7 +378,7 @@ impl AatbeModule { }*/ } - pub fn get_interior_pointer(&self, parts: Vec) -> Option { + /*pub fn get_interior_pointer(&self, parts: Vec) -> Option { match parts.as_slice() { [field, access @ ..] => { let agg_bind = self.get_var(&field)?; @@ -399,7 +394,7 @@ impl AatbeModule { } [] => unreachable!(), } - } + }*/ pub fn has_ret(&self, expr: &Expression) -> bool { match expr { @@ -636,7 +631,7 @@ impl AatbeModule { }*/ } - pub fn start_scope(&mut self) { + /*pub fn start_scope(&mut self) { self.scope_stack.push(Scope::new()); } @@ -727,7 +722,7 @@ impl AatbeModule { } None - } + }*/ pub fn propagate_generic_body( body: Box, @@ -797,7 +792,7 @@ impl AatbeModule { }) }*/ - pub fn is_extern(&self, func: (String, FunctionType)) -> bool { + /*pub fn is_extern(&self, func: (String, FunctionType)) -> bool { let val_ref = self.get_func(func); if let Some(func) = val_ref { func.is_extern() @@ -818,7 +813,7 @@ impl AatbeModule { Some(Slot::FunctionArgument(_arg, _)) => val_ref, _ => None, } - } + }*/ /*pub fn propagate_types_in_function( &mut self, @@ -983,7 +978,7 @@ impl AatbeModule { }*/ } - pub fn fdir(&self) -> PathBuf { + /*pub fn fdir(&self) -> PathBuf { for scope in self.scope_stack.iter().rev() { if let Some(fdir) = scope.fdir() { return fdir.clone(); @@ -992,14 +987,7 @@ impl AatbeModule { unreachable!(); } - pub fn llvm_builder_ref(&self) -> &Builder { - for scope in self.scope_stack.iter().rev() { - if let Some(builder) = scope.builder() { - return builder; - } - } - unreachable!(); - } + */ pub fn llvm_module_ref(&self) -> &Module { todo!() //&self.llvm_module diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 7b9a6d2..4a9bf77 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -5,7 +5,7 @@ use crate::codegen::{ }, AatbeModule, }; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, path::PathBuf, rc::Rc}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; use parser::ast::FunctionType; @@ -16,7 +16,7 @@ pub struct Scope { functions: FunctionMap, name: String, function: Option<(String, FunctionType)>, - builder: Option, + builder: Option>, fdir: Option, } @@ -47,18 +47,21 @@ impl Scope { functions: HashMap::new(), name: String::default(), function: None, - builder: Some(builder), + builder: Some(Rc::new(builder)), fdir: None, } } - pub fn with_builder_and_fdir(builder: Builder, fdir: PathBuf) -> Self { + pub fn with_builder_and_fdir

(builder: Builder, fdir: P) -> Self + where + P: Into, + { Self { refs: HashMap::new(), functions: HashMap::new(), name: String::default(), function: None, - builder: Some(builder), - fdir: Some(fdir), + builder: Some(Rc::new(builder)), + fdir: Some(fdir.into()), } } pub fn with_function(func: (String, FunctionType), builder: Builder) -> Self { @@ -67,7 +70,7 @@ impl Scope { functions: HashMap::new(), name: func.0.clone(), function: Some(func), - builder: Some(builder), + builder: Some(Rc::new(builder)), fdir: None, } } @@ -93,14 +96,14 @@ impl Scope { pub fn function(&self) -> Option<(String, FunctionType)> { self.function.clone() } - pub fn builder(&self) -> Option<&Builder> { - self.builder.as_ref() + pub fn builder(&self) -> Option> { + self.builder.clone() } pub fn fdir(&self) -> Option { self.fdir.clone() } - pub fn bb(&self, module: &AatbeModule, name: &String) -> Option { + /*pub fn bb(&self, module: &AatbeModule, name: &String) -> Option { let func = self.function.as_ref()?; Some( @@ -108,7 +111,7 @@ impl Scope { .unwrap() .append_basic_block(name.as_ref()), ) - } + }*/ } /* TODO: Implement local dropping diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 35fc11e..31d9aa8 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,7 +3,7 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{FuncType, Mutability, Slot}, + unit::{FuncType, ModuleCommand, Mutability, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -135,9 +135,17 @@ pub fn declare_function(ctx: &mut ModuleContext, function: &Expression) { let func = Func::new(ty.clone(), name.clone(), func); if !export { - (ctx.register_function)(&name, func, FuncType::Local); + (ctx.dispatch)(ModuleCommand::RegisterFunction( + &name, + func, + FuncType::Local, + )); } else { - (ctx.register_function)(&name, func, FuncType::Export); + (ctx.dispatch)(ModuleCommand::RegisterFunction( + &name, + func, + FuncType::Export, + )); } } _ => unimplemented!("{:?}", function), diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 5ef73e6..eb38335 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -12,7 +12,7 @@ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; pub mod module; -pub use module::{FuncType, ModuleContext, ModuleUnit}; +pub use module::{FuncType, ModuleCommand, ModuleContext, ModuleUnit}; pub mod decl; pub use decl::decl; diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index 7ae1585..754d53b 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -1,5 +1,6 @@ use std::{ collections::HashMap, + path::PathBuf, rc::{Rc, Weak}, }; @@ -7,7 +8,10 @@ use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; use parser::ast::{Expression, AST}; use crate::{ - codegen::unit::{comp, decl}, + codegen::{ + unit::{comp, decl}, + Scope, + }, ty::TypeContext, }; @@ -18,12 +22,16 @@ pub enum FuncType { Export, } +pub enum ModuleCommand<'cmd> { + RegisterFunction(&'cmd String, Func, FuncType), +} + pub struct ModuleContext<'ctx> { pub llvm_context: &'ctx Context, pub llvm_module: &'ctx Module, pub llvm_builder: &'ctx Builder, pub function_templates: HashMap, - pub register_function: &'ctx mut dyn FnMut(&String, Func, FuncType) -> (), + pub dispatch: &'ctx mut dyn FnMut(ModuleCommand) -> (), } impl<'ctx> ModuleContext<'ctx> { @@ -31,14 +39,14 @@ impl<'ctx> ModuleContext<'ctx> { llvm_context: &'ctx Context, llvm_module: &'ctx Module, llvm_builder: &'ctx Builder, - register_function: &'ctx mut dyn FnMut(&String, Func, FuncType) -> (), + dispatch: &'ctx mut dyn FnMut(ModuleCommand) -> (), ) -> Self { Self { llvm_context, llvm_module, llvm_builder, + dispatch, function_templates: HashMap::new(), - register_function, } } } @@ -49,27 +57,52 @@ pub struct ModuleUnit<'ctx> { typectx: TypeContext, llvm_context: &'ctx Context, llvm_module: &'ctx Module, - llvm_builder: &'ctx Builder, + scope_stack: Vec, + path: PathBuf, } impl<'ctx> ModuleUnit<'ctx> { - pub fn new( + pub fn new

( + path: P, ast: Box, llvm_context: &'ctx Context, llvm_module: &'ctx Module, - llvm_builder: &'ctx Builder, - ) -> Self { + ) -> Self + where + P: Into, + { Self { - modules: HashMap::new(), + path: path.into(), ast, - typectx: TypeContext::new(), llvm_context, llvm_module, - llvm_builder, + modules: HashMap::new(), + typectx: TypeContext::new(), + scope_stack: vec![], } } - fn register_function(&mut self, name: &String, func: Func, func_type: FuncType) {} + pub fn in_root_scope(&mut self, mut f: F) + where + F: FnMut(&mut Self), + { + self.enter_root_scope(); + f(self); + self.exit_scope(); + } + + fn enter_root_scope(&mut self) { + self.scope_stack.push(Scope::with_builder_and_fdir( + Builder::new_in_context(self.llvm_context.as_ref()), + self.path.clone(), + )); + } + + fn exit_scope(&mut self) { + self.scope_stack.pop(); + } + + fn dispatch(&mut self, command: ModuleCommand) {} pub fn push(&mut self, name: &String, module: ModuleUnit<'ctx>) -> Option> { self.modules.insert(name.clone(), module) @@ -83,12 +116,9 @@ impl<'ctx> ModuleUnit<'ctx> { let ast = self.ast.clone(); let llvm_context = self.llvm_context; let llvm_module = self.llvm_module; - let llvm_builder = self.llvm_builder; - let register_function = &mut |name: &String, func: Func, func_type: FuncType| { - self.register_function(name, func, func_type) - }; - let mut ctx = - ModuleContext::new(llvm_context, llvm_module, llvm_builder, register_function); + let llvm_builder = self.llvm_builder_ref(); + let dispatch = &mut |command: ModuleCommand| self.dispatch(command); + let mut ctx = ModuleContext::new(llvm_context, llvm_module, &*llvm_builder, dispatch); match ast { box AST::File(ref nodes) => nodes .iter() @@ -102,15 +132,21 @@ impl<'ctx> ModuleUnit<'ctx> { let ast = self.ast.clone(); let llvm_context = self.llvm_context; let llvm_module = self.llvm_module; - let llvm_builder = self.llvm_builder; - let register_function = &mut |name: &String, func: Func, func_type: FuncType| { - self.register_function(name, func, func_type) - }; - let mut ctx = - ModuleContext::new(llvm_context, llvm_module, llvm_builder, register_function); + let llvm_builder = self.llvm_builder_ref(); + let dispatch = &mut |command: ModuleCommand| self.dispatch(command); + let mut ctx = ModuleContext::new(llvm_context, llvm_module, &*llvm_builder, dispatch); match ast { box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| comp(n)), _ => todo!("{:?}", self.ast), } } + + pub fn llvm_builder_ref(&self) -> Rc { + for scope in self.scope_stack.iter().rev() { + if let Some(builder) = scope.builder() { + return builder; + } + } + unreachable!(); + } } diff --git a/comp-be/src/codegen/unit/variable.rs b/comp-be/src/codegen/unit/variable.rs index f58d7ed..d3da812 100644 --- a/comp-be/src/codegen/unit/variable.rs +++ b/comp-be/src/codegen/unit/variable.rs @@ -105,7 +105,9 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option return Some(ty.clone()); }*/ - if value.is_none() { + todo!(); + + /*if value.is_none() { let ty = ty.as_ref().expect("ICE: Ty none for none value"); let val_ref = module.llvm_builder_ref().build_alloca_with_name( todo!(), /*ty.llvm_ty_in_ctx(module)*/ @@ -123,7 +125,7 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option ); return Some(*ty.clone()); - } + }*/ // TODO: Variants, generic records let ty = infer_type( @@ -135,11 +137,13 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option panic!("ICE: ty is none {:?} value", value); } let (ty, constant) = ty.unwrap(); - + /* let var_ref = module .llvm_builder_ref() - .build_alloca_with_name(todo!() /*ty.llvm_ty_in_ctx(module)*/, name.as_ref()); + .build_alloca_with_name(todo!() /*ty.llvm_ty_in_ctx(module)*/, name.as_ref());*/ + todo!(); + /* module.push_in_scope( name, Slot::Variable { @@ -149,8 +153,10 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option value: var_ref, }, ); + */ - if let Some(e) = value { + todo!() + /*if let Some(e) = value { if let box Expression::RecordInit { record, types, @@ -225,8 +231,8 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option } }; } - } - Some(ty.clone()) + }*/ + //Some(ty.clone()) } _ => unreachable!(), } @@ -336,7 +342,8 @@ pub fn store_value( value: &Expression, ) -> Option { fn get_lval(module: &mut AatbeModule, lvalue: &LValue) -> Option { - match lvalue { + todo!() + /*match lvalue { LValue::Ident(name) => match module.get_var(name) { None => panic!("Cannot find variable {}", name), Some(var) => { @@ -392,10 +399,11 @@ pub fn store_value( None } } - } + }*/ } - get_lval(module, lval).and_then(|var| { + todo!() + /*get_lval(module, lval).and_then(|var| { let val = module.codegen_expr(value)?; if var.prim() != val.prim().inner() { module.add_error(CompileError::AssignMismatch { @@ -409,5 +417,5 @@ pub fn store_value( } else { Some((module.llvm_builder_ref().build_store(*val, *var), var.ty()).into()) } - }) + })*/ } diff --git a/comp-be/src/ty/infer.rs b/comp-be/src/ty/infer.rs index 83eff39..29800ef 100644 --- a/comp-be/src/ty/infer.rs +++ b/comp-be/src/ty/infer.rs @@ -5,7 +5,7 @@ use crate::codegen::{unit::function::find_function, AatbeModule}; pub fn infer_type(module: &AatbeModule, expr: &Expression) -> Option<(PrimitiveType, bool)> { match expr { Expression::Atom(atom) => infer_atom(module, &atom), - Expression::Call { + /*Expression::Call { name, args: call_args, .. @@ -24,7 +24,7 @@ pub fn infer_type(module: &AatbeModule, expr: &Expression) -> Option<(PrimitiveT let func = find_function(group, &args)?; return Some((func.ret_ty().clone(), false)); - } + }*/ Expression::RecordInit { record, types, .. } if types.len() == 0 => { Some((PrimitiveType::TypeRef(record.clone()), true)) } @@ -60,11 +60,11 @@ pub fn infer_atom(module: &AatbeModule, atom: &AtomKind) -> Option<(PrimitiveTyp None } } - AtomKind::Ident(name) => { + /*AtomKind::Ident(name) => { let var = module.get_var(name)?; Some((var.var_ty().clone(), false)) - } + }*/ AtomKind::Cast(_, ty) => Some((ty.clone(), false)), AtomKind::Parenthesized(box expr) => infer_type(module, expr), _ => unimplemented!("{:?}", atom), From 3f52145542019503a01e64bc1611689fb2f5cbc7 Mon Sep 17 00:00:00 2001 From: chronium Date: Thu, 4 Mar 2021 20:56:33 +0200 Subject: [PATCH 04/18] The One With Modules IV Function declaration has `some` output --- comp-be/src/codegen/module.rs | 16 ++-------------- comp-be/src/codegen/unit/comp/mod.rs | 3 ++- comp-be/src/codegen/unit/module.rs | 19 ++++++++++++++++++- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 4f875c1..513db8f 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -69,8 +69,8 @@ impl AatbeModule { compilation_units.insert(name.clone(), base_cu); Self { - llvm_context, llvm_module, + llvm_context, name, compile_errors: vec![], record_templates: HashMap::new(), @@ -683,19 +683,7 @@ impl AatbeModule { .add_symbol(name, unit); } - pub fn add_function(&mut self, name: &String, func: Func) { - self.scope_stack - .last_mut() - .expect("Compiler broke. Scope stack is corrupted.") - .add_function(name, func); - } - pub fn export_function(&mut self, name: &String, func: Func) { - self.scope_stack - .first_mut() - .expect("Compiler broke. Scope stack is corrupted.") - .add_function(name, func); - } pub fn export_global(&mut self, name: &String, unit: Slot) { self.scope_stack @@ -990,7 +978,7 @@ impl AatbeModule { */ pub fn llvm_module_ref(&self) -> &Module { - todo!() //&self.llvm_module + &self.llvm_module } pub fn llvm_context_ref(&self) -> &Context { diff --git a/comp-be/src/codegen/unit/comp/mod.rs b/comp-be/src/codegen/unit/comp/mod.rs index 23504da..5dc36a2 100644 --- a/comp-be/src/codegen/unit/comp/mod.rs +++ b/comp-be/src/codegen/unit/comp/mod.rs @@ -2,5 +2,6 @@ use llvm_sys_wrapper::LLVMValueRef; use parser::ast::AST; pub fn comp(ast: &AST) -> Option { - todo!("{:?}", ast) + //todo!("{:?}", ast) + None } diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index 754d53b..a4f1e39 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -17,6 +17,7 @@ use crate::{ use super::function::Func; +#[derive(Copy, Clone, PartialEq, Eq)] pub enum FuncType { Local, Export, @@ -102,7 +103,19 @@ impl<'ctx> ModuleUnit<'ctx> { self.scope_stack.pop(); } - fn dispatch(&mut self, command: ModuleCommand) {} + fn dispatch(&mut self, command: ModuleCommand) { + match command { + ModuleCommand::RegisterFunction(name, func, ty) => { + if ty == FuncType::Local { + self.scope_stack.last_mut() + } else { + self.scope_stack.first_mut() + } + .expect("ICE: Scope stack is corrupted.") + .add_function(name, func); + } + } + } pub fn push(&mut self, name: &String, module: ModuleUnit<'ctx>) -> Option> { self.modules.insert(name.clone(), module) @@ -149,4 +162,8 @@ impl<'ctx> ModuleUnit<'ctx> { } unreachable!(); } + + pub fn llvm_module_ref(&self) -> &Module { + &self.llvm_module + } } From ed63b19b0b3eae29173954308a575af79bbdd6d3 Mon Sep 17 00:00:00 2001 From: chronium Date: Fri, 5 Mar 2021 19:09:54 +0200 Subject: [PATCH 05/18] The One With Modules V --- comp-be/src/codegen/module.rs | 28 +---- comp-be/src/codegen/scope.rs | 13 +-- comp-be/src/codegen/unit/cg/expr.rs | 20 ++++ comp-be/src/codegen/unit/cg/mod.rs | 13 +++ comp-be/src/codegen/unit/comp/mod.rs | 7 -- comp-be/src/codegen/unit/function.rs | 91 ++++++++------- comp-be/src/codegen/unit/mod.rs | 6 +- comp-be/src/codegen/unit/module.rs | 169 ++++++++++++++++++++------- 8 files changed, 221 insertions(+), 126 deletions(-) create mode 100644 comp-be/src/codegen/unit/cg/expr.rs create mode 100644 comp-be/src/codegen/unit/cg/mod.rs delete mode 100644 comp-be/src/codegen/unit/comp/mod.rs diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 513db8f..89190ce 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -63,8 +63,6 @@ impl AatbeModule { internal_functions.insert(String::from("len"), Rc::new(AatbeModule::internal_len)); internal_functions.insert(String::from("box"), Rc::new(AatbeModule::internal_box)); - let ast = box base_cu.ast().clone(); - let mut compilation_units = HashMap::new(); compilation_units.insert(name.clone(), base_cu); @@ -90,6 +88,8 @@ impl AatbeModule { .ast() .clone(); + let root_builder = Builder::new_in_context(self.llvm_context.as_ref()); + ModuleUnit::new( base_cu.path().clone(), box main_ast, @@ -97,11 +97,9 @@ impl AatbeModule { &self.llvm_module, ) .in_root_scope(|root_module| { - root_module.decl(); - root_module.codegen(); + root_module.decl(&root_builder); + root_module.codegen(&root_builder); }); - - //self.exit_scope(); } /*pub fn parse_import(&mut self, module: &String) -> io::Result { @@ -639,14 +637,6 @@ impl AatbeModule { self.scope_stack.push(Scope::with_name(name)); } - pub fn start_scope_with_function(&mut self, func: (String, FunctionType), builder: Builder) { - self.scope_stack.push(Scope::with_function(func, builder)); - } - - pub fn exit_scope(&mut self) { - self.scope_stack.pop(); - } - pub fn get_in_scope(&self, name: &String) -> Option<&Slot> { for scope in self.scope_stack.iter().rev() { if let Some(sym) = scope.find_symbol(name) { @@ -702,15 +692,7 @@ impl AatbeModule { None } - pub fn get_func(&self, func: (String, FunctionType)) -> Option<&Func> { - for scope in self.scope_stack.iter().rev() { - if let Some(group) = scope.func_by_name(&func.0) { - return find_func(group, &func.1); - } - } - - None - }*/ + */ pub fn propagate_generic_body( body: Box, diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 4a9bf77..340de95 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -16,7 +16,6 @@ pub struct Scope { functions: FunctionMap, name: String, function: Option<(String, FunctionType)>, - builder: Option>, fdir: Option, } @@ -27,7 +26,6 @@ impl Scope { functions: HashMap::new(), name: String::default(), function: None, - builder: None, fdir: None, } } @@ -37,7 +35,6 @@ impl Scope { functions: HashMap::new(), name: name.clone(), function: None, - builder: None, fdir: None, } } @@ -47,11 +44,10 @@ impl Scope { functions: HashMap::new(), name: String::default(), function: None, - builder: Some(Rc::new(builder)), fdir: None, } } - pub fn with_builder_and_fdir

(builder: Builder, fdir: P) -> Self + pub fn with_fdir

(fdir: P) -> Self where P: Into, { @@ -60,7 +56,6 @@ impl Scope { functions: HashMap::new(), name: String::default(), function: None, - builder: Some(Rc::new(builder)), fdir: Some(fdir.into()), } } @@ -70,7 +65,6 @@ impl Scope { functions: HashMap::new(), name: func.0.clone(), function: Some(func), - builder: Some(Rc::new(builder)), fdir: None, } } @@ -84,7 +78,7 @@ impl Scope { self.functions.insert(name.clone(), vec![]); } - self.functions.get_mut(name).unwrap().push(func); + self.functions.get_mut(name).unwrap().push(Rc::new(func)); } pub fn find_symbol(&self, name: &String) -> Option<&Slot> { @@ -96,9 +90,6 @@ impl Scope { pub fn function(&self) -> Option<(String, FunctionType)> { self.function.clone() } - pub fn builder(&self) -> Option> { - self.builder.clone() - } pub fn fdir(&self) -> Option { self.fdir.clone() } diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs new file mode 100644 index 0000000..14ba658 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -0,0 +1,20 @@ +use parser::ast::{Expression, FunctionType}; + +use crate::codegen::{ + unit::{declare_and_compile_function, ModuleContext}, + ValueTypePair, +}; + +pub fn cg(expr: &Expression, ctx: ModuleContext) -> Option { + match expr { + Expression::Function { ty, type_names, .. } if type_names.len() == 0 => match ty { + FunctionType { + ret_ty: _, + params: _, + ext: true, + } => None, + _ => declare_and_compile_function(ctx, expr), + }, + _ => todo!("{:?}", expr), + } +} diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs new file mode 100644 index 0000000..5b15a58 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -0,0 +1,13 @@ +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::AST; + +use super::ModuleContext; + +mod expr; + +pub fn cg(ast: &AST, ctx: ModuleContext) -> Option { + match ast { + AST::Expr(expr) => expr::cg(expr, ctx).map(|e| *e), + _ => todo!("{:?}", ast), + } +} diff --git a/comp-be/src/codegen/unit/comp/mod.rs b/comp-be/src/codegen/unit/comp/mod.rs deleted file mode 100644 index 5dc36a2..0000000 --- a/comp-be/src/codegen/unit/comp/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::AST; - -pub fn comp(ast: &AST) -> Option { - //todo!("{:?}", ast) - None -} diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 31d9aa8..4d91e87 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,15 +3,19 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{FuncType, ModuleCommand, Mutability, Slot}, + unit::{FuncType, Message, Mutability, Query, QueryResponse, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, ty::LLVMTyInCtx, }; use llvm_sys_wrapper::Function; -use std::collections::HashMap; -use std::ops::Deref; +use std::{ + borrow::Borrow, + collections::HashMap, + ops::Deref, + rc::{Rc, Weak}, +}; use parser::ast::{Expression, FunctionType, PrimitiveType}; @@ -41,13 +45,13 @@ impl AatbeFmt for &Func { } } -pub type FuncTyMap = Vec; +pub type FuncTyMap = Vec>; pub type FunctionMap = HashMap; -pub fn find_func<'a>(map: &'a FuncTyMap, ty: &FunctionType) -> Option<&'a Func> { +pub fn find_func<'a>(map: &'a FuncTyMap, ty: &FunctionType) -> Option> { for func in map { if &func.ty == ty { - return Some(func); + return Some(Rc::downgrade(func)); } } return None; @@ -120,7 +124,7 @@ impl Func { } } -pub fn declare_function(ctx: &mut ModuleContext, function: &Expression) { +pub fn declare_function(ctx: &ModuleContext, function: &Expression) { match function { Expression::Function { ty, @@ -135,29 +139,21 @@ pub fn declare_function(ctx: &mut ModuleContext, function: &Expression) { let func = Func::new(ty.clone(), name.clone(), func); if !export { - (ctx.dispatch)(ModuleCommand::RegisterFunction( - &name, - func, - FuncType::Local, - )); + ctx.dispatch(Message::RegisterFunction(&name, func, FuncType::Local)); } else { - (ctx.dispatch)(ModuleCommand::RegisterFunction( - &name, - func, - FuncType::Export, - )); + ctx.dispatch(Message::RegisterFunction(&name, func, FuncType::Export)); } } _ => unimplemented!("{:?}", function), } } -pub fn declare_and_compile_function( - module: &mut AatbeModule, +pub fn declare_and_compile_function<'ctx>( + ctx: ModuleContext, func: &Expression, ) -> Option { - todo!() - /*match func { + //todo!("{:?}", func); + match func { Expression::Function { ty, body, name, .. } => match ty { FunctionType { ret_ty: _, @@ -165,9 +161,18 @@ pub fn declare_and_compile_function( ext: true, } => None, _ => { - let builder = Builder::new_in_context(module.llvm_context_ref().as_ref()); - module.start_scope_with_function((name.clone(), ty.clone()), builder); - codegen_function(module, func); + ctx.in_function_scope((name.clone(), ty.clone()), |ctx| { + codegen_function(&ctx, func); + + if !has_return_type(ty) { + core::ret_void(&ctx); + } else { + todo!(); + } + + None + }) + /* inject_function_in_scope(module, func); let ret_val = module.codegen_expr( &body @@ -187,7 +192,8 @@ pub fn declare_and_compile_function( let ret_ty = *ty.ret_ty.clone(); core::ret( module, - (cast::child_to_parent(module, val, parent_ty), ret_ty).into(), + (cast::child_to_parent(module, val, parent_ty), ret_ty) + .into(), ) } _ => core::ret(module, val), @@ -202,39 +208,40 @@ pub fn declare_and_compile_function( core::ret_void(module); } - module.exit_scope(); - - None + module.exit_scope();*/ } }, _ => unreachable!(), - }*/ + } } -pub fn codegen_function(module: &mut AatbeModule, function: &Expression) { - todo!() - /*match function { +pub fn codegen_function(ctx: &ModuleContext, function: &Expression) { + match function { Expression::Function { attributes, name, ty, .. } => { - let func = module.get_func((name.clone(), ty.clone())).unwrap(); + let func = ctx.query(Query::Function((name, ty))); - if !attributes.is_empty() { - for attr in attributes { - match attr.to_lowercase().as_ref() { - "entry" => core::pos_at_end(module, func.bb("entry".to_string())), - _ => panic!("Cannot decorate function with {}", name), - }; + if let QueryResponse::Function(Some(func)) = func { + let func = func.upgrade().expect("ICE"); + + if !attributes.is_empty() { + for attr in attributes { + match attr.to_lowercase().as_ref() { + "entry" => core::pos_at_end(ctx, func.bb("entry".to_string())), + _ => panic!("Cannot decorate function with {}", name), + }; + } + } else { + core::pos_at_end(ctx, func.bb(String::default())); } - } else { - core::pos_at_end(module, func.bb(String::default())); } } _ => unreachable!(), - }*/ + } } pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) { diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index eb38335..8d74379 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -12,13 +12,13 @@ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; pub mod module; -pub use module::{FuncType, ModuleCommand, ModuleContext, ModuleUnit}; +pub use module::{FuncType, Message, ModuleContext, ModuleUnit, Query, QueryResponse}; pub mod decl; pub use decl::decl; -pub mod comp; -pub use comp::comp; +pub mod cg; +pub use cg::cg; #[derive(Debug, Clone)] pub enum Mutability { diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index a4f1e39..e68affc 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -1,16 +1,18 @@ use std::{ + borrow::Borrow, + cell::RefCell, collections::HashMap, path::PathBuf, rc::{Rc, Weak}, }; use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; -use parser::ast::{Expression, AST}; +use parser::ast::{Expression, FunctionType, AST}; use crate::{ codegen::{ - unit::{comp, decl}, - Scope, + unit::{cg, decl, function::find_func}, + Scope, ValueTypePair, }, ty::TypeContext, }; @@ -23,8 +25,18 @@ pub enum FuncType { Export, } -pub enum ModuleCommand<'cmd> { +pub enum Message<'cmd> { RegisterFunction(&'cmd String, Func, FuncType), + EnterFunctionScope((String, FunctionType)), + ExitScope, +} + +pub enum Query<'cmd> { + Function((&'cmd String, &'cmd FunctionType)), +} + +pub enum QueryResponse { + Function(Option>), } pub struct ModuleContext<'ctx> { @@ -32,7 +44,30 @@ pub struct ModuleContext<'ctx> { pub llvm_module: &'ctx Module, pub llvm_builder: &'ctx Builder, pub function_templates: HashMap, - pub dispatch: &'ctx mut dyn FnMut(ModuleCommand) -> (), + dispatch: &'ctx dyn Fn(Message) -> (), + query: &'ctx dyn Fn(Query) -> QueryResponse, +} + +impl ModuleContext<'ctx> { + pub fn dispatch(&self, command: Message) { + (self.dispatch)(command) + } + + pub fn query(&self, query: Query) -> QueryResponse { + (self.query)(query) + } + + pub fn in_function_scope(&self, func: (String, FunctionType), f: F) -> Option + where + F: FnOnce(ModuleContext) -> Option, + { + self.dispatch(Message::EnterFunctionScope(func)); + let builder = Builder::new_in_context(self.llvm_context.as_ref()); + let ctx = self.with_builder(&builder); + let res = f(ctx); + self.dispatch(Message::ExitScope); + res + } } impl<'ctx> ModuleContext<'ctx> { @@ -40,13 +75,26 @@ impl<'ctx> ModuleContext<'ctx> { llvm_context: &'ctx Context, llvm_module: &'ctx Module, llvm_builder: &'ctx Builder, - dispatch: &'ctx mut dyn FnMut(ModuleCommand) -> (), + dispatch: &'ctx dyn Fn(Message) -> (), + query: &'ctx dyn Fn(Query) -> QueryResponse, ) -> Self { Self { llvm_context, llvm_module, llvm_builder, dispatch, + query, + function_templates: HashMap::new(), + } + } + + fn with_builder(&'ctx self, builder: &'ctx Builder) -> Self { + Self { + llvm_context: self.llvm_context, + llvm_module: self.llvm_module, + llvm_builder: builder, + dispatch: self.dispatch, + query: self.query, function_templates: HashMap::new(), } } @@ -58,7 +106,7 @@ pub struct ModuleUnit<'ctx> { typectx: TypeContext, llvm_context: &'ctx Context, llvm_module: &'ctx Module, - scope_stack: Vec, + scope_stack: RefCell>, path: PathBuf, } @@ -79,41 +127,63 @@ impl<'ctx> ModuleUnit<'ctx> { llvm_module, modules: HashMap::new(), typectx: TypeContext::new(), - scope_stack: vec![], + scope_stack: RefCell::new(vec![]), } } - pub fn in_root_scope(&mut self, mut f: F) + pub fn in_root_scope(&self, f: F) where - F: FnMut(&mut Self), + F: FnOnce(&Self), { self.enter_root_scope(); f(self); self.exit_scope(); } - fn enter_root_scope(&mut self) { - self.scope_stack.push(Scope::with_builder_and_fdir( - Builder::new_in_context(self.llvm_context.as_ref()), - self.path.clone(), - )); + fn enter_root_scope(&self) { + self.scope_stack + .borrow_mut() + .push(Scope::with_fdir(self.path.clone())); + } + + fn in_function_scope(&self, func: (String, FunctionType), builder: Builder) { + self.enter_function_scope(func, builder); + self.exit_scope(); + } + + fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { + self.scope_stack + .borrow_mut() + .push(Scope::with_function(func, builder)); } - fn exit_scope(&mut self) { - self.scope_stack.pop(); + fn exit_scope(&self) { + self.scope_stack.borrow_mut().pop(); } - fn dispatch(&mut self, command: ModuleCommand) { + fn dispatch(&self, command: Message) { match command { - ModuleCommand::RegisterFunction(name, func, ty) => { + Message::RegisterFunction(name, func, ty) => { + let mut scope_stack = self.scope_stack.borrow_mut(); if ty == FuncType::Local { - self.scope_stack.last_mut() + scope_stack.last_mut() } else { - self.scope_stack.first_mut() + scope_stack.first_mut() } .expect("ICE: Scope stack is corrupted.") .add_function(name, func); } + Message::EnterFunctionScope(func) => { + let builder = Builder::new_in_context(self.llvm_context.as_ref()); + self.in_function_scope(func, builder); + } + Message::ExitScope => self.exit_scope(), + } + } + + fn query(&self, query: Query) -> QueryResponse { + match query { + Query::Function(func) => QueryResponse::Function(self.get_func(func)), } } @@ -125,42 +195,61 @@ impl<'ctx> ModuleUnit<'ctx> { self.modules.get_mut(name) } - pub fn decl(&mut self) { + pub fn decl(&'ctx self, root_builder: &Builder) { let ast = self.ast.clone(); - let llvm_context = self.llvm_context; - let llvm_module = self.llvm_module; - let llvm_builder = self.llvm_builder_ref(); - let dispatch = &mut |command: ModuleCommand| self.dispatch(command); - let mut ctx = ModuleContext::new(llvm_context, llvm_module, &*llvm_builder, dispatch); + let dispatch = &|command: Message| self.dispatch(command); + let query = &|query: Query| self.query(query); + match ast { box AST::File(ref nodes) => nodes .iter() - .fold(Some(()), |_, ast| Some(decl(ast, &mut ctx))) + .fold(Some(()), |_, ast| { + Some(decl( + ast, + &mut ModuleContext::new( + self.llvm_context, + self.llvm_module, + root_builder, + dispatch, + query, + ), + )) + }) .unwrap(), _ => todo!("{:?}", self.ast), } } - pub fn codegen(&mut self) -> Option { + pub fn codegen(&'ctx self, root_builder: &Builder) -> Option { let ast = self.ast.clone(); - let llvm_context = self.llvm_context; - let llvm_module = self.llvm_module; - let llvm_builder = self.llvm_builder_ref(); - let dispatch = &mut |command: ModuleCommand| self.dispatch(command); - let mut ctx = ModuleContext::new(llvm_context, llvm_module, &*llvm_builder, dispatch); + let dispatch = &|command: Message| self.dispatch(command); + let query = &|query: Query| self.query(query); + match ast { - box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| comp(n)), + box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| { + cg( + n, + ModuleContext::new( + self.llvm_context, + self.llvm_module, + root_builder, + dispatch, + query, + ), + ) + }), _ => todo!("{:?}", self.ast), } } - pub fn llvm_builder_ref(&self) -> Rc { - for scope in self.scope_stack.iter().rev() { - if let Some(builder) = scope.builder() { - return builder; + pub fn get_func(&self, func: (&String, &FunctionType)) -> Option> { + for scope in self.scope_stack.borrow().iter().rev() { + if let Some(group) = scope.func_by_name(func.0) { + return find_func(group, func.1); } } - unreachable!(); + + None } pub fn llvm_module_ref(&self) -> &Module { From 5776fadb5d262a1bb15a39acf35b2331fb9e0181 Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 6 Mar 2021 15:06:09 +0200 Subject: [PATCH 06/18] The One With Modules VI --- comp-be/src/codegen/atom.rs | 5 -- comp-be/src/codegen/module.rs | 12 ----- comp-be/src/codegen/scope.rs | 14 +++-- comp-be/src/codegen/unit/cg/atom.rs | 14 +++++ comp-be/src/codegen/unit/cg/call.rs | 78 ++++++++++++++++++++++++++++ comp-be/src/codegen/unit/cg/expr.rs | 9 +++- comp-be/src/codegen/unit/cg/mod.rs | 6 ++- comp-be/src/codegen/unit/function.rs | 25 +++++---- comp-be/src/codegen/unit/module.rs | 67 +++++++++++++----------- comp-be/src/lib.rs | 3 +- main.aat | 5 +- 11 files changed, 170 insertions(+), 68 deletions(-) create mode 100644 comp-be/src/codegen/unit/cg/atom.rs create mode 100644 comp-be/src/codegen/unit/cg/call.rs diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index 8d6f48b..69b39c3 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -184,13 +184,8 @@ impl AatbeModule { Some((*var, PrimitiveType::Ref(box var.prim().clone())).into()) } - atom @ (AtomKind::StringLiteral(_) | AtomKind::CharLiteral(_)) => { - const_atom(self, atom) - } atom @ AtomKind::Integer(_, _) => const_atom(self, atom), atom @ AtomKind::Floating(_, _) => const_atom(self, atom), - AtomKind::Bool(Boolean::True) => Some(value::t(self)), - AtomKind::Bool(Boolean::False) => Some(value::f(self)), AtomKind::Expr(expr) => self.codegen_expr(expr), AtomKind::Unit => None, AtomKind::Unary(op, val) if op == &String::from("-") => { diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 89190ce..964a5a3 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -551,7 +551,6 @@ impl AatbeModule { } Expression::Loop { .. } => self.codegen_basic_loop(expr), Expression::If { .. } => self.codegen_if(expr), - Expression::Call { .. } => self.codegen_call(expr), Expression::Binary(lhs, op, rhs) => match codegen_binary(self, op, lhs, rhs) { Ok(val) => Some(val), Err(_) => { @@ -585,7 +584,6 @@ impl AatbeModule { ret } - Expression::Atom(atom) => self.codegen_atom(atom), _ => panic!("ICE: codegen_expr {:?}", expr), }*/ } @@ -682,16 +680,6 @@ impl AatbeModule { .add_symbol(name, unit); } - pub fn get_func_group(&self, name: &String) -> Option<&FuncTyMap> { - for scope in self.scope_stack.iter().rev() { - if let Some(func) = scope.func_by_name(name) { - return Some(func); - } - } - - None - } - */ pub fn propagate_generic_body( diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 340de95..71449b5 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -5,7 +5,7 @@ use crate::codegen::{ }, AatbeModule, }; -use std::{collections::HashMap, path::PathBuf, rc::Rc}; +use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; use parser::ast::FunctionType; @@ -69,16 +69,20 @@ impl Scope { } } - pub fn func_by_name(&self, name: &String) -> Option<&FuncTyMap> { - self.functions.get(name) + pub fn func_by_name(&self, name: &String) -> Option> { + self.functions.get(name).cloned() } pub fn add_function(&mut self, name: &String, func: Func) { if !self.functions.contains_key(name) { - self.functions.insert(name.clone(), vec![]); + self.functions.insert(name.clone(), RefCell::new(vec![])); } - self.functions.get_mut(name).unwrap().push(Rc::new(func)); + self.functions + .get_mut(name) + .unwrap() + .get_mut() + .push(Rc::new(func)); } pub fn find_symbol(&self, name: &String) -> Option<&Slot> { diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs new file mode 100644 index 0000000..3e765f6 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -0,0 +1,14 @@ +use parser::ast::{AtomKind, Boolean}; + +use crate::codegen::{ + builder::value, expr::const_expr::const_atom, unit::ModuleContext, ValueTypePair, +}; + +pub fn cg(atom: &AtomKind, ctx: &ModuleContext) -> Option { + match atom { + AtomKind::Bool(Boolean::True) => Some(value::t(ctx)), + AtomKind::Bool(Boolean::False) => Some(value::f(ctx)), + atom @ (AtomKind::StringLiteral(_) | AtomKind::CharLiteral(_)) => const_atom(ctx, atom), + _ => todo!("{:?}", atom), + } +} diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs new file mode 100644 index 0000000..fcdbefd --- /dev/null +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -0,0 +1,78 @@ +use std::borrow::Borrow; + +use parser::ast::{AtomKind, Expression, PrimitiveType}; + +use crate::codegen::{ + builder::core, + unit::{cg::expr, function::find_function, ModuleContext, Query, QueryResponse}, + ValueTypePair, +}; + +pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { + if let Expression::Call { + name, + types: _, + args, + } = expr + { + let mut call_types = vec![]; + + let mut error = false; + let mut call_args = args + .iter() + .filter_map(|arg| match arg { + Expression::Atom(AtomKind::SymbolLiteral(sym)) => { + call_types.push(PrimitiveType::Symbol(sym.clone())); + None + } + Expression::Atom(AtomKind::Unit) => { + call_types.push(PrimitiveType::Unit); + None + } + _ => { + let expr = expr::cg(arg, ctx); + + if expr.is_none() { + error = true; + + None + } else { + expr.map_or(None, |arg| match arg.prim().clone() { + ref ty @ PrimitiveType::VariantType(ref _name) => todo!("{:?}", ty), + ref ty @ PrimitiveType::Array { .. } => todo!("{:?}", ty), + ref ty @ PrimitiveType::Ref(box PrimitiveType::Array { .. }) => { + todo!("{:?}", ty) + } + ref ty @ _ => { + call_types.push(ty.clone()); + Some(*arg) + } + }) + } + } + }) + .collect::>(); + + if error { + return None; + } + + if let QueryResponse::FunctionGroup(Some(group)) = ctx.query(Query::FunctionGroup(name)) { + if let Some(func) = find_function(group, &call_types) { + Some(core::call( + ctx, + func.upgrade().expect("ICE").borrow(), + &mut call_args, + )); + } else { + todo!(); + } + } else { + todo!(); + } + + None + } else { + unreachable!() + } +} diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 14ba658..bb1b161 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -1,12 +1,17 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ - unit::{declare_and_compile_function, ModuleContext}, + unit::{ + cg::{atom, call}, + declare_and_compile_function, ModuleContext, + }, ValueTypePair, }; -pub fn cg(expr: &Expression, ctx: ModuleContext) -> Option { +pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { match expr { + Expression::Call { .. } => call::cg(expr, ctx), + Expression::Atom(atom) => atom::cg(atom, ctx), Expression::Function { ty, type_names, .. } if type_names.len() == 0 => match ty { FunctionType { ret_ty: _, diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs index 5b15a58..bd0d95f 100644 --- a/comp-be/src/codegen/unit/cg/mod.rs +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -3,9 +3,11 @@ use parser::ast::AST; use super::ModuleContext; -mod expr; +pub mod atom; +pub mod call; +pub mod expr; -pub fn cg(ast: &AST, ctx: ModuleContext) -> Option { +pub fn cg(ast: &AST, ctx: &ModuleContext) -> Option { match ast { AST::Expr(expr) => expr::cg(expr, ctx).map(|e| *e), _ => todo!("{:?}", ast), diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 4d91e87..cc04c4c 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,7 +3,7 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{FuncType, Message, Mutability, Query, QueryResponse, Slot}, + unit::{cg::expr, FuncType, Message, Mutability, Query, QueryResponse, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -12,6 +12,7 @@ use crate::{ use llvm_sys_wrapper::Function; use std::{ borrow::Borrow, + cell::RefCell, collections::HashMap, ops::Deref, rc::{Rc, Weak}, @@ -46,10 +47,10 @@ impl AatbeFmt for &Func { } pub type FuncTyMap = Vec>; -pub type FunctionMap = HashMap; +pub type FunctionMap = HashMap>; -pub fn find_func<'a>(map: &'a FuncTyMap, ty: &FunctionType) -> Option> { - for func in map { +pub fn find_func<'a>(map: RefCell, ty: &FunctionType) -> Option> { + for func in map.borrow().iter() { if &func.ty == ty { return Some(Rc::downgrade(func)); } @@ -57,10 +58,10 @@ pub fn find_func<'a>(map: &'a FuncTyMap, ty: &FunctionType) -> Option return None; } -pub fn find_function<'a>(map: &'a FuncTyMap, args: &Vec) -> Option<&'a Func> { - for func in map { +pub fn find_function<'a>(map: RefCell, args: &Vec) -> Option> { + for func in map.borrow().iter() { if func.accepts(args) { - return Some(func); + return Some(Rc::downgrade(func)); } } return None; @@ -149,10 +150,9 @@ pub fn declare_function(ctx: &ModuleContext, function: &Expression) { } pub fn declare_and_compile_function<'ctx>( - ctx: ModuleContext, + ctx: &ModuleContext, func: &Expression, ) -> Option { - //todo!("{:?}", func); match func { Expression::Function { ty, body, name, .. } => match ty { FunctionType { @@ -164,6 +164,13 @@ pub fn declare_and_compile_function<'ctx>( ctx.in_function_scope((name.clone(), ty.clone()), |ctx| { codegen_function(&ctx, func); + expr::cg( + &body + .as_ref() + .expect("ICE Function with no body but not external"), + &ctx, + ); + if !has_return_type(ty) { core::ret_void(&ctx); } else { diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index e68affc..f5c0d72 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -1,10 +1,4 @@ -use std::{ - borrow::Borrow, - cell::RefCell, - collections::HashMap, - path::PathBuf, - rc::{Rc, Weak}, -}; +use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Weak}; use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; use parser::ast::{Expression, FunctionType, AST}; @@ -17,7 +11,7 @@ use crate::{ ty::TypeContext, }; -use super::function::Func; +use super::function::{Func, FuncTyMap}; #[derive(Copy, Clone, PartialEq, Eq)] pub enum FuncType { @@ -33,10 +27,12 @@ pub enum Message<'cmd> { pub enum Query<'cmd> { Function((&'cmd String, &'cmd FunctionType)), + FunctionGroup(&'cmd String), } pub enum QueryResponse { Function(Option>), + FunctionGroup(Option>), } pub struct ModuleContext<'ctx> { @@ -48,28 +44,6 @@ pub struct ModuleContext<'ctx> { query: &'ctx dyn Fn(Query) -> QueryResponse, } -impl ModuleContext<'ctx> { - pub fn dispatch(&self, command: Message) { - (self.dispatch)(command) - } - - pub fn query(&self, query: Query) -> QueryResponse { - (self.query)(query) - } - - pub fn in_function_scope(&self, func: (String, FunctionType), f: F) -> Option - where - F: FnOnce(ModuleContext) -> Option, - { - self.dispatch(Message::EnterFunctionScope(func)); - let builder = Builder::new_in_context(self.llvm_context.as_ref()); - let ctx = self.with_builder(&builder); - let res = f(ctx); - self.dispatch(Message::ExitScope); - res - } -} - impl<'ctx> ModuleContext<'ctx> { pub fn new( llvm_context: &'ctx Context, @@ -98,6 +72,26 @@ impl<'ctx> ModuleContext<'ctx> { function_templates: HashMap::new(), } } + + pub fn dispatch(&self, command: Message) { + (self.dispatch)(command) + } + + pub fn query(&self, query: Query) -> QueryResponse { + (self.query)(query) + } + + pub fn in_function_scope(&self, func: (String, FunctionType), f: F) -> Option + where + F: FnOnce(ModuleContext) -> Option, + { + self.dispatch(Message::EnterFunctionScope(func)); + let builder = Builder::new_in_context(self.llvm_context.as_ref()); + let ctx = self.with_builder(&builder); + let res = f(ctx); + self.dispatch(Message::ExitScope); + res + } } pub struct ModuleUnit<'ctx> { @@ -184,6 +178,7 @@ impl<'ctx> ModuleUnit<'ctx> { fn query(&self, query: Query) -> QueryResponse { match query { Query::Function(func) => QueryResponse::Function(self.get_func(func)), + Query::FunctionGroup(name) => QueryResponse::FunctionGroup(self.get_func_group(name)), } } @@ -229,7 +224,7 @@ impl<'ctx> ModuleUnit<'ctx> { box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| { cg( n, - ModuleContext::new( + &ModuleContext::new( self.llvm_context, self.llvm_module, root_builder, @@ -242,6 +237,16 @@ impl<'ctx> ModuleUnit<'ctx> { } } + pub fn get_func_group(&self, name: &String) -> Option> { + for scope in self.scope_stack.borrow().iter().rev() { + if let Some(func) = scope.func_by_name(name) { + return Some(func); + } + } + + None + } + pub fn get_func(&self, func: (&String, &FunctionType)) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { if let Some(group) = scope.func_by_name(func.0) { diff --git a/comp-be/src/lib.rs b/comp-be/src/lib.rs index 1f44c7b..7965207 100644 --- a/comp-be/src/lib.rs +++ b/comp-be/src/lib.rs @@ -7,7 +7,8 @@ or_patterns, bindings_after_at, type_alias_impl_trait, - in_band_lifetimes + in_band_lifetimes, + move_ref_pattern )] pub mod codegen; diff --git a/main.aat b/main.aat index 12b4e7a..9145ab6 100644 --- a/main.aat +++ b/main.aat @@ -1,2 +1,5 @@ +extern fn printf str, ... -> () + @entry -fn main () -> () = {} +fn main () -> () = + printf "Hello" From 32c61041a984a9a7c468e27b75067140d44ea1eb Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 6 Mar 2021 20:36:56 +0200 Subject: [PATCH 07/18] The One With Modules VII --- Cargo.lock | 193 ++++++++++----------------- aatboot/Cargo.toml | 2 +- aatboot/src/main.rs | 7 +- comp-be/Cargo.toml | 1 + comp-be/src/codegen/unit/cg/atom.rs | 7 +- comp-be/src/codegen/unit/cg/call.rs | 8 +- comp-be/src/codegen/unit/cg/expr.rs | 1 + comp-be/src/codegen/unit/function.rs | 11 +- comp-be/src/codegen/unit/module.rs | 17 ++- main.aat | 6 +- 10 files changed, 110 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1f9da6..83a71d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,12 +7,12 @@ dependencies = [ "clap", "comp-be", "dotenv", + "flexi_logger", "glob", "llvm-sys", "llvm-sys-wrapper", "log", "parser", - "simplelog", ] [[package]] @@ -37,18 +37,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - [[package]] name = "atty" version = "0.2.14" @@ -66,29 +54,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -[[package]] -name = "base64" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" - [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "cc" version = "1.0.50" @@ -97,9 +68,9 @@ checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" @@ -132,49 +103,11 @@ name = "comp-be" version = "0.0.1" dependencies = [ "llvm-sys-wrapper", + "log", "parser", "tuple-combinator", ] -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "dirs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -dependencies = [ - "cfg-if", - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -dependencies = [ - "cfg-if", - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenv" version = "0.15.0" @@ -182,14 +115,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] -name = "getrandom" -version = "0.1.14" +name = "flexi_logger" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" +checksum = "33ab94b6ac8eb69f1496a6993f26f785b5fd6d99b7416023eb2a6175c0b242b1" dependencies = [ - "cfg-if", - "libc", - "wasi", + "atty", + "chrono", + "glob", + "lazy_static", + "log", + "regex", + "thiserror", + "yansi", ] [[package]] @@ -242,9 +180,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if", ] @@ -279,22 +217,29 @@ name = "parser" version = "0.1.0" [[package]] -name = "redox_syscall" -version = "0.1.56" +name = "proc-macro2" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] [[package]] -name = "redox_users" -version = "0.3.4" +name = "quote" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ - "getrandom", - "redox_syscall", - "rust-argon2", + "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" + [[package]] name = "regex" version = "1.3.9" @@ -313,18 +258,6 @@ version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" -[[package]] -name = "rust-argon2" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "semver" version = "0.9.0" @@ -340,17 +273,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "simplelog" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a3e303ace6adb0a60a9e9e2fbc6a33e1749d1e43587e2125f7efa9c5e107c5" -dependencies = [ - "chrono", - "log", - "term", -] - [[package]] name = "strsim" version = "0.8.0" @@ -358,13 +280,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] -name = "term" -version = "0.6.1" +name = "syn" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" +checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5" dependencies = [ - "dirs", - "winapi", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] @@ -376,6 +299,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -409,16 +352,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" [[package]] -name = "vec_map" -version = "0.8.1" +name = "unicode-xid" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +name = "vec_map" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "winapi" @@ -441,3 +384,9 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yansi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" diff --git a/aatboot/Cargo.toml b/aatboot/Cargo.toml index ad12e32..538bdd8 100644 --- a/aatboot/Cargo.toml +++ b/aatboot/Cargo.toml @@ -12,7 +12,7 @@ comp-be = { path="../comp-be" } parser = { path="../parser" } clap = "^2.33.0" -simplelog = "^0.7.4" +flexi_logger = "0.17.1" log = "^0.4" glob = "^0.3.0" llvm-sys = "100.0" diff --git a/aatboot/src/main.rs b/aatboot/src/main.rs index 6ba7291..295f0b1 100644 --- a/aatboot/src/main.rs +++ b/aatboot/src/main.rs @@ -1,6 +1,7 @@ use comp_be::codegen::{comp_unit::CompilationUnit, AatbeModule, CompileError}; use clap::{clap_app, crate_authors, crate_description, crate_version}; +use flexi_logger::Logger; use std::{ env, ffi::CString, @@ -17,7 +18,6 @@ use glob::glob; use llvm_sys::support::LLVMLoadLibraryPermanently; use llvm_sys_wrapper::{CodegenLevel, CPU, LLVM}; use log::{error, warn}; -use simplelog::*; fn main() -> io::Result<()> { dotenv().ok(); @@ -34,10 +34,7 @@ fn main() -> io::Result<()> { (@arg LIB: -l ... +takes_value "Link with library without prefix or extension")) .get_matches(); - if let Err(_) = TermLogger::init(LevelFilter::Warn, Config::default(), TerminalMode::Mixed) { - SimpleLogger::init(LevelFilter::Warn, Config::default()) - .expect("No logger should be already set") - } + Logger::with_env_or_str("trace").start().unwrap(); let input_path = Path::new(matches.value_of_os("INPUT").unwrap()).to_path_buf(); let main_cu = CompilationUnit::new(input_path.clone())?; diff --git a/comp-be/Cargo.toml b/comp-be/Cargo.toml index 2b79400..7475990 100644 --- a/comp-be/Cargo.toml +++ b/comp-be/Cargo.toml @@ -13,3 +13,4 @@ path = "src/lib.rs" llvm-sys-wrapper = { path = "../llvm-sys-wrapper" } tuple-combinator = "0.2.1" parser = { path = "../parser" } +log = "0.4.14" diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index 3e765f6..8d4bfe1 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -1,11 +1,16 @@ use parser::ast::{AtomKind, Boolean}; use crate::codegen::{ - builder::value, expr::const_expr::const_atom, unit::ModuleContext, ValueTypePair, + builder::value, + expr::const_expr::const_atom, + unit::{cg::expr, ModuleContext}, + ValueTypePair, }; pub fn cg(atom: &AtomKind, ctx: &ModuleContext) -> Option { match atom { + AtomKind::Parenthesized(expr) => expr::cg(expr, ctx), + AtomKind::Unit => None, AtomKind::Bool(Boolean::True) => Some(value::t(ctx)), AtomKind::Bool(Boolean::False) => Some(value::f(ctx)), atom @ (AtomKind::StringLiteral(_) | AtomKind::CharLiteral(_)) => const_atom(ctx, atom), diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index fcdbefd..714ee1a 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -8,6 +8,8 @@ use crate::codegen::{ ValueTypePair, }; +use log::*; + pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { if let Expression::Call { name, @@ -15,6 +17,7 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { args, } = expr { + trace!("Call {}", name); let mut call_types = vec![]; let mut error = false; @@ -54,6 +57,7 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { .collect::>(); if error { + trace!("Got error"); return None; } @@ -63,15 +67,13 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { ctx, func.upgrade().expect("ICE").borrow(), &mut call_args, - )); + )) } else { todo!(); } } else { todo!(); } - - None } else { unreachable!() } diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index bb1b161..e495726 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -20,6 +20,7 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { } => None, _ => declare_and_compile_function(ctx, expr), }, + Expression::Block(body) if body.len() == 0 => None, _ => todo!("{:?}", expr), } } diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index cc04c4c..9ab6a4b 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -164,7 +164,7 @@ pub fn declare_and_compile_function<'ctx>( ctx.in_function_scope((name.clone(), ty.clone()), |ctx| { codegen_function(&ctx, func); - expr::cg( + let ret_val = expr::cg( &body .as_ref() .expect("ICE Function with no body but not external"), @@ -174,7 +174,14 @@ pub fn declare_and_compile_function<'ctx>( if !has_return_type(ty) { core::ret_void(&ctx); } else { - todo!(); + if let Some(val) = ret_val { + match val.prim() { + PrimitiveType::VariantType(_variant) => todo!(), + _ => core::ret(&ctx, val), + }; + } else { + todo!() + } } None diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index f5c0d72..d5e7e6b 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -13,23 +13,28 @@ use crate::{ use super::function::{Func, FuncTyMap}; -#[derive(Copy, Clone, PartialEq, Eq)] +use log::*; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum FuncType { Local, Export, } +#[derive(Debug)] pub enum Message<'cmd> { RegisterFunction(&'cmd String, Func, FuncType), EnterFunctionScope((String, FunctionType)), ExitScope, } +#[derive(Debug)] pub enum Query<'cmd> { Function((&'cmd String, &'cmd FunctionType)), FunctionGroup(&'cmd String), } +#[derive(Debug)] pub enum QueryResponse { Function(Option>), FunctionGroup(Option>), @@ -135,23 +140,21 @@ impl<'ctx> ModuleUnit<'ctx> { } fn enter_root_scope(&self) { + trace!("Enter root scope"); self.scope_stack .borrow_mut() .push(Scope::with_fdir(self.path.clone())); } - fn in_function_scope(&self, func: (String, FunctionType), builder: Builder) { - self.enter_function_scope(func, builder); - self.exit_scope(); - } - fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { + trace!("Enter function scope {}", func.0); self.scope_stack .borrow_mut() .push(Scope::with_function(func, builder)); } fn exit_scope(&self) { + trace!("Exit scope"); self.scope_stack.borrow_mut().pop(); } @@ -169,7 +172,7 @@ impl<'ctx> ModuleUnit<'ctx> { } Message::EnterFunctionScope(func) => { let builder = Builder::new_in_context(self.llvm_context.as_ref()); - self.in_function_scope(func, builder); + self.enter_function_scope(func, builder); } Message::ExitScope => self.exit_scope(), } diff --git a/main.aat b/main.aat index 9145ab6..29845ab 100644 --- a/main.aat +++ b/main.aat @@ -1,5 +1,7 @@ extern fn printf str, ... -> () +fn world () -> str = "World!\n" + @entry -fn main () -> () = - printf "Hello" +fn main () = + printf "Hello %s", world() From 4894eca98e971fed16a80ac52d0953766bc9c167 Mon Sep 17 00:00:00 2001 From: chronium Date: Mon, 15 Mar 2021 10:40:32 +0200 Subject: [PATCH 08/18] The One With Modules VIII --- aatboot/src/main.rs | 9 +-- comp-be/src/codegen/comp_unit.rs | 2 +- comp-be/src/codegen/mod.rs | 2 +- comp-be/src/codegen/unit/cg/call.rs | 13 ++-- comp-be/src/codegen/unit/cg/expr.rs | 14 ++++- comp-be/src/codegen/unit/function.rs | 21 +++++-- comp-be/src/codegen/unit/mod.rs | 2 +- comp-be/src/codegen/unit/module.rs | 88 ++++++++++++++++++++++++---- comp-be/src/lib.rs | 2 - main.aat | 3 +- 10 files changed, 121 insertions(+), 35 deletions(-) diff --git a/aatboot/src/main.rs b/aatboot/src/main.rs index 295f0b1..43a1fc7 100644 --- a/aatboot/src/main.rs +++ b/aatboot/src/main.rs @@ -77,11 +77,8 @@ fn main() -> io::Result<()> { error!("-l{} found too many matches, please be more specific", lib); } else { unsafe { - LLVMLoadLibraryPermanently( - CString::new(globs[0].to_str().unwrap()) - .expect("cstring failed") - .as_ptr(), - ); + let cs = CString::new(globs[0].to_str().unwrap()).expect("cstring failed"); + LLVMLoadLibraryPermanently(cs.as_ptr()); } } } @@ -227,6 +224,6 @@ fn main() -> io::Result<()> { } Ok(()) } - Err(err) => panic!(err), + Err(err) => panic!("{}", err), } } diff --git a/comp-be/src/codegen/comp_unit.rs b/comp-be/src/codegen/comp_unit.rs index ed351f0..18a1efc 100644 --- a/comp-be/src/codegen/comp_unit.rs +++ b/comp-be/src/codegen/comp_unit.rs @@ -26,7 +26,7 @@ impl CompilationUnit { path, ast: match Parser::new(Lexer::new(code.as_str()).lex()).parse() { Ok(ptree) => ptree, - Err(err) => panic!(format!("{:#?}", err)), + Err(err) => panic!("{:#?}", err), }, }) } diff --git a/comp-be/src/codegen/mod.rs b/comp-be/src/codegen/mod.rs index d511459..152fab2 100644 --- a/comp-be/src/codegen/mod.rs +++ b/comp-be/src/codegen/mod.rs @@ -132,7 +132,7 @@ impl ValueTypePair { }), ) => ty, ValueTypePair(_, TypeKind::Primitive(prim)) => prim, - _ => panic!("ICE prim {:?}"), + _ => panic!("ICE prim"), } } diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index 714ee1a..1d5cddf 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -2,10 +2,13 @@ use std::borrow::Borrow; use parser::ast::{AtomKind, Expression, PrimitiveType}; -use crate::codegen::{ - builder::core, - unit::{cg::expr, function::find_function, ModuleContext, Query, QueryResponse}, - ValueTypePair, +use crate::{ + codegen::{ + builder::core, + unit::{cg::expr, function::find_function, ModuleContext, Query, QueryResponse}, + ValueTypePair, + }, + fmt::AatbeFmt, }; use log::*; @@ -17,7 +20,7 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { args, } = expr { - trace!("Call {}", name); + trace!("Call {}", AatbeFmt::fmt(expr)); let mut call_types = vec![]; let mut error = false; diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index e495726..9b56613 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -3,7 +3,7 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ unit::{ cg::{atom, call}, - declare_and_compile_function, ModuleContext, + declare_and_compile_function, Message, ModuleContext, }, ValueTypePair, }; @@ -21,6 +21,18 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { _ => declare_and_compile_function(ctx, expr), }, Expression::Block(body) if body.len() == 0 => None, + Expression::Block(body) => { + ctx.dispatch(Message::EnterAnonymousScope); + + let ret = body + .iter() + .fold(None, |_, expr| Some(cg(expr, ctx))) + .unwrap(); + + ctx.dispatch(Message::ExitScope); + + ret + } _ => todo!("{:?}", expr), } } diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 9ab6a4b..a245c7a 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,7 +3,7 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{cg::expr, FuncType, Message, Mutability, Query, QueryResponse, Slot}, + unit::{cg::expr, FunctionVisibility, Message, Mutability, Query, QueryResponse, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -24,13 +24,18 @@ use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; use super::ModuleContext; -#[derive(Debug)] pub struct Func { ty: FunctionType, name: String, inner: Function, } +impl std::fmt::Debug for Func { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", AatbeFmt::fmt(self)) + } +} + impl AatbeFmt for &Func { fn fmt(self) -> String { format!( @@ -140,9 +145,17 @@ pub fn declare_function(ctx: &ModuleContext, function: &Expression) { let func = Func::new(ty.clone(), name.clone(), func); if !export { - ctx.dispatch(Message::RegisterFunction(&name, func, FuncType::Local)); + ctx.dispatch(Message::RegisterFunction( + &name, + func, + FunctionVisibility::Local, + )); } else { - ctx.dispatch(Message::RegisterFunction(&name, func, FuncType::Export)); + ctx.dispatch(Message::RegisterFunction( + &name, + func, + FunctionVisibility::Export, + )); } } _ => unimplemented!("{:?}", function), diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 8d74379..6f9abbd 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -12,7 +12,7 @@ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; pub mod module; -pub use module::{FuncType, Message, ModuleContext, ModuleUnit, Query, QueryResponse}; +pub use module::{FunctionVisibility, Message, ModuleContext, ModuleUnit, Query, QueryResponse}; pub mod decl; pub use decl::decl; diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/module.rs index d5e7e6b..09e0564 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/module.rs @@ -8,6 +8,7 @@ use crate::{ unit::{cg, decl, function::find_func}, Scope, ValueTypePair, }, + fmt::AatbeFmt, ty::TypeContext, }; @@ -16,30 +17,86 @@ use super::function::{Func, FuncTyMap}; use log::*; #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum FuncType { +pub enum FunctionVisibility { Local, Export, } -#[derive(Debug)] pub enum Message<'cmd> { - RegisterFunction(&'cmd String, Func, FuncType), + RegisterFunction(&'cmd String, Func, FunctionVisibility), EnterFunctionScope((String, FunctionType)), + EnterAnonymousScope, ExitScope, } -#[derive(Debug)] +impl std::fmt::Debug for Message<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Message::RegisterFunction(name, ty, vis) => f + .debug_tuple("RegisterFunction") + .field(name) + .field(&AatbeFmt::fmt(ty)) + .field(vis) + .finish(), + Message::EnterFunctionScope(func) => f + .debug_tuple("EnterFunctionScope") + .field(&func.0) + .field(&AatbeFmt::fmt(&func.1)) + .finish(), + Message::EnterAnonymousScope => write!(f, "EnterAnonymousScope"), + Message::ExitScope => write!(f, "ExitScope"), + } + } +} + pub enum Query<'cmd> { Function((&'cmd String, &'cmd FunctionType)), FunctionGroup(&'cmd String), } -#[derive(Debug)] +impl std::fmt::Debug for Query<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Query::Function(func) => f + .debug_tuple("Function") + .field(func.0) + .field(&AatbeFmt::fmt(func.1)) + .finish(), + Query::FunctionGroup(name) => f.debug_tuple("FunctionGroup").field(name).finish(), + } + } +} + pub enum QueryResponse { Function(Option>), FunctionGroup(Option>), } +impl std::fmt::Debug for QueryResponse { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + QueryResponse::Function(ref func) => f + .debug_tuple("Function") + .field( + &func + .as_ref() + .map(|f| AatbeFmt::fmt(f.upgrade().expect("ICE").as_ref())), + ) + .finish(), + QueryResponse::FunctionGroup(group) => f + .debug_tuple("FunctionGroup") + .field(&format_args!( + "{}", + match group.as_ref() { + None => String::from("[]"), + Some(gr) => format!("{:?}", gr.borrow().iter().collect::>()), + } + )) + .finish(), + } + } +} + pub struct ModuleContext<'ctx> { pub llvm_context: &'ctx Context, pub llvm_module: &'ctx Module, @@ -78,8 +135,8 @@ impl<'ctx> ModuleContext<'ctx> { } } - pub fn dispatch(&self, command: Message) { - (self.dispatch)(command) + pub fn dispatch(&self, message: Message) { + (self.dispatch)(message) } pub fn query(&self, query: Query) -> QueryResponse { @@ -147,7 +204,7 @@ impl<'ctx> ModuleUnit<'ctx> { } fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { - trace!("Enter function scope {}", func.0); + trace!("Enter function scope {:?}", func.0); self.scope_stack .borrow_mut() .push(Scope::with_function(func, builder)); @@ -158,11 +215,12 @@ impl<'ctx> ModuleUnit<'ctx> { self.scope_stack.borrow_mut().pop(); } - fn dispatch(&self, command: Message) { - match command { + fn dispatch(&self, message: Message) { + trace!("Dispatch {:?}", message); + match message { Message::RegisterFunction(name, func, ty) => { let mut scope_stack = self.scope_stack.borrow_mut(); - if ty == FuncType::Local { + if ty == FunctionVisibility::Local { scope_stack.last_mut() } else { scope_stack.first_mut() @@ -174,15 +232,19 @@ impl<'ctx> ModuleUnit<'ctx> { let builder = Builder::new_in_context(self.llvm_context.as_ref()); self.enter_function_scope(func, builder); } + Message::EnterAnonymousScope => {} Message::ExitScope => self.exit_scope(), } } fn query(&self, query: Query) -> QueryResponse { - match query { + trace!("Query {:?}", query); + let response = match query { Query::Function(func) => QueryResponse::Function(self.get_func(func)), Query::FunctionGroup(name) => QueryResponse::FunctionGroup(self.get_func_group(name)), - } + }; + trace!("Response {:?}", response); + response } pub fn push(&mut self, name: &String, module: ModuleUnit<'ctx>) -> Option> { diff --git a/comp-be/src/lib.rs b/comp-be/src/lib.rs index 7965207..7972c04 100644 --- a/comp-be/src/lib.rs +++ b/comp-be/src/lib.rs @@ -2,13 +2,11 @@ box_syntax, box_patterns, type_ascription, - vec_remove_item, option_expect_none, or_patterns, bindings_after_at, type_alias_impl_trait, in_band_lifetimes, - move_ref_pattern )] pub mod codegen; diff --git a/main.aat b/main.aat index 29845ab..e0e6fc2 100644 --- a/main.aat +++ b/main.aat @@ -3,5 +3,6 @@ extern fn printf str, ... -> () fn world () -> str = "World!\n" @entry -fn main () = +fn main () = { printf "Hello %s", world() +} From 10e06d63646595dbbf872ad66fc4cef092fe4102 Mon Sep 17 00:00:00 2001 From: chronium Date: Wed, 17 Mar 2021 07:18:46 +0200 Subject: [PATCH 09/18] The One With Modules IX --- comp-be/src/codegen/builder/branch.rs | 6 +- comp-be/src/codegen/builder/cast.rs | 28 +- comp-be/src/codegen/builder/core.rs | 52 ++-- comp-be/src/codegen/builder/op.rs | 10 +- comp-be/src/codegen/builder/ty.rs | 22 +- comp-be/src/codegen/builder/value.rs | 34 +-- comp-be/src/codegen/expr/compare.rs | 8 +- comp-be/src/codegen/expr/const_expr.rs | 6 +- comp-be/src/codegen/expr/eqne.rs | 8 +- comp-be/src/codegen/expr/math.rs | 8 +- comp-be/src/codegen/expr/mod.rs | 12 +- comp-be/src/codegen/mangle_v1.rs | 21 +- comp-be/src/codegen/module.rs | 8 +- comp-be/src/codegen/scope.rs | 8 +- comp-be/src/codegen/unit/cg/atom.rs | 4 +- comp-be/src/codegen/unit/cg/call.rs | 27 +- comp-be/src/codegen/unit/cg/expr.rs | 4 +- comp-be/src/codegen/unit/cg/mod.rs | 11 +- .../codegen/unit/{module.rs => compiler.rs} | 265 +++++++++++++----- comp-be/src/codegen/unit/decl/expr.rs | 4 +- comp-be/src/codegen/unit/decl/mod.rs | 13 +- comp-be/src/codegen/unit/function.rs | 36 +-- comp-be/src/codegen/unit/mod.rs | 6 +- comp-be/src/fmt.rs | 13 +- comp-be/src/ty/aggregate.rs | 8 +- comp-be/src/ty/mod.rs | 12 +- comp-be/src/ty/record.rs | 12 +- comp-be/src/ty/variant.rs | 10 +- main.aat | 7 +- main.aat.bak | 6 + parser/src/ast.rs | 9 +- parser/src/parser/expression.rs | 8 +- parser/src/tests.rs | 103 ++++--- 33 files changed, 488 insertions(+), 301 deletions(-) rename comp-be/src/codegen/unit/{module.rs => compiler.rs} (50%) create mode 100644 main.aat.bak diff --git a/comp-be/src/codegen/builder/branch.rs b/comp-be/src/codegen/builder/branch.rs index 8356ca4..b9c3c8f 100644 --- a/comp-be/src/codegen/builder/branch.rs +++ b/comp-be/src/codegen/builder/branch.rs @@ -1,12 +1,12 @@ -use crate::codegen::unit::ModuleContext; +use crate::codegen::unit::CompilerContext; use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMValueRef}; -pub fn branch(module: &ModuleContext, block: LLVMBasicBlockRef) -> LLVMValueRef { +pub fn branch(module: &CompilerContext, block: LLVMBasicBlockRef) -> LLVMValueRef { module.llvm_builder.build_br(block) } pub fn cond_branch( - module: &ModuleContext, + module: &CompilerContext, cond: LLVMValueRef, then_block: LLVMBasicBlockRef, else_block: LLVMBasicBlockRef, diff --git a/comp-be/src/codegen/builder/cast.rs b/comp-be/src/codegen/builder/cast.rs index 074e9fb..425ba55 100644 --- a/comp-be/src/codegen/builder/cast.rs +++ b/comp-be/src/codegen/builder/cast.rs @@ -1,12 +1,12 @@ use crate::{ - codegen::{unit::ModuleContext, ValueTypePair}, + codegen::{unit::CompilerContext, ValueTypePair}, ty::variant::VariantType, ty::LLVMTyInCtx, }; use llvm_sys_wrapper::{LLVMTypeRef, LLVMValueRef}; use parser::ast::PrimitiveType; -pub fn zext(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn zext(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder.build_zext(*val, ty.llvm_ty_in_ctx(ctx)), ty, @@ -14,7 +14,7 @@ pub fn zext(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn trunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn trunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder.build_trunc(*val, ty.llvm_ty_in_ctx(ctx)), ty, @@ -22,7 +22,7 @@ pub fn trunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Val .into() } -pub fn ftrunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftrunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_fp_trunc(*val, ty.llvm_ty_in_ctx(ctx)), @@ -31,7 +31,7 @@ pub fn ftrunc(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn itop(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn itop(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_int_to_ptr(*val, ty.llvm_ty_in_ctx(ctx)), @@ -40,7 +40,7 @@ pub fn itop(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn ptoi(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ptoi(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_ptr_to_int(*val, ty.llvm_ty_in_ctx(ctx)), @@ -49,7 +49,7 @@ pub fn ptoi(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn stof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn stof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_si_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), @@ -58,7 +58,7 @@ pub fn stof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn utof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn utof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_ui_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), @@ -67,7 +67,7 @@ pub fn utof(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn ftos(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftos(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_fp_to_si(*val, ty.llvm_ty_in_ctx(ctx)), @@ -76,7 +76,7 @@ pub fn ftos(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn ftou(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftou(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder .build_fp_to_ui(*val, ty.llvm_ty_in_ctx(ctx)), @@ -85,11 +85,11 @@ pub fn ftou(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> Valu .into() } -pub fn bitcast(ctx: &ModuleContext, val: ValueTypePair, ty: &dyn LLVMTyInCtx) -> LLVMValueRef { +pub fn bitcast(ctx: &CompilerContext, val: ValueTypePair, ty: &dyn LLVMTyInCtx) -> LLVMValueRef { ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)) } -pub fn bitcast_ty(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn bitcast_ty(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { ( ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)), ty, @@ -98,7 +98,7 @@ pub fn bitcast_ty(ctx: &ModuleContext, val: ValueTypePair, ty: &PrimitiveType) - } pub fn child_to_parent( - ctx: &ModuleContext, + ctx: &CompilerContext, val: ValueTypePair, parent: &VariantType, ) -> LLVMValueRef { @@ -108,6 +108,6 @@ pub fn child_to_parent( )) } -pub fn bitcast_to(ctx: &ModuleContext, val: LLVMValueRef, ty: LLVMTypeRef) -> LLVMValueRef { +pub fn bitcast_to(ctx: &CompilerContext, val: LLVMValueRef, ty: LLVMTypeRef) -> LLVMValueRef { ctx.llvm_builder.build_bitcast(val, ty) } diff --git a/comp-be/src/codegen/builder/core.rs b/comp-be/src/codegen/builder/core.rs index 57098d7..cef1704 100644 --- a/comp-be/src/codegen/builder/core.rs +++ b/comp-be/src/codegen/builder/core.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - unit::{function::Func, ModuleContext}, + unit::{function::Func, CompilerContext}, ValueTypePair, }, ty::{LLVMTyInCtx, TypeKind}, @@ -8,28 +8,28 @@ use crate::{ use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMTypeRef, LLVMValueRef}; use parser::ast::{IntSize, PrimitiveType}; -pub fn load(ctx: &ModuleContext, pointer: LLVMValueRef) -> LLVMValueRef { +pub fn load(ctx: &CompilerContext, pointer: LLVMValueRef) -> LLVMValueRef { ctx.llvm_builder.build_load(pointer) } -pub fn load_ty(ctx: &ModuleContext, pointer: LLVMValueRef, ty: TypeKind) -> ValueTypePair { +pub fn load_ty(ctx: &CompilerContext, pointer: LLVMValueRef, ty: TypeKind) -> ValueTypePair { (ctx.llvm_builder.build_load(pointer), ty).into() } -pub fn load_prim(ctx: &ModuleContext, pointer: LLVMValueRef, ty: PrimitiveType) -> ValueTypePair { +pub fn load_prim(ctx: &CompilerContext, pointer: LLVMValueRef, ty: PrimitiveType) -> ValueTypePair { (ctx.llvm_builder.build_load(pointer), ty).into() } -pub fn store(ctx: &ModuleContext, value: LLVMValueRef, pointer: LLVMValueRef) -> LLVMValueRef { +pub fn store(ctx: &CompilerContext, value: LLVMValueRef, pointer: LLVMValueRef) -> LLVMValueRef { ctx.llvm_builder.build_store(value, pointer) } -pub fn struct_gep(ctx: &ModuleContext, pointer: LLVMValueRef, index: u32) -> LLVMValueRef { +pub fn struct_gep(ctx: &CompilerContext, pointer: LLVMValueRef, index: u32) -> LLVMValueRef { ctx.llvm_builder.build_struct_gep(pointer, index) } pub fn struct_gep_with_name( - ctx: &ModuleContext, + ctx: &CompilerContext, pointer: LLVMValueRef, index: u32, name: &str, @@ -39,7 +39,7 @@ pub fn struct_gep_with_name( } pub fn inbounds_gep( - ctx: &ModuleContext, + ctx: &CompilerContext, pointer: LLVMValueRef, indices: &mut Vec, ) -> LLVMValueRef { @@ -47,24 +47,28 @@ pub fn inbounds_gep( .build_inbounds_gep(pointer, indices.as_mut_slice()) } -pub fn alloca(ctx: &ModuleContext, ty: LLVMTypeRef) -> LLVMValueRef { +pub fn alloca(ctx: &CompilerContext, ty: LLVMTypeRef) -> LLVMValueRef { ctx.llvm_builder.build_alloca(ty) } -pub fn alloca_with_name(ctx: &ModuleContext, ty: LLVMTypeRef, name: &str) -> LLVMValueRef { +pub fn alloca_with_name(ctx: &CompilerContext, ty: LLVMTypeRef, name: &str) -> LLVMValueRef { ctx.llvm_builder.build_alloca_with_name(ty, name) } -pub fn alloca_ty(ctx: &ModuleContext, ty: &PrimitiveType) -> LLVMValueRef { +pub fn alloca_ty(ctx: &CompilerContext, ty: &PrimitiveType) -> LLVMValueRef { ctx.llvm_builder.build_alloca(ty.llvm_ty_in_ctx(ctx)) } -pub fn alloca_with_name_ty(ctx: &ModuleContext, ty: &PrimitiveType, name: &str) -> LLVMValueRef { +pub fn alloca_with_name_ty(ctx: &CompilerContext, ty: &PrimitiveType, name: &str) -> LLVMValueRef { ctx.llvm_builder .build_alloca_with_name(ty.llvm_ty_in_ctx(ctx), name) } -pub fn call(ctx: &ModuleContext, func: &Func, call_args: &mut Vec) -> ValueTypePair { +pub fn call( + ctx: &CompilerContext, + func: &Func, + call_args: &mut Vec, +) -> ValueTypePair { ( ctx.llvm_builder .build_call(func.as_ref(), call_args.as_mut()), @@ -73,7 +77,7 @@ pub fn call(ctx: &ModuleContext, func: &Func, call_args: &mut Vec) .into() } -pub fn extract_i8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits8), @@ -81,7 +85,7 @@ pub fn extract_i8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Val .into() } -pub fn extract_i16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits16), @@ -89,7 +93,7 @@ pub fn extract_i16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn extract_i32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits32), @@ -97,7 +101,7 @@ pub fn extract_i32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn extract_i64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_i64(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::Int(IntSize::Bits64), @@ -105,7 +109,7 @@ pub fn extract_i64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn extract_u8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits8), @@ -113,7 +117,7 @@ pub fn extract_u8(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Val .into() } -pub fn extract_u16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits16), @@ -121,7 +125,7 @@ pub fn extract_u16(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn extract_u32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits32), @@ -129,7 +133,7 @@ pub fn extract_u32(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn extract_u64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { +pub fn extract_u64(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), PrimitiveType::UInt(IntSize::Bits64), @@ -137,14 +141,14 @@ pub fn extract_u64(ctx: &ModuleContext, agg_val: LLVMValueRef, index: u32) -> Va .into() } -pub fn ret(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { +pub fn ret(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { (ctx.llvm_builder.build_ret(*val), val.prim()).into() } -pub fn ret_void(ctx: &ModuleContext) { +pub fn ret_void(ctx: &CompilerContext) { ctx.llvm_builder.build_ret_void(); } -pub fn pos_at_end(ctx: &ModuleContext, bb: LLVMBasicBlockRef) { +pub fn pos_at_end(ctx: &CompilerContext, bb: LLVMBasicBlockRef) { ctx.llvm_builder.position_at_end(bb); } diff --git a/comp-be/src/codegen/builder/op.rs b/comp-be/src/codegen/builder/op.rs index 0a46dbc..84b8480 100644 --- a/comp-be/src/codegen/builder/op.rs +++ b/comp-be/src/codegen/builder/op.rs @@ -1,20 +1,20 @@ -use crate::codegen::{unit::ModuleContext, ValueTypePair}; +use crate::codegen::{unit::CompilerContext, ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; use parser::ast::PrimitiveType; -pub fn neg(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { +pub fn neg(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { (ctx.llvm_builder.build_neg(*val), val.prim()).into() } -pub fn fneg(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { +pub fn fneg(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { (ctx.llvm_builder.build_fneg(*val), val.prim()).into() } -pub fn not(ctx: &ModuleContext, val: ValueTypePair) -> ValueTypePair { +pub fn not(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { (ctx.llvm_builder.build_not(*val), val.prim()).into() } -pub fn ieq(ctx: &ModuleContext, lhs: LLVMValueRef, rhs: LLVMValueRef) -> ValueTypePair { +pub fn ieq(ctx: &CompilerContext, lhs: LLVMValueRef, rhs: LLVMValueRef) -> ValueTypePair { ( ctx.llvm_builder.build_icmp_eq(lhs, rhs), PrimitiveType::Bool, diff --git a/comp-be/src/codegen/builder/ty.rs b/comp-be/src/codegen/builder/ty.rs index 7628bca..92db37e 100644 --- a/comp-be/src/codegen/builder/ty.rs +++ b/comp-be/src/codegen/builder/ty.rs @@ -1,44 +1,44 @@ -use crate::{codegen::unit::ModuleContext, ty::LLVMTyInCtx}; +use crate::{codegen::unit::CompilerContext, ty::LLVMTyInCtx}; use llvm_sys_wrapper::LLVMTypeRef; -pub fn pointer(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { +pub fn pointer(ctx: &CompilerContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { ctx.llvm_context.PointerType(ty.llvm_ty_in_ctx(ctx)) } -pub fn slice_type(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { +pub fn slice_type(ctx: &CompilerContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { ctx.llvm_context .StructType(&mut vec![slice_ptr(ctx, ty), i32(ctx)], false) .as_ref() } -pub fn pointer_to(ctx: &ModuleContext, ty: LLVMTypeRef) -> LLVMTypeRef { +pub fn pointer_to(ctx: &CompilerContext, ty: LLVMTypeRef) -> LLVMTypeRef { ctx.llvm_context.PointerType(ty) } -pub fn array(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx, count: u32) -> LLVMTypeRef { +pub fn array(ctx: &CompilerContext, ty: &dyn LLVMTyInCtx, count: u32) -> LLVMTypeRef { ctx.llvm_context.ArrayType(ty.llvm_ty_in_ctx(ctx), count) } -pub fn slice(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { +pub fn slice(ctx: &CompilerContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { ctx.llvm_context.ArrayType(ty.llvm_ty_in_ctx(ctx), 0) } -pub fn slice_ptr(ctx: &ModuleContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { +pub fn slice_ptr(ctx: &CompilerContext, ty: &dyn LLVMTyInCtx) -> LLVMTypeRef { pointer_to(ctx, slice(ctx, ty)) } -pub fn i8(ctx: &ModuleContext) -> LLVMTypeRef { +pub fn i8(ctx: &CompilerContext) -> LLVMTypeRef { ctx.llvm_context.Int8Type() } -pub fn i16(ctx: &ModuleContext) -> LLVMTypeRef { +pub fn i16(ctx: &CompilerContext) -> LLVMTypeRef { ctx.llvm_context.Int16Type() } -pub fn i32(ctx: &ModuleContext) -> LLVMTypeRef { +pub fn i32(ctx: &CompilerContext) -> LLVMTypeRef { ctx.llvm_context.Int32Type() } -pub fn i64(ctx: &ModuleContext) -> LLVMTypeRef { +pub fn i64(ctx: &CompilerContext) -> LLVMTypeRef { ctx.llvm_context.Int64Type() } diff --git a/comp-be/src/codegen/builder/value.rs b/comp-be/src/codegen/builder/value.rs index 16e4e7d..06df75a 100644 --- a/comp-be/src/codegen/builder/value.rs +++ b/comp-be/src/codegen/builder/value.rs @@ -1,20 +1,20 @@ -use crate::codegen::{unit::ModuleContext, ValueTypePair}; +use crate::codegen::{unit::CompilerContext, ValueTypePair}; use llvm_sys_wrapper::{LLVMValueRef, Struct}; use parser::ast::{FloatSize, IntSize, PrimitiveType}; -pub fn t(ctx: &ModuleContext) -> ValueTypePair { +pub fn t(ctx: &CompilerContext) -> ValueTypePair { (ctx.llvm_context.SInt1(1), PrimitiveType::Bool).into() } -pub fn f(ctx: &ModuleContext) -> ValueTypePair { +pub fn f(ctx: &CompilerContext) -> ValueTypePair { (ctx.llvm_context.SInt1(0), PrimitiveType::Bool).into() } -pub fn char(ctx: &ModuleContext, c: char) -> ValueTypePair { +pub fn char(ctx: &CompilerContext, c: char) -> ValueTypePair { (ctx.llvm_context.SInt8(c as u64), PrimitiveType::Char).into() } -pub fn s8(ctx: &ModuleContext, value: i8) -> ValueTypePair { +pub fn s8(ctx: &CompilerContext, value: i8) -> ValueTypePair { ( ctx.llvm_context.SInt8(value as u64), PrimitiveType::Int(IntSize::Bits8), @@ -22,7 +22,7 @@ pub fn s8(ctx: &ModuleContext, value: i8) -> ValueTypePair { .into() } -pub fn s16(ctx: &ModuleContext, value: i16) -> ValueTypePair { +pub fn s16(ctx: &CompilerContext, value: i16) -> ValueTypePair { ( ctx.llvm_context.SInt16(value as u64), PrimitiveType::Int(IntSize::Bits16), @@ -30,7 +30,7 @@ pub fn s16(ctx: &ModuleContext, value: i16) -> ValueTypePair { .into() } -pub fn s32(ctx: &ModuleContext, value: i32) -> ValueTypePair { +pub fn s32(ctx: &CompilerContext, value: i32) -> ValueTypePair { ( ctx.llvm_context.SInt32(value as u64), PrimitiveType::Int(IntSize::Bits32), @@ -38,7 +38,7 @@ pub fn s32(ctx: &ModuleContext, value: i32) -> ValueTypePair { .into() } -pub fn s64(ctx: &ModuleContext, value: i64) -> ValueTypePair { +pub fn s64(ctx: &CompilerContext, value: i64) -> ValueTypePair { ( ctx.llvm_context.SInt64(value as u64), PrimitiveType::Int(IntSize::Bits64), @@ -46,7 +46,7 @@ pub fn s64(ctx: &ModuleContext, value: i64) -> ValueTypePair { .into() } -pub fn u8(ctx: &ModuleContext, value: u8) -> ValueTypePair { +pub fn u8(ctx: &CompilerContext, value: u8) -> ValueTypePair { ( ctx.llvm_context.UInt8(value as u64), PrimitiveType::UInt(IntSize::Bits8), @@ -54,7 +54,7 @@ pub fn u8(ctx: &ModuleContext, value: u8) -> ValueTypePair { .into() } -pub fn u16(ctx: &ModuleContext, value: u16) -> ValueTypePair { +pub fn u16(ctx: &CompilerContext, value: u16) -> ValueTypePair { ( ctx.llvm_context.UInt16(value as u64), PrimitiveType::UInt(IntSize::Bits16), @@ -62,7 +62,7 @@ pub fn u16(ctx: &ModuleContext, value: u16) -> ValueTypePair { .into() } -pub fn u32(ctx: &ModuleContext, value: u32) -> ValueTypePair { +pub fn u32(ctx: &CompilerContext, value: u32) -> ValueTypePair { ( ctx.llvm_context.UInt32(value as u64), PrimitiveType::UInt(IntSize::Bits32), @@ -70,7 +70,7 @@ pub fn u32(ctx: &ModuleContext, value: u32) -> ValueTypePair { .into() } -pub fn u64(ctx: &ModuleContext, value: u64) -> ValueTypePair { +pub fn u64(ctx: &CompilerContext, value: u64) -> ValueTypePair { ( ctx.llvm_context.UInt64(value), PrimitiveType::UInt(IntSize::Bits64), @@ -79,7 +79,7 @@ pub fn u64(ctx: &ModuleContext, value: u64) -> ValueTypePair { } pub fn slice( - ctx: &ModuleContext, + ctx: &CompilerContext, pointer: LLVMValueRef, ty: PrimitiveType, len: u32, @@ -91,7 +91,7 @@ pub fn slice( .into() } -pub fn sint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { +pub fn sint(ctx: &CompilerContext, size: IntSize, value: u64) -> ValueTypePair { ( match size { IntSize::Bits8 => ctx.llvm_context.SInt8(value), @@ -104,7 +104,7 @@ pub fn sint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { .into() } -pub fn uint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { +pub fn uint(ctx: &CompilerContext, size: IntSize, value: u64) -> ValueTypePair { ( match size { IntSize::Bits8 => ctx.llvm_context.UInt8(value), @@ -117,7 +117,7 @@ pub fn uint(ctx: &ModuleContext, size: IntSize, value: u64) -> ValueTypePair { .into() } -pub fn floating(ctx: &ModuleContext, size: FloatSize, value: f64) -> ValueTypePair { +pub fn floating(ctx: &CompilerContext, size: FloatSize, value: f64) -> ValueTypePair { ( match size { FloatSize::Bits32 => ctx.llvm_context.Float(value), @@ -128,7 +128,7 @@ pub fn floating(ctx: &ModuleContext, size: FloatSize, value: f64) -> ValueTypePa .into() } -pub fn str(ctx: &ModuleContext, string: &str) -> ValueTypePair { +pub fn str(ctx: &CompilerContext, string: &str) -> ValueTypePair { ( ctx.llvm_builder.build_global_string_ptr(string), PrimitiveType::Str, diff --git a/comp-be/src/codegen/expr/compare.rs b/comp-be/src/codegen/expr/compare.rs index ff0f703..a896f42 100644 --- a/comp-be/src/codegen/expr/compare.rs +++ b/comp-be/src/codegen/expr/compare.rs @@ -1,10 +1,10 @@ -use crate::codegen::{unit::ModuleContext, ValueTypePair}; +use crate::codegen::{unit::CompilerContext, ValueTypePair}; use parser::ast::PrimitiveType; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_compare_float( - module: &ModuleContext, + module: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -23,7 +23,7 @@ pub fn codegen_compare_float( } pub fn codegen_compare_signed( - module: &ModuleContext, + module: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -42,7 +42,7 @@ pub fn codegen_compare_signed( } pub fn codegen_compare_unsigned( - module: &ModuleContext, + module: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, diff --git a/comp-be/src/codegen/expr/const_expr.rs b/comp-be/src/codegen/expr/const_expr.rs index 3c99648..cd7cb12 100644 --- a/comp-be/src/codegen/expr/const_expr.rs +++ b/comp-be/src/codegen/expr/const_expr.rs @@ -1,7 +1,7 @@ use crate::{ codegen::{ builder::value, - unit::{ModuleContext, Mutability, Slot}, + unit::{CompilerContext, Mutability, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, @@ -9,7 +9,7 @@ use crate::{ }; use parser::ast::{AtomKind, Expression, PrimitiveType, AST}; -pub fn const_atom(ctx: &ModuleContext, atom: &AtomKind) -> Option { +pub fn const_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option { match atom { AtomKind::StringLiteral(string) => Some(value::str(ctx, string.as_ref())), AtomKind::CharLiteral(ch) => Some(value::char(ctx, *ch)), @@ -40,7 +40,7 @@ pub fn const_atom(ctx: &ModuleContext, atom: &AtomKind) -> Option } } -fn fold_expression(ctx: &ModuleContext, expr: &Expression) -> Option { +fn fold_expression(ctx: &CompilerContext, expr: &Expression) -> Option { match expr { Expression::Atom(atom) => const_atom(ctx, atom), _ => panic!("ICE fold_expression {:?}", expr), diff --git a/comp-be/src/codegen/expr/eqne.rs b/comp-be/src/codegen/expr/eqne.rs index 37617ff..46359f9 100644 --- a/comp-be/src/codegen/expr/eqne.rs +++ b/comp-be/src/codegen/expr/eqne.rs @@ -1,10 +1,10 @@ -use crate::codegen::{unit::ModuleContext, ValueTypePair}; +use crate::codegen::{unit::CompilerContext, ValueTypePair}; use parser::ast::PrimitiveType; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_eq_ne( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -21,7 +21,7 @@ pub fn codegen_eq_ne( } pub fn codegen_boolean( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -38,7 +38,7 @@ pub fn codegen_boolean( } pub fn codegen_eq_ne_float( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, diff --git a/comp-be/src/codegen/expr/math.rs b/comp-be/src/codegen/expr/math.rs index 4ebfcf5..50ea889 100644 --- a/comp-be/src/codegen/expr/math.rs +++ b/comp-be/src/codegen/expr/math.rs @@ -1,10 +1,10 @@ -use crate::codegen::{unit::ModuleContext, ValueTypePair}; +use crate::codegen::{unit::CompilerContext, ValueTypePair}; use parser::ast::{FloatSize, IntSize, PrimitiveType}; use llvm_sys_wrapper::LLVMValueRef; pub fn codegen_float_ops( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -25,7 +25,7 @@ pub fn codegen_float_ops( } pub fn codegen_signed_ops( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -46,7 +46,7 @@ pub fn codegen_signed_ops( } pub fn codegen_unsigned_ops( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, diff --git a/comp-be/src/codegen/expr/mod.rs b/comp-be/src/codegen/expr/mod.rs index e8b9f9f..5963111 100644 --- a/comp-be/src/codegen/expr/mod.rs +++ b/comp-be/src/codegen/expr/mod.rs @@ -10,7 +10,7 @@ use math::{codegen_float_ops, codegen_signed_ops, codegen_unsigned_ops}; pub mod const_expr; use crate::{ - codegen::{unit::ModuleContext, CompileError, GenRes, ValueTypePair}, + codegen::{unit::CompilerContext, CompileError, GenRes, ValueTypePair}, fmt::AatbeFmt, }; use parser::ast::{Expression, FloatSize, IntSize, PrimitiveType}; @@ -18,7 +18,7 @@ use parser::ast::{Expression, FloatSize, IntSize, PrimitiveType}; use llvm_sys_wrapper::LLVMValueRef; fn dispatch_bool( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -31,7 +31,7 @@ fn dispatch_bool( } fn dispatch_signed( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -46,7 +46,7 @@ fn dispatch_signed( } fn dispatch_float( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -61,7 +61,7 @@ fn dispatch_float( } fn dispatch_unsigned( - ctx: &ModuleContext, + ctx: &CompilerContext, op: &String, lhs: LLVMValueRef, rhs: LLVMValueRef, @@ -76,7 +76,7 @@ fn dispatch_unsigned( } pub fn codegen_binary( - module: &mut ModuleContext, + module: &mut CompilerContext, op: &String, lhs_expr: &Expression, rhs_expr: &Expression, diff --git a/comp-be/src/codegen/mangle_v1.rs b/comp-be/src/codegen/mangle_v1.rs index f17d592..f3da7d8 100644 --- a/comp-be/src/codegen/mangle_v1.rs +++ b/comp-be/src/codegen/mangle_v1.rs @@ -1,15 +1,14 @@ -use crate::codegen::AatbeModule; - use parser::ast::{AtomKind, Expression, FloatSize, FunctionType, IntSize, PrimitiveType}; -use super::unit::ModuleContext; +use super::unit::CompilerContext; +use crate::prefix; pub trait NameMangler { - fn mangle(&self, ctx: &ModuleContext) -> String; + fn mangle(&self, ctx: &CompilerContext) -> String; } impl NameMangler for Expression { - fn mangle(&self, ctx: &ModuleContext) -> String { + fn mangle(&self, ctx: &CompilerContext) -> String { match self { Expression::Function { name, @@ -27,7 +26,7 @@ impl NameMangler for Expression { if !attributes.contains(&String::from("entry")) { format!( "{}{}{}", - name, + prefix!(ctx, name.clone()).join("__"), if type_names.len() > 0 { format!("G{}", type_names.len()) } else { @@ -51,7 +50,7 @@ impl NameMangler for Expression { } impl NameMangler for AtomKind { - fn mangle(&self, ctx: &ModuleContext) -> String { + fn mangle(&self, ctx: &CompilerContext) -> String { match self { AtomKind::StringLiteral(lit) => format!("{:?}", lit), AtomKind::Ident(id) => id.clone(), @@ -67,7 +66,7 @@ impl NameMangler for AtomKind { } impl NameMangler for FunctionType { - fn mangle(&self, ctx: &ModuleContext) -> String { + fn mangle(&self, ctx: &CompilerContext) -> String { let params_mangled = self .params .iter() @@ -84,7 +83,7 @@ impl NameMangler for FunctionType { } impl NameMangler for PrimitiveType { - fn mangle(&self, ctx: &ModuleContext) -> String { + fn mangle(&self, ctx: &CompilerContext) -> String { match self { PrimitiveType::TypeRef(ty) => ty.clone(), PrimitiveType::Function(ty) => ty.mangle(ctx), @@ -120,7 +119,7 @@ impl NameMangler for PrimitiveType { } impl NameMangler for IntSize { - fn mangle(&self, _ctx: &ModuleContext) -> String { + fn mangle(&self, _ctx: &CompilerContext) -> String { match self { IntSize::Bits8 => String::from("8"), IntSize::Bits16 => String::from("16"), @@ -131,7 +130,7 @@ impl NameMangler for IntSize { } impl NameMangler for FloatSize { - fn mangle(&self, _ctx: &ModuleContext) -> String { + fn mangle(&self, _ctx: &CompilerContext) -> String { match self { FloatSize::Bits32 => String::from("32"), FloatSize::Bits64 => String::from("64"), diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index 964a5a3..cd2b0f2 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -15,7 +15,7 @@ use crate::{ mangle_v1::NameMangler, unit::{ alloc_variable, declare_and_compile_function, declare_function, init_record, - store_value, ModuleUnit, Slot, + store_value, CompilerUnit, Slot, }, CompileError, Scope, ValueTypePair, }, @@ -90,7 +90,7 @@ impl AatbeModule { let root_builder = Builder::new_in_context(self.llvm_context.as_ref()); - ModuleUnit::new( + CompilerUnit::new( base_cu.path().clone(), box main_ast, &self.llvm_context, @@ -117,7 +117,7 @@ impl AatbeModule { CompilationUnit::new(path) }*/ - pub fn decl_pass(&mut self, root_module: &mut ModuleUnit) { + pub fn decl_pass(&mut self, root_module: &mut CompilerUnit) { /*match ast { AST::Constant { .. } | AST::Global { .. } => {} @@ -588,7 +588,7 @@ impl AatbeModule { }*/ } - pub fn codegen_pass(&mut self, root_module: &mut ModuleUnit) -> Option { + pub fn codegen_pass(&mut self, root_module: &mut CompilerUnit) -> Option { todo!() /*match ast { AST::Constant { diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 71449b5..df5e444 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -69,11 +69,11 @@ impl Scope { } } - pub fn func_by_name(&self, name: &String) -> Option> { + pub fn func_by_name(&self, name: &Vec) -> Option> { self.functions.get(name).cloned() } - pub fn add_function(&mut self, name: &String, func: Func) { + pub fn add_function(&mut self, name: &Vec, func: Func) { if !self.functions.contains_key(name) { self.functions.insert(name.clone(), RefCell::new(vec![])); } @@ -98,6 +98,10 @@ impl Scope { self.fdir.clone() } + pub fn name(&self) -> String { + self.name.clone() + } + /*pub fn bb(&self, module: &AatbeModule, name: &String) -> Option { let func = self.function.as_ref()?; diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index 8d4bfe1..d0dd9a5 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -3,11 +3,11 @@ use parser::ast::{AtomKind, Boolean}; use crate::codegen::{ builder::value, expr::const_expr::const_atom, - unit::{cg::expr, ModuleContext}, + unit::{cg::expr, CompilerContext}, ValueTypePair, }; -pub fn cg(atom: &AtomKind, ctx: &ModuleContext) -> Option { +pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { match atom { AtomKind::Parenthesized(expr) => expr::cg(expr, ctx), AtomKind::Unit => None, diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index 1d5cddf..213c4c6 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -1,19 +1,20 @@ use std::borrow::Borrow; -use parser::ast::{AtomKind, Expression, PrimitiveType}; +use parser::ast::{AtomKind, Expression, Ident, PrimitiveType}; use crate::{ codegen::{ builder::core, - unit::{cg::expr, function::find_function, ModuleContext, Query, QueryResponse}, + unit::{cg::expr, function::find_function, CompilerContext, Query, QueryResponse}, ValueTypePair, }, fmt::AatbeFmt, + prefix, }; use log::*; -pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { if let Expression::Call { name, types: _, @@ -64,13 +65,19 @@ pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { return None; } - if let QueryResponse::FunctionGroup(Some(group)) = ctx.query(Query::FunctionGroup(name)) { - if let Some(func) = find_function(group, &call_types) { - Some(core::call( - ctx, - func.upgrade().expect("ICE").borrow(), - &mut call_args, - )) + if let Ident::Local(name) = name { + if let QueryResponse::FunctionGroup(Some(group)) = + ctx.query(Query::FunctionGroup(prefix!(call ctx, name.clone()))) + { + if let Some(func) = find_function(group, &call_types) { + Some(core::call( + ctx, + func.upgrade().expect("ICE").borrow(), + &mut call_args, + )) + } else { + todo!(); + } } else { todo!(); } diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 9b56613..9f7154c 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -3,12 +3,12 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ unit::{ cg::{atom, call}, - declare_and_compile_function, Message, ModuleContext, + declare_and_compile_function, CompilerContext, Message, }, ValueTypePair, }; -pub fn cg(expr: &Expression, ctx: &ModuleContext) -> Option { +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { Expression::Call { .. } => call::cg(expr, ctx), Expression::Atom(atom) => atom::cg(atom, ctx), diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs index bd0d95f..e257bb2 100644 --- a/comp-be/src/codegen/unit/cg/mod.rs +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -1,15 +1,22 @@ use llvm_sys_wrapper::LLVMValueRef; use parser::ast::AST; -use super::ModuleContext; +use super::{CompilerContext, Message}; pub mod atom; pub mod call; pub mod expr; -pub fn cg(ast: &AST, ctx: &ModuleContext) -> Option { +pub fn cg(ast: &AST, ctx: &CompilerContext) -> Option { match ast { AST::Expr(expr) => expr::cg(expr, ctx).map(|e| *e), + AST::File(nodes) => nodes.iter().fold(None, |_, n| cg(n, ctx)), + AST::Module(name, ast) => { + ctx.dispatch(Message::RestoreModuleScope(name.clone())); + let ret = cg(ast, ctx); + ctx.dispatch(Message::ExitScope); + ret + } _ => todo!("{:?}", ast), } } diff --git a/comp-be/src/codegen/unit/module.rs b/comp-be/src/codegen/unit/compiler.rs similarity index 50% rename from comp-be/src/codegen/unit/module.rs rename to comp-be/src/codegen/unit/compiler.rs index 09e0564..78ad53d 100644 --- a/comp-be/src/codegen/unit/module.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -1,4 +1,10 @@ -use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Weak}; +use std::{ + cell::RefCell, + collections::HashMap, + path::PathBuf, + rc::Weak, + sync::atomic::{AtomicUsize, Ordering}, +}; use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; use parser::ast::{Expression, FunctionType, AST}; @@ -22,18 +28,21 @@ pub enum FunctionVisibility { Export, } -pub enum Message<'cmd> { - RegisterFunction(&'cmd String, Func, FunctionVisibility), +pub enum Message { + DeclareFunction(Vec, Func, FunctionVisibility), EnterFunctionScope((String, FunctionType)), + EnterModuleScope(String), + ExitModuleScope(String), + RestoreModuleScope(String), EnterAnonymousScope, ExitScope, } -impl std::fmt::Debug for Message<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl std::fmt::Debug for Message { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - Message::RegisterFunction(name, ty, vis) => f - .debug_tuple("RegisterFunction") + Message::DeclareFunction(name, ty, vis) => f + .debug_tuple("DeclareFunction") .field(name) .field(&AatbeFmt::fmt(ty)) .field(vis) @@ -43,6 +52,15 @@ impl std::fmt::Debug for Message<'_> { .field(&func.0) .field(&AatbeFmt::fmt(&func.1)) .finish(), + Message::EnterModuleScope(name) => { + f.debug_tuple("EnterModuleScope").field(&name).finish() + } + Message::ExitModuleScope(name) => { + f.debug_tuple("ExitModuleScope").field(&name).finish() + } + Message::RestoreModuleScope(name) => { + f.debug_tuple("RestoreModuleScope").field(&name).finish() + } Message::EnterAnonymousScope => write!(f, "EnterAnonymousScope"), Message::ExitScope => write!(f, "ExitScope"), } @@ -50,8 +68,9 @@ impl std::fmt::Debug for Message<'_> { } pub enum Query<'cmd> { - Function((&'cmd String, &'cmd FunctionType)), - FunctionGroup(&'cmd String), + Function((Vec, &'cmd FunctionType)), + FunctionGroup(Vec), + Prefix, } impl std::fmt::Debug for Query<'_> { @@ -59,10 +78,11 @@ impl std::fmt::Debug for Query<'_> { match self { Query::Function(func) => f .debug_tuple("Function") - .field(func.0) + .field(&func.0.join("::")) .field(&AatbeFmt::fmt(func.1)) .finish(), Query::FunctionGroup(name) => f.debug_tuple("FunctionGroup").field(name).finish(), + Query::Prefix => write!(f, "Prefix"), } } } @@ -70,6 +90,7 @@ impl std::fmt::Debug for Query<'_> { pub enum QueryResponse { Function(Option>), FunctionGroup(Option>), + Prefix(Vec), } impl std::fmt::Debug for QueryResponse { @@ -93,11 +114,16 @@ impl std::fmt::Debug for QueryResponse { } )) .finish(), + QueryResponse::Prefix(prefix) => f + .debug_tuple("Prefix") + .field(&format_args!("{}", prefix.join("::"))) + .finish(), } } } -pub struct ModuleContext<'ctx> { +pub struct CompilerContext<'ctx> { + pub path: PathBuf, pub llvm_context: &'ctx Context, pub llvm_module: &'ctx Module, pub llvm_builder: &'ctx Builder, @@ -106,15 +132,20 @@ pub struct ModuleContext<'ctx> { query: &'ctx dyn Fn(Query) -> QueryResponse, } -impl<'ctx> ModuleContext<'ctx> { - pub fn new( +impl<'ctx> CompilerContext<'ctx> { + pub fn new

( + path: P, llvm_context: &'ctx Context, llvm_module: &'ctx Module, llvm_builder: &'ctx Builder, dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, - ) -> Self { + ) -> Self + where + P: Into, + { Self { + path: path.into(), llvm_context, llvm_module, llvm_builder, @@ -126,6 +157,7 @@ impl<'ctx> ModuleContext<'ctx> { fn with_builder(&'ctx self, builder: &'ctx Builder) -> Self { Self { + path: self.path.clone(), llvm_context: self.llvm_context, llvm_module: self.llvm_module, llvm_builder: builder, @@ -145,7 +177,7 @@ impl<'ctx> ModuleContext<'ctx> { pub fn in_function_scope(&self, func: (String, FunctionType), f: F) -> Option where - F: FnOnce(ModuleContext) -> Option, + F: FnOnce(CompilerContext) -> Option, { self.dispatch(Message::EnterFunctionScope(func)); let builder = Builder::new_in_context(self.llvm_context.as_ref()); @@ -156,17 +188,19 @@ impl<'ctx> ModuleContext<'ctx> { } } -pub struct ModuleUnit<'ctx> { - modules: HashMap>, +pub struct CompilerUnit<'ctx> { + modules: HashMap>, ast: Box, typectx: TypeContext, llvm_context: &'ctx Context, llvm_module: &'ctx Module, scope_stack: RefCell>, + module_scopes: RefCell>, path: PathBuf, + ident: RefCell, } -impl<'ctx> ModuleUnit<'ctx> { +impl<'ctx> CompilerUnit<'ctx> { pub fn new

( path: P, ast: Box, @@ -184,6 +218,8 @@ impl<'ctx> ModuleUnit<'ctx> { modules: HashMap::new(), typectx: TypeContext::new(), scope_stack: RefCell::new(vec![]), + module_scopes: RefCell::new(HashMap::new()), + ident: RefCell::new(0), } } @@ -193,32 +229,63 @@ impl<'ctx> ModuleUnit<'ctx> { { self.enter_root_scope(); f(self); + println!("└── Exit Root Scope"); self.exit_scope(); } fn enter_root_scope(&self) { - trace!("Enter root scope"); + println!("Enter Root Scope"); self.scope_stack .borrow_mut() .push(Scope::with_fdir(self.path.clone())); } + fn enter_anonymous_scope(&self) { + print!("{}", "│ ".repeat(*self.ident.borrow())); + println!("├── Enter Scope"); + self.scope_stack.borrow_mut().push(Scope::new()); + } + fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { - trace!("Enter function scope {:?}", func.0); self.scope_stack .borrow_mut() .push(Scope::with_function(func, builder)); } + fn enter_module_scope(&self, name: String) { + self.scope_stack.borrow_mut().push(Scope::with_name(&name)); + } + + fn exit_module_scope(&self, name: String) { + let scope = self + .scope_stack + .borrow_mut() + .pop() + .expect("ICE Scope stack broke"); + self.module_scopes.borrow_mut().insert(name, scope); + } + + fn restore_module_scope(&self, name: String) { + let scope = self + .module_scopes + .borrow_mut() + .remove(&name) + .expect("ICE Scope stack broke"); + self.scope_stack.borrow_mut().push(scope); + } + fn exit_scope(&self) { - trace!("Exit scope"); - self.scope_stack.borrow_mut().pop(); + self.scope_stack + .borrow_mut() + .pop() + .expect("ICE Scope Stack Broke"); } fn dispatch(&self, message: Message) { - trace!("Dispatch {:?}", message); + print!("{}", "│ ".repeat(*self.ident.borrow())); match message { - Message::RegisterFunction(name, func, ty) => { + Message::DeclareFunction(ref name, ref func, ty) => { + println!("├── {:?}", message); let mut scope_stack = self.scope_stack.borrow_mut(); if ty == FunctionVisibility::Local { scope_stack.last_mut() @@ -226,28 +293,56 @@ impl<'ctx> ModuleUnit<'ctx> { scope_stack.first_mut() } .expect("ICE: Scope stack is corrupted.") - .add_function(name, func); + .add_function(&name, func.clone()); } - Message::EnterFunctionScope(func) => { + Message::EnterFunctionScope(ref func) => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; let builder = Builder::new_in_context(self.llvm_context.as_ref()); - self.enter_function_scope(func, builder); + self.enter_function_scope(func.clone(), builder); + } + Message::EnterModuleScope(ref name) => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.enter_module_scope(name.clone()) + } + Message::ExitModuleScope(ref name) => { + println!("└── {:?}", message); + *self.ident.borrow_mut() -= 1; + self.exit_module_scope(name.clone()) + } + Message::RestoreModuleScope(ref name) => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.restore_module_scope(name.clone()) + } + Message::EnterAnonymousScope => self.enter_anonymous_scope(), + Message::ExitScope => { + println!("└── {:?}", message); + *self.ident.borrow_mut() -= 1; + self.exit_scope() } - Message::EnterAnonymousScope => {} - Message::ExitScope => self.exit_scope(), } } fn query(&self, query: Query) -> QueryResponse { - trace!("Query {:?}", query); + print!("{}", "│ ".repeat(*self.ident.borrow())); + println!("├── Query {:?}", query); let response = match query { Query::Function(func) => QueryResponse::Function(self.get_func(func)), Query::FunctionGroup(name) => QueryResponse::FunctionGroup(self.get_func_group(name)), + Query::Prefix => QueryResponse::Prefix(self.get_prefix()), }; - trace!("Response {:?}", response); + print!("{}", "│ ".repeat(*self.ident.borrow())); + println!("├── Response {:?}", response); response } - pub fn push(&mut self, name: &String, module: ModuleUnit<'ctx>) -> Option> { + pub fn push( + &mut self, + name: &String, + module: CompilerUnit<'ctx>, + ) -> Option> { self.modules.insert(name.clone(), module) } @@ -260,24 +355,17 @@ impl<'ctx> ModuleUnit<'ctx> { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); - match ast { - box AST::File(ref nodes) => nodes - .iter() - .fold(Some(()), |_, ast| { - Some(decl( - ast, - &mut ModuleContext::new( - self.llvm_context, - self.llvm_module, - root_builder, - dispatch, - query, - ), - )) - }) - .unwrap(), - _ => todo!("{:?}", self.ast), - } + decl::decl( + &*ast, + &mut CompilerContext::new( + self.path.clone(), + self.llvm_context, + self.llvm_module, + root_builder, + dispatch, + query, + ), + ); } pub fn codegen(&'ctx self, root_builder: &Builder) -> Option { @@ -285,26 +373,22 @@ impl<'ctx> ModuleUnit<'ctx> { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); - match ast { - box AST::File(ref nodes) => nodes.iter().fold(None, |_, n| { - cg( - n, - &ModuleContext::new( - self.llvm_context, - self.llvm_module, - root_builder, - dispatch, - query, - ), - ) - }), - _ => todo!("{:?}", self.ast), - } + cg::cg( + &*ast, + &CompilerContext::new( + self.path.clone(), + self.llvm_context, + self.llvm_module, + root_builder, + dispatch, + query, + ), + ) } - pub fn get_func_group(&self, name: &String) -> Option> { + pub fn get_func_group(&self, name: Vec) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { - if let Some(func) = scope.func_by_name(name) { + if let Some(func) = scope.func_by_name(&name) { return Some(func); } } @@ -312,9 +396,9 @@ impl<'ctx> ModuleUnit<'ctx> { None } - pub fn get_func(&self, func: (&String, &FunctionType)) -> Option> { + pub fn get_func(&self, func: (Vec, &FunctionType)) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { - if let Some(group) = scope.func_by_name(func.0) { + if let Some(group) = scope.func_by_name(&func.0) { return find_func(group, func.1); } } @@ -325,4 +409,47 @@ impl<'ctx> ModuleUnit<'ctx> { pub fn llvm_module_ref(&self) -> &Module { &self.llvm_module } + + pub fn get_prefix(&self) -> Vec { + self.scope_stack + .borrow() + .iter() + .map(|s| s.name()) + .filter(|n| n != &String::default()) + .collect::>() + } +} + +#[macro_export] +macro_rules! prefix { + (call $ctx: expr, $name: expr) => {{ + if let crate::codegen::unit::compiler::QueryResponse::Prefix(mut prefix) = + $ctx.query(crate::codegen::unit::compiler::Query::Prefix) + { + prefix.pop(); + prefix.push($name); + prefix + } else { + panic!("PREFIX ICE") + } + }}; + ($ctx: expr, $name: expr) => {{ + if let crate::codegen::unit::compiler::QueryResponse::Prefix(mut prefix) = + $ctx.query(crate::codegen::unit::compiler::Query::Prefix) + { + prefix.push($name); + prefix + } else { + panic!("PREFIX ICE") + } + }}; + ($ctx: expr) => {{ + if let crate::codegen::unit::compiler::QueryResponse::Prefix(prefix) = + $ctx.query(crate::codegen::unit::compiler::Query::Prefix) + { + prefix + } else { + panic!("PREFIX ICE") + } + }}; } diff --git a/comp-be/src/codegen/unit/decl/expr.rs b/comp-be/src/codegen/unit/decl/expr.rs index 669427e..04e54f0 100644 --- a/comp-be/src/codegen/unit/decl/expr.rs +++ b/comp-be/src/codegen/unit/decl/expr.rs @@ -1,8 +1,8 @@ use parser::ast::Expression; -use crate::codegen::unit::{declare_function, ModuleContext}; +use crate::codegen::unit::{declare_function, CompilerContext}; -pub fn decl(expr: &Expression, ctx: &mut ModuleContext) { +pub fn decl(expr: &Expression, ctx: &mut CompilerContext) { match expr { Expression::Function { type_names, .. } if type_names.len() == 0 => { declare_function(ctx, expr) diff --git a/comp-be/src/codegen/unit/decl/mod.rs b/comp-be/src/codegen/unit/decl/mod.rs index 1cdbf32..da48c01 100644 --- a/comp-be/src/codegen/unit/decl/mod.rs +++ b/comp-be/src/codegen/unit/decl/mod.rs @@ -2,11 +2,20 @@ mod expr; use parser::ast::AST; -use super::ModuleContext; +use super::{CompilerContext, Message}; -pub fn decl(ast: &AST, ctx: &mut ModuleContext) { +pub fn decl(ast: &AST, ctx: &mut CompilerContext) { match ast { AST::Expr(expr) => expr::decl(expr, ctx), + AST::Module(name, ast) => { + ctx.dispatch(Message::EnterModuleScope(name.clone())); + super::decl(ast, ctx); + ctx.dispatch(Message::ExitModuleScope(name.clone())); + } + AST::File(nodes) => nodes + .iter() + .fold(Some(()), |_, ast| Some(decl(ast, ctx))) + .unwrap(), _ => todo!("{:?}", ast), } } diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index a245c7a..3918de2 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -3,10 +3,14 @@ use crate::{ codegen::{ builder::core, mangle_v1::NameMangler, - unit::{cg::expr, FunctionVisibility, Message, Mutability, Query, QueryResponse, Slot}, + unit::{ + cg::expr, CompilerContext, FunctionVisibility, Message, Mutability, Query, + QueryResponse, Slot, + }, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, + prefix, ty::LLVMTyInCtx, }; use llvm_sys_wrapper::Function; @@ -22,11 +26,10 @@ use parser::ast::{Expression, FunctionType, PrimitiveType}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; -use super::ModuleContext; - +#[derive(Clone)] pub struct Func { ty: FunctionType, - name: String, + ident: Vec, inner: Function, } @@ -45,14 +48,14 @@ impl AatbeFmt for &Func { } else { String::default() }, - self.name, + self.ident.join("::"), (&self.ty).fmt() ) } } pub type FuncTyMap = Vec>; -pub type FunctionMap = HashMap>; +pub type FunctionMap = HashMap, RefCell>; pub fn find_func<'a>(map: RefCell, ty: &FunctionType) -> Option> { for func in map.borrow().iter() { @@ -80,8 +83,8 @@ impl Deref for Func { } impl Func { - pub fn new(ty: FunctionType, name: String, inner: Function) -> Self { - Self { ty, name, inner } + pub fn new(ty: FunctionType, ident: Vec, inner: Function) -> Self { + Self { ty, ident, inner } } pub fn ty(&self) -> &FunctionType { @@ -130,7 +133,7 @@ impl Func { } } -pub fn declare_function(ctx: &ModuleContext, function: &Expression) { +pub fn declare_function(ctx: &CompilerContext, function: &Expression) { match function { Expression::Function { ty, @@ -143,16 +146,17 @@ pub fn declare_function(ctx: &ModuleContext, function: &Expression) { .llvm_module .get_or_add_function(&function.mangle(&ctx), ty.llvm_ty_in_ctx(&ctx)); + let name = prefix!(ctx, name.clone()); let func = Func::new(ty.clone(), name.clone(), func); if !export { - ctx.dispatch(Message::RegisterFunction( - &name, + ctx.dispatch(Message::DeclareFunction( + name, func, FunctionVisibility::Local, )); } else { - ctx.dispatch(Message::RegisterFunction( - &name, + ctx.dispatch(Message::DeclareFunction( + name, func, FunctionVisibility::Export, )); @@ -163,7 +167,7 @@ pub fn declare_function(ctx: &ModuleContext, function: &Expression) { } pub fn declare_and_compile_function<'ctx>( - ctx: &ModuleContext, + ctx: &CompilerContext, func: &Expression, ) -> Option { match func { @@ -242,7 +246,7 @@ pub fn declare_and_compile_function<'ctx>( } } -pub fn codegen_function(ctx: &ModuleContext, function: &Expression) { +pub fn codegen_function(ctx: &CompilerContext, function: &Expression) { match function { Expression::Function { attributes, @@ -250,7 +254,7 @@ pub fn codegen_function(ctx: &ModuleContext, function: &Expression) { ty, .. } => { - let func = ctx.query(Query::Function((name, ty))); + let func = ctx.query(Query::Function((prefix!(ctx), ty))); if let QueryResponse::Function(Some(func)) = func { let func = func.upgrade().expect("ICE"); diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 6f9abbd..6382daa 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -11,8 +11,10 @@ pub use function::{ pub mod variable; pub use variable::{alloc_variable, init_record, store_value}; -pub mod module; -pub use module::{FunctionVisibility, Message, ModuleContext, ModuleUnit, Query, QueryResponse}; +pub mod compiler; +pub use compiler::{ + CompilerContext, CompilerUnit, FunctionVisibility, Message, Query, QueryResponse, +}; pub mod decl; pub use decl::decl; diff --git a/comp-be/src/fmt.rs b/comp-be/src/fmt.rs index ebd3873..b7531f7 100644 --- a/comp-be/src/fmt.rs +++ b/comp-be/src/fmt.rs @@ -1,11 +1,20 @@ use parser::ast::{ - AtomKind, Boolean, Expression, FloatSize, FunctionType, IntSize, LValue, PrimitiveType, + AtomKind, Boolean, Expression, FloatSize, FunctionType, Ident, IntSize, LValue, PrimitiveType, }; pub trait AatbeFmt { fn fmt(self) -> String; } +impl AatbeFmt for &Ident { + fn fmt(self) -> String { + match self { + Ident::Local(path) => path.clone(), + Ident::Module(path) => todo!("{:?}", path), + } + } +} + impl AatbeFmt for PrimitiveType { fn fmt(self) -> String { (&self).fmt() @@ -155,7 +164,7 @@ impl AatbeFmt for &Expression { ), Expression::Call { name, types, args } => format!( "{}{} {}", - name, + name.fmt(), if types.len() > 0 { format!( "[{}]", diff --git a/comp-be/src/ty/aggregate.rs b/comp-be/src/ty/aggregate.rs index 1edc58e..b027520 100644 --- a/comp-be/src/ty/aggregate.rs +++ b/comp-be/src/ty/aggregate.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{unit::ModuleContext, AatbeModule, ValueTypePair}, + codegen::{unit::CompilerContext, ValueTypePair}, ty::TypeResult, }; @@ -8,21 +8,21 @@ use llvm_sys_wrapper::LLVMValueRef; pub trait Aggregate { fn gep_indexed_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult; fn gep_named_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult; fn gep_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult { diff --git a/comp-be/src/ty/mod.rs b/comp-be/src/ty/mod.rs index d9d995f..3ceb09d 100644 --- a/comp-be/src/ty/mod.rs +++ b/comp-be/src/ty/mod.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{unit::ModuleContext, AatbeModule, ValueTypePair}, + codegen::{unit::CompilerContext, AatbeModule, ValueTypePair}, fmt::AatbeFmt, ty::variant::{Variant, VariantType}, }; @@ -7,7 +7,7 @@ use parser::ast::{FloatSize, FunctionType, IntSize, PrimitiveType}; use llvm_sys_wrapper::{LLVMFunctionType, LLVMTypeRef, LLVMValueRef}; -use std::{borrow::Borrow, collections::HashMap, fmt}; +use std::{collections::HashMap, fmt}; pub mod aggregate; pub mod infer; @@ -65,7 +65,7 @@ impl fmt::Debug for TypedefKind { } impl LLVMTyInCtx for TypeKind { - fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, ctx: &CompilerContext) -> LLVMTypeRef { match self { TypeKind::RecordType(record) => record.llvm_ty_in_ctx(ctx), TypeKind::Primitive(primitive) => primitive.llvm_ty_in_ctx(ctx), @@ -230,11 +230,11 @@ impl TypeContext { } pub trait LLVMTyInCtx { - fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef; + fn llvm_ty_in_ctx(&self, ctx: &CompilerContext) -> LLVMTypeRef; } impl LLVMTyInCtx for FunctionType { - fn llvm_ty_in_ctx(&self, ctx: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, ctx: &CompilerContext) -> LLVMTypeRef { let ret = self.ret_ty.llvm_ty_in_ctx(ctx); let mut varargs = false; let ext = self.ext; @@ -280,7 +280,7 @@ impl LLVMTyInCtx for FunctionType { } impl LLVMTyInCtx for PrimitiveType { - fn llvm_ty_in_ctx(&self, mctx: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, mctx: &CompilerContext) -> LLVMTypeRef { let ctx = mctx.llvm_context; match self { diff --git a/comp-be/src/ty/record.rs b/comp-be/src/ty/record.rs index 0d43953..602ce57 100644 --- a/comp-be/src/ty/record.rs +++ b/comp-be/src/ty/record.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, unit::ModuleContext, AatbeModule, ValueTypePair}, + codegen::{builder::core, unit::CompilerContext, AatbeModule, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; use parser::ast::PrimitiveType; @@ -35,7 +35,7 @@ impl Record { } } - pub fn set_body(&self, ctx: &ModuleContext, types: &Vec) { + pub fn set_body(&self, ctx: &CompilerContext, types: &Vec) { let mut types = types .iter() .map(|ty| ty.llvm_ty_in_ctx(ctx)) @@ -57,7 +57,7 @@ impl Record { impl Aggregate for Record { fn gep_indexed_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult { @@ -73,7 +73,7 @@ impl Aggregate for Record { fn gep_named_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, name: &String, aggregate_ref: LLVMValueRef, ) -> TypeResult { @@ -92,7 +92,7 @@ impl Aggregate for Record { } pub fn store_named_field( - ctx: &ModuleContext, + ctx: &CompilerContext, struct_ref: LLVMValueRef, rec_name: &String, rec: &Record, @@ -119,7 +119,7 @@ pub fn store_named_field( } impl LLVMTyInCtx for &Record { - fn llvm_ty_in_ctx(&self, _ctx: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _ctx: &CompilerContext) -> LLVMTypeRef { self.inner.as_ref() } } diff --git a/comp-be/src/ty/variant.rs b/comp-be/src/ty/variant.rs index 043811c..facd8ec 100644 --- a/comp-be/src/ty/variant.rs +++ b/comp-be/src/ty/variant.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, unit::ModuleContext, AatbeModule, ValueTypePair}, + codegen::{builder::core, unit::CompilerContext, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; @@ -21,7 +21,7 @@ impl VariantType { } impl LLVMTyInCtx for VariantType { - fn llvm_ty_in_ctx(&self, _: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _: &CompilerContext) -> LLVMTypeRef { self.ty } } @@ -36,7 +36,7 @@ pub struct Variant { } impl LLVMTyInCtx for Variant { - fn llvm_ty_in_ctx(&self, _: &ModuleContext) -> LLVMTypeRef { + fn llvm_ty_in_ctx(&self, _: &CompilerContext) -> LLVMTypeRef { self.ty } } @@ -54,7 +54,7 @@ impl VariantType { impl Aggregate for Variant { fn gep_indexed_field( &self, - ctx: &ModuleContext, + ctx: &CompilerContext, index: u32, aggregate_ref: LLVMValueRef, ) -> TypeResult { @@ -73,7 +73,7 @@ impl Aggregate for Variant { fn gep_named_field( &self, - _ctx: &ModuleContext, + _ctx: &CompilerContext, name: &String, _aggregate_ref: LLVMValueRef, ) -> TypeResult { diff --git a/main.aat b/main.aat index e0e6fc2..cb7d112 100644 --- a/main.aat +++ b/main.aat @@ -1,8 +1,7 @@ -extern fn printf str, ... -> () - -fn world () -> str = "World!\n" +module test { + fn t () -> () = () +} @entry fn main () = { - printf "Hello %s", world() } diff --git a/main.aat.bak b/main.aat.bak new file mode 100644 index 0000000..9678ebb --- /dev/null +++ b/main.aat.bak @@ -0,0 +1,6 @@ +fn test() -> () = () + +@entry +fn main () = { + test() +} diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 251f3b0..57d6738 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -2,6 +2,13 @@ use std::fmt; type ModPath = Vec; +#[derive(Debug, PartialEq, Clone)] +pub enum IdentPath { + Local(String), + Module(ModPath), + Root(ModPath), +} + #[derive(Debug, PartialEq, Clone)] pub enum AST { File(Vec), @@ -49,7 +56,7 @@ pub enum Expression { value: Box, }, Call { - name: String, + name: IdentPath, types: Vec, args: Vec, }, diff --git a/parser/src/parser/expression.rs b/parser/src/parser/expression.rs index 0bfd529..e04428e 100644 --- a/parser/src/parser/expression.rs +++ b/parser/src/parser/expression.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{AtomKind, BindType, Expression, LValue}, + ast::{AtomKind, BindType, Expression, IdentPath, LValue}, parser::{ParseError, ParseResult, Parser}, token::{Keyword, Symbol, Token}, }; @@ -86,7 +86,11 @@ impl Parser { if args.len() < 1 { Err(ParseError::ExpectedExpression) } else { - Ok(Expression::Call { name, types, args }) + Ok(Expression::Call { + name: IdentPath::Local(name), + types, + args, + }) } } diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 327e55b..7dcb804 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -1,8 +1,7 @@ #[cfg(test)] mod parser_tests { - use crate::ast::FunctionType; use crate::{ - ast::{AtomKind, BindType, Boolean, IntSize, LValue, TypeKind}, + ast::{AtomKind, BindType, Boolean, FunctionType, IdentPath, IntSize, LValue, TypeKind}, lexer::{token::Token, Lexer}, Expression, ParseError, Parser, PrimitiveType, AST, }; @@ -165,39 +164,39 @@ fn main () -> () = 1 + 2 * 3 + 4 || 1 == 2 & -foo 1, PrimitiveType::Int(IntSize::Bits32) )), - String::from("+"), + "+".to_string(), box Expression::Binary( box Expression::Atom(AtomKind::Integer( 2, PrimitiveType::Int(IntSize::Bits32) )), - String::from("*"), + "*".to_string(), box Expression::Atom(AtomKind::Integer( 3, PrimitiveType::Int(IntSize::Bits32) )), ), ), - String::from("+"), + "+".to_string(), box Expression::Atom(AtomKind::Integer( 4, PrimitiveType::Int(IntSize::Bits32) )), ), - String::from("||"), + "||".to_string(), box Expression::Binary( box Expression::Binary( box Expression::Atom(AtomKind::Integer( 1, PrimitiveType::Int(IntSize::Bits32) )), - String::from("=="), + "==".to_string(), box Expression::Atom(AtomKind::Integer( 2, PrimitiveType::Int(IntSize::Bits32) )), ), - String::from("&"), + "&".to_string(), box Expression::Atom(AtomKind::Unary( "-".to_string(), box AtomKind::Ident("foo".to_string()), @@ -328,21 +327,21 @@ fn main () -> () = { export: false, body: Some(box Expression::Block(vec![ Expression::Call { - name: "puts".to_string(), + name: IdentPath::Local("puts".to_string()), types: vec![], args: vec![Expression::Atom(AtomKind::StringLiteral( "Hello World".to_string() ))], }, Expression::Call { - name: "puts".to_string(), + name: IdentPath::Local("puts".to_string()), types: vec![], args: vec![Expression::Atom(AtomKind::StringLiteral( "Hallo".to_string() ))], }, Expression::Call { - name: "test".to_string(), + name: IdentPath::Local("test".to_string()), types: vec![], args: vec![ Expression::Atom(AtomKind::StringLiteral("Test".to_string())), @@ -351,7 +350,7 @@ fn main () -> () = { 1, PrimitiveType::Int(IntSize::Bits32) )), - String::from("+"), + "+".to_string(), box Expression::Atom(AtomKind::Integer( 2, PrimitiveType::Int(IntSize::Bits32) @@ -398,9 +397,9 @@ fn main () -> () = { name: "var_t".to_string(), ty: Some(box PrimitiveType::Str), }, - value: Some(box Expression::Atom(AtomKind::StringLiteral(String::from( - "Hello World" - )))), + value: Some(box Expression::Atom(AtomKind::StringLiteral( + "Hello World".to_string() + ))), exterior_bind: BindType::Mutable, }, Expression::Decl { @@ -421,9 +420,9 @@ fn main () -> () = { }, Expression::Assign { lval: LValue::Ident("var_t".to_string()), - value: box Expression::Atom(AtomKind::StringLiteral(String::from( - "Aloha honua" - ))), + value: box Expression::Atom(AtomKind::StringLiteral( + "Aloha honua".to_string() + )), } ])), ty: FunctionType { @@ -475,14 +474,14 @@ fn main () -> () = { )), ), then_expr: box Expression::Block(vec![Expression::Call { - name: "foo".to_string(), + name: IdentPath::Local("foo".to_string()), types: vec![], args: vec![Expression::Atom(AtomKind::StringLiteral( "bar".to_string() ))] }]), else_expr: Some(box Expression::Block(vec![Expression::Call { - name: "bar".to_string(), + name: IdentPath::Local("bar".to_string()), types: vec![], args: vec![Expression::Atom(AtomKind::StringLiteral( "foo".to_string() @@ -500,7 +499,7 @@ fn main () -> () = { )), )), then_expr: box Expression::Call { - name: "baz".to_string(), + name: IdentPath::Local("baz".to_string()), types: vec![], args: vec![Expression::Atom(AtomKind::Bool(Boolean::True))] }, @@ -542,7 +541,7 @@ fn main () -> () assert_eq!( pt, AST::File(vec![ - AST::Import(String::from("lib.aat")), + AST::Import("lib.aat".to_string()), AST::Expr(Expression::Function { name: "main".to_string(), attributes: attr(vec!["entry"]), @@ -589,10 +588,10 @@ rec Unit() ), AST::Record( "Generic".to_string(), - Some(vec![String::from("T")]), + Some(vec!["T".to_string()]), vec![PrimitiveType::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef(String::from("T"))), + ty: Some(box PrimitiveType::TypeRef("T".to_string())), },] ), AST::Record("Unit".to_string(), None, vec![PrimitiveType::Unit],) @@ -632,10 +631,10 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } ), AST::Record( "Generic".to_string(), - Some(vec![String::from("T")]), + Some(vec!["T".to_string()]), vec![PrimitiveType::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef(String::from("T"))), + ty: Some(box PrimitiveType::TypeRef("T".to_string())), },] ), AST::Expr(Expression::Function { @@ -715,39 +714,39 @@ fn generic_test[T] value: T AST::File(vec![ AST::Record( "Generic".to_string(), - Some(vec![String::from("T")]), + Some(vec!["T".to_string()]), vec![PrimitiveType::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef(String::from("T"))), + ty: Some(box PrimitiveType::TypeRef("T".to_string())), },] ), AST::Expr(Expression::Function { name: "generic_record_test".to_string(), attributes: vec![], - type_names: vec![String::from("T")], + type_names: vec!["T".to_string()], body: None, export: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, params: vec![PrimitiveType::GenericTypeRef( - String::from("Generic"), - vec![PrimitiveType::TypeRef(String::from("T"))] + "Generic".to_string(), + vec![PrimitiveType::TypeRef("T".to_string())] )], } }), AST::Expr(Expression::Function { name: "generic_test".to_string(), attributes: vec![], - type_names: vec![String::from("T")], + type_names: vec!["T".to_string()], body: None, export: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, params: vec![PrimitiveType::NamedType { - name: String::from("value"), - ty: Some(box PrimitiveType::TypeRef(String::from("T"))) + name: "value".to_string(), + ty: Some(box PrimitiveType::TypeRef("T".to_string())) }], } }), @@ -771,15 +770,15 @@ fn test () = generic_test[i32] 64 AST::Expr(Expression::Function { name: "generic_test".to_string(), attributes: vec![], - type_names: vec![String::from("T")], + type_names: vec!["T".to_string()], body: None, export: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, params: vec![PrimitiveType::NamedType { - name: String::from("value"), - ty: Some(box PrimitiveType::TypeRef(String::from("T"))) + name: "value".to_string(), + ty: Some(box PrimitiveType::TypeRef("T".to_string())) }], } }), @@ -789,7 +788,7 @@ fn test () = generic_test[i32] 64 type_names: vec![], export: false, body: Some(box Expression::Call { - name: String::from("generic_test"), + name: IdentPath::Local("generic_test".to_string()), types: vec![PrimitiveType::Int(IntSize::Bits32)], args: vec![Expression::Atom(AtomKind::Integer( 64, @@ -824,35 +823,35 @@ type Complex = u8 | u16 | Comp @str pt, AST::File(vec![ AST::Typedef { - name: String::from("Opaque"), + name: "Opaque".to_string(), type_names: None, variants: None, }, AST::Typedef { - name: String::from("Generic"), - type_names: Some(vec![String::from("T")]), + name: "Generic".to_string(), + type_names: Some(vec!["T".to_string()]), variants: None, }, AST::Typedef { - name: String::from("Newtype"), + name: "Newtype".to_string(), type_names: None, variants: Some(vec![TypeKind::Newtype(PrimitiveType::UInt( IntSize::Bits32 ))]), }, AST::Typedef { - name: String::from("Option"), - type_names: Some(vec![String::from("T")]), + name: "Option".to_string(), + type_names: Some(vec!["T".to_string()]), variants: Some(vec![ - TypeKind::Variant(String::from("None"), None), + TypeKind::Variant("None".to_string(), None), TypeKind::Variant( - String::from("Some"), - Some(vec![PrimitiveType::TypeRef(String::from("T"))]) + "Some".to_string(), + Some(vec![PrimitiveType::TypeRef("T".to_string())]) ) ]), }, AST::Typedef { - name: String::from("Number"), + name: "Number".to_string(), type_names: None, variants: Some(vec![ TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits8)), @@ -860,13 +859,13 @@ type Complex = u8 | u16 | Comp @str ]), }, AST::Typedef { - name: String::from("Complex"), + name: "Complex".to_string(), type_names: None, variants: Some(vec![ TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits8)), TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits16)), TypeKind::Variant( - String::from("Comp"), + "Comp".to_string(), Some(vec![PrimitiveType::Box(box PrimitiveType::Str)]) ) ]), @@ -908,7 +907,7 @@ module mod { AST::File(vec![AST::Module( "mod".to_string(), box AST::File(vec![AST::Typedef { - name: String::from("Opaque"), + name: "Opaque".to_string(), type_names: None, variants: None, }]) @@ -928,7 +927,7 @@ type Newtype = mod::test::next assert_eq!( pt, AST::File(vec![AST::Typedef { - name: String::from("Newtype"), + name: "Newtype".to_string(), type_names: None, variants: Some(vec![TypeKind::Newtype(PrimitiveType::Path(vec![ "mod".to_string(), From 3e66bc9ea7b189b73fc45c98cd640e6387a11b54 Mon Sep 17 00:00:00 2001 From: chronium Date: Thu, 18 Mar 2021 15:15:10 +0200 Subject: [PATCH 10/18] The One With Modules X Milestone 1: Call functions from modules --- comp-be/src/codegen/mangle_v1.rs | 16 +++- comp-be/src/codegen/unit/cg/call.rs | 38 +++++----- comp-be/src/codegen/unit/compiler.rs | 36 ++++++++- comp-be/src/codegen/unit/function.rs | 5 +- comp-be/src/fmt.rs | 16 ++-- main.aat | 5 +- parser/src/ast.rs | 2 +- parser/src/lexer/tests.rs | 4 +- parser/src/lexer/token.rs | 4 +- parser/src/lib.rs | 6 +- parser/src/parser/expression.rs | 10 +-- parser/src/parser/macros.rs | 53 +++++++++++++ parser/src/parser/pass/type_resolution.rs | 4 +- parser/src/tests.rs | 91 +++++++++++++++++------ 14 files changed, 214 insertions(+), 76 deletions(-) diff --git a/comp-be/src/codegen/mangle_v1.rs b/comp-be/src/codegen/mangle_v1.rs index f3da7d8..4843619 100644 --- a/comp-be/src/codegen/mangle_v1.rs +++ b/comp-be/src/codegen/mangle_v1.rs @@ -16,7 +16,7 @@ impl NameMangler for Expression { body: _, attributes, type_names, - export: _, + public: _, } => match ty { FunctionType { ext: false, @@ -26,7 +26,19 @@ impl NameMangler for Expression { if !attributes.contains(&String::from("entry")) { format!( "{}{}{}", - prefix!(ctx, name.clone()).join("__"), + { + let n = prefix!(ctx, name.clone()); + if n.len() == 1 { + n[0].clone() + } else { + format!( + "_{}", + n.iter().fold(String::default(), |prev, curr| { + format!("{}{}{}", prev, curr.len(), curr) + }) + ) + } + }, if type_names.len() > 0 { format!("G{}", type_names.len()) } else { diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index 213c4c6..dd4a9a2 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; -use parser::ast::{AtomKind, Expression, Ident, PrimitiveType}; +use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; use crate::{ codegen::{ @@ -21,7 +21,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { args, } = expr { - trace!("Call {}", AatbeFmt::fmt(expr)); + ctx.trace(format!("Call {}", AatbeFmt::fmt(expr))); let mut call_types = vec![]; let mut error = false; @@ -65,25 +65,23 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { return None; } - if let Ident::Local(name) = name { - if let QueryResponse::FunctionGroup(Some(group)) = - ctx.query(Query::FunctionGroup(prefix!(call ctx, name.clone()))) - { - if let Some(func) = find_function(group, &call_types) { - Some(core::call( - ctx, - func.upgrade().expect("ICE").borrow(), - &mut call_args, - )) - } else { - todo!(); - } - } else { - todo!(); + let prefix = |path: &IdentPath| -> Vec { + match path { + IdentPath::Local(name) => prefix!(call ctx, name.clone()), + IdentPath::Module(name) => prefix!(call module ctx, name.clone()), + _ => todo!(), } - } else { - todo!(); - } + }; + + find_function( + match ctx.query(Query::FunctionGroup(prefix(name))) { + QueryResponse::FunctionGroup(Some(group)) => group, + QueryResponse::FunctionGroup(None) => todo!("no function found"), + _ => panic!("ICE"), + }, + &call_types, + ) + .map(|func| core::call(ctx, func.upgrade().expect("ICE").borrow(), &mut call_args)) } else { unreachable!() } diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index 78ad53d..0b90e81 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -130,6 +130,7 @@ pub struct CompilerContext<'ctx> { pub function_templates: HashMap, dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, + trace: &'ctx dyn Fn(String) -> (), } impl<'ctx> CompilerContext<'ctx> { @@ -140,6 +141,7 @@ impl<'ctx> CompilerContext<'ctx> { llvm_builder: &'ctx Builder, dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, + trace: &'ctx dyn Fn(String) -> (), ) -> Self where P: Into, @@ -151,6 +153,7 @@ impl<'ctx> CompilerContext<'ctx> { llvm_builder, dispatch, query, + trace, function_templates: HashMap::new(), } } @@ -163,10 +166,15 @@ impl<'ctx> CompilerContext<'ctx> { llvm_builder: builder, dispatch: self.dispatch, query: self.query, + trace: self.trace, function_templates: HashMap::new(), } } + pub fn trace(&self, message: String) { + (self.trace)(message) + } + pub fn dispatch(&self, message: Message) { (self.dispatch)(message) } @@ -241,8 +249,6 @@ impl<'ctx> CompilerUnit<'ctx> { } fn enter_anonymous_scope(&self) { - print!("{}", "│ ".repeat(*self.ident.borrow())); - println!("├── Enter Scope"); self.scope_stack.borrow_mut().push(Scope::new()); } @@ -316,7 +322,11 @@ impl<'ctx> CompilerUnit<'ctx> { *self.ident.borrow_mut() += 1; self.restore_module_scope(name.clone()) } - Message::EnterAnonymousScope => self.enter_anonymous_scope(), + Message::EnterAnonymousScope => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.enter_anonymous_scope() + } Message::ExitScope => { println!("└── {:?}", message); *self.ident.borrow_mut() -= 1; @@ -338,6 +348,11 @@ impl<'ctx> CompilerUnit<'ctx> { response } + fn trace(&self, message: String) { + print!("{}", "│ ".repeat(*self.ident.borrow())); + println!("├── {}", message); + } + pub fn push( &mut self, name: &String, @@ -354,6 +369,7 @@ impl<'ctx> CompilerUnit<'ctx> { let ast = self.ast.clone(); let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); + let trace = &|message: String| self.trace(message); decl::decl( &*ast, @@ -364,6 +380,7 @@ impl<'ctx> CompilerUnit<'ctx> { root_builder, dispatch, query, + trace, ), ); } @@ -372,6 +389,7 @@ impl<'ctx> CompilerUnit<'ctx> { let ast = self.ast.clone(); let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); + let trace = &|message: String| self.trace(message); cg::cg( &*ast, @@ -382,6 +400,7 @@ impl<'ctx> CompilerUnit<'ctx> { root_builder, dispatch, query, + trace, ), ) } @@ -433,6 +452,17 @@ macro_rules! prefix { panic!("PREFIX ICE") } }}; + (call module $ctx: expr, $name: expr) => {{ + if let crate::codegen::unit::compiler::QueryResponse::Prefix(mut prefix) = + $ctx.query(crate::codegen::unit::compiler::Query::Prefix) + { + prefix.pop(); + prefix.extend($name); + prefix + } else { + panic!("PREFIX ICE") + } + }}; ($ctx: expr, $name: expr) => {{ if let crate::codegen::unit::compiler::QueryResponse::Prefix(mut prefix) = $ctx.query(crate::codegen::unit::compiler::Query::Prefix) diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 3918de2..2e6e2f8 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -15,7 +15,6 @@ use crate::{ }; use llvm_sys_wrapper::Function; use std::{ - borrow::Borrow, cell::RefCell, collections::HashMap, ops::Deref, @@ -137,7 +136,7 @@ pub fn declare_function(ctx: &CompilerContext, function: &Expression) { match function { Expression::Function { ty, - export, + public, type_names, name, .. @@ -148,7 +147,7 @@ pub fn declare_function(ctx: &CompilerContext, function: &Expression) { let name = prefix!(ctx, name.clone()); let func = Func::new(ty.clone(), name.clone(), func); - if !export { + if !public { ctx.dispatch(Message::DeclareFunction( name, func, diff --git a/comp-be/src/fmt.rs b/comp-be/src/fmt.rs index b7531f7..df839dd 100644 --- a/comp-be/src/fmt.rs +++ b/comp-be/src/fmt.rs @@ -1,16 +1,18 @@ use parser::ast::{ - AtomKind, Boolean, Expression, FloatSize, FunctionType, Ident, IntSize, LValue, PrimitiveType, + AtomKind, Boolean, Expression, FloatSize, FunctionType, IdentPath, IntSize, LValue, + PrimitiveType, }; pub trait AatbeFmt { fn fmt(self) -> String; } -impl AatbeFmt for &Ident { +impl AatbeFmt for &IdentPath { fn fmt(self) -> String { match self { - Ident::Local(path) => path.clone(), - Ident::Module(path) => todo!("{:?}", path), + IdentPath::Local(path) => path.clone(), + IdentPath::Module(path) => path.join("::"), + IdentPath::Root(path) => format!("::{}", path.join("::")), } } } @@ -103,7 +105,7 @@ impl AatbeFmt for &PrimitiveType { impl AatbeFmt for &AtomKind { fn fmt(self) -> String { match self { - AtomKind::StringLiteral(lit) => format!("\"{}\"", lit), + AtomKind::StringLiteral(lit) => format!("{:?}", lit), AtomKind::CharLiteral(lit) => format!("{}", lit), AtomKind::Integer(val, ty) => format!("{}{}", val, ty.fmt()), AtomKind::Floating(val, ty) => format!("{}{}", val, ty.fmt()), @@ -184,12 +186,12 @@ impl AatbeFmt for &Expression { ), Expression::Function { name, - export, + public, ty: ty @ FunctionType { ext, .. }, .. } => format!( "{}{}fn {}{}", - if *export { "exp " } else { "" }, + if *public { "public " } else { "" }, if *ext { "ext " } else { "" }, name, ty.fmt(), diff --git a/main.aat b/main.aat index cb7d112..b669c2f 100644 --- a/main.aat +++ b/main.aat @@ -1,7 +1,8 @@ -module test { - fn t () -> () = () +module libc { + public extern fn printf str, ... -> i32 } @entry fn main () = { + libc::printf "Hello World!\n" } diff --git a/parser/src/ast.rs b/parser/src/ast.rs index 57d6738..b7a1a38 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -66,7 +66,7 @@ pub enum Expression { body: Option>, attributes: Vec, type_names: Vec, - export: bool, + public: bool, }, If { cond_expr: Box, diff --git a/parser/src/lexer/tests.rs b/parser/src/lexer/tests.rs index b82c6ca..0b132ed 100644 --- a/parser/src/lexer/tests.rs +++ b/parser/src/lexer/tests.rs @@ -150,7 +150,7 @@ mod lexer_tests { #[test] fn keyword_identifier() { let mut lexer = Lexer::new( - "fn extern var val if else use true false main record.test bool rec global ret while until type is exp module", + "fn extern var val if else use true false main record.test bool rec global ret while until type is public module", ); let mut tokens = lexer.lex().into_iter(); @@ -198,7 +198,7 @@ mod lexer_tests { sep!(tokens); assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Is)); sep!(tokens); - assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Exp)); + assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Public)); sep!(tokens); assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Module)); } diff --git a/parser/src/lexer/token.rs b/parser/src/lexer/token.rs index 886fe04..82fd1f4 100644 --- a/parser/src/lexer/token.rs +++ b/parser/src/lexer/token.rs @@ -115,7 +115,7 @@ pub enum Keyword { Until, Type, Is, - Exp, + Public, Module, } @@ -254,7 +254,7 @@ impl FromStr for Keyword { "until" => Ok(Self::Until), "type" => Ok(Self::Type), "is" => Ok(Self::Is), - "exp" => Ok(Self::Exp), + "public" => Ok(Self::Public), "module" => Ok(Self::Module), _ => Err(()), } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 6eab97e..66d7b97 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -222,7 +222,7 @@ impl Parser { } fn parse_const_global(&mut self) -> ParseResult { - let export = kw!(bool Exp, self); + let export = kw!(bool Public, self); let cons = kw!(bool Const, self); let glob = kw!(bool Global, self); @@ -312,7 +312,7 @@ impl Parser { } } - let export = kw!(bool Exp, self); + let public = kw!(bool Public, self); let ext = kw!(bool Extern, self); kw!(Fn, self); let name = ident!(required self); @@ -345,7 +345,7 @@ impl Parser { attributes, body, type_names, - export, + public, ty: FunctionType { ext, ret_ty, diff --git a/parser/src/parser/expression.rs b/parser/src/parser/expression.rs index e04428e..7835cae 100644 --- a/parser/src/parser/expression.rs +++ b/parser/src/parser/expression.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{AtomKind, BindType, Expression, IdentPath, LValue}, + ast::{AtomKind, BindType, Expression, LValue}, parser::{ParseError, ParseResult, Parser}, token::{Keyword, Symbol, Token}, }; @@ -50,7 +50,7 @@ impl Parser { } fn parse_funcall(&mut self) -> ParseResult { - let name = ident!(required self); + let name = path!(required self); let types = if sym!(bool LBracket, self) { let types = self.parse_type_list()?; @@ -86,11 +86,7 @@ impl Parser { if args.len() < 1 { Err(ParseError::ExpectedExpression) } else { - Ok(Expression::Call { - name: IdentPath::Local(name), - types, - args, - }) + Ok(Expression::Call { name, types, args }) } } diff --git a/parser/src/parser/macros.rs b/parser/src/parser/macros.rs index e921072..c595268 100644 --- a/parser/src/parser/macros.rs +++ b/parser/src/parser/macros.rs @@ -110,6 +110,59 @@ macro_rules! kw { }}; } +#[macro_export] +macro_rules! path { + (required $self:ident) => {{ + use crate::{ast::IdentPath, lexer::token::TokenKind}; + let prev_ind = $self.index; + let token = $self.next(); + if let Some(tok) = token { + match tok.kind { + TokenKind::Identifier(id) => { + let mut res = vec![id.clone()]; + + while matches!($self.peek_symbol(Symbol::Doubly), Some(true)) { + $self.next(); + if $self.peek_ident().is_some() { + $self.next().unwrap().ident().map(|id| res.push(id.clone())); + } + } + + if !matches!($self.peek_symbol(Symbol::LBracket), Some(true)) { + $self.index -= 1; + } + + if res.len() == 1 { + IdentPath::Local(id) + } else { + IdentPath::Module(res) + } + } + TokenKind::Symbol(Symbol::Doubly) => { + $self.index = prev_ind; + let mut res = vec![]; + + while matches!($self.peek_symbol(Symbol::Doubly), Some(true)) { + $self.next(); + if $self.peek_ident().is_some() { + $self.next().unwrap().ident().map(|id| res.push(id.clone())); + } + } + + IdentPath::Root(res) + } + _ => { + $self.index = prev_ind; + return Err(ParseError::ExpectedIdent); + } + } + } else { + $self.index = prev_ind; + return Err(ParseError::ExpectedIdent); + } + }}; +} + #[macro_export] macro_rules! ident { (required $self:ident) => {{ diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 8e78ebf..2dd2d57 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -51,12 +51,12 @@ fn resolve_expr(variants: &Vec, ast: &Expression) -> Expression { name, body, ty, - export, + public, } => Expression::Function { name: name.clone(), attributes: attributes.clone(), type_names: type_names.clone(), - export: *export, + public: *public, ty: resolve_function_ty(variants, ty), body: body.as_ref().map(|body| box resolve_expr(variants, &body)), }, diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 7dcb804..41abe93 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -46,7 +46,7 @@ mod parser_tests { #[test] fn unit_function() { - let pt = parse_test!("exp fn test () -> ()", "Unit Function"); + let pt = parse_test!("public fn test () -> ()", "Unit Function"); assert_eq!( pt, @@ -55,7 +55,7 @@ mod parser_tests { attributes: vec![], body: None, type_names: vec![], - export: true, + public: true, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -76,7 +76,7 @@ mod parser_tests { attributes: vec![], body: None, type_names: vec![], - export: false, + public: false, ty: FunctionType { ext: true, ret_ty: box PrimitiveType::Unit, @@ -102,7 +102,7 @@ fn main () -> () name: "main".to_string(), attributes: attr(vec!["entry"]), body: None, - export: false, + public: false, type_names: vec![], ty: FunctionType { ext: false, @@ -129,7 +129,7 @@ fn main () -> () = () name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Atom(AtomKind::Unit)), ty: FunctionType { ext: false, @@ -156,7 +156,7 @@ fn main () -> () = 1 + 2 * 3 + 4 || 1 == 2 & -foo name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Binary( box Expression::Binary( box Expression::Binary( @@ -229,7 +229,7 @@ fn main () -> () = {} attributes: attr(vec!["entry"]), body: Some(box Expression::Block(vec![])), type_names: vec![], - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -255,7 +255,7 @@ fn main () -> () = { () } name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Block(vec![Expression::Atom( AtomKind::Unit )])), @@ -294,7 +294,7 @@ fn main () -> () = { attributes: vec![], body: None, type_names: vec![], - export: false, + public: false, ty: FunctionType { ext: true, ret_ty: box PrimitiveType::Int(IntSize::Bits32), @@ -306,7 +306,7 @@ fn main () -> () = { attributes: vec![], body: None, type_names: vec![], - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -324,7 +324,7 @@ fn main () -> () = { name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Block(vec![ Expression::Call { name: IdentPath::Local("puts".to_string()), @@ -390,7 +390,7 @@ fn main () -> () = { name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Block(vec![ Expression::Decl { ty: PrimitiveType::NamedType { @@ -459,7 +459,7 @@ fn main () -> () = { name: "main".to_string(), attributes: attr(vec!["entry"]), type_names: vec![], - export: false, + public: false, body: Some(box Expression::Block(vec![ Expression::If { cond_expr: box Expression::Binary( @@ -547,7 +547,7 @@ fn main () -> () attributes: attr(vec!["entry"]), body: None, type_names: vec![], - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -641,7 +641,7 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } name: "rec_test".to_string(), attributes: vec![], type_names: vec![], - export: false, + public: false, body: Some(box Expression::RecordInit { record: "Record".to_string(), types: vec![], @@ -678,7 +678,7 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } name: "generic_test".to_string(), attributes: vec![], type_names: vec![], - export: false, + public: false, body: Some(box Expression::RecordInit { record: "Generic".to_string(), types: vec![PrimitiveType::Str], @@ -725,7 +725,7 @@ fn generic_test[T] value: T attributes: vec![], type_names: vec!["T".to_string()], body: None, - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -740,7 +740,7 @@ fn generic_test[T] value: T attributes: vec![], type_names: vec!["T".to_string()], body: None, - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -772,7 +772,7 @@ fn test () = generic_test[i32] 64 attributes: vec![], type_names: vec!["T".to_string()], body: None, - export: false, + public: false, ty: FunctionType { ext: false, ret_ty: box PrimitiveType::Unit, @@ -786,7 +786,7 @@ fn test () = generic_test[i32] 64 name: "test".to_string(), attributes: vec![], type_names: vec![], - export: false, + public: false, body: Some(box Expression::Call { name: IdentPath::Local("generic_test".to_string()), types: vec![PrimitiveType::Int(IntSize::Bits32)], @@ -881,7 +881,7 @@ type Complex = u8 | u16 | Comp @str module mod { }", - "Parse Module" + "Parse Empty Module" ); assert_eq!( @@ -921,7 +921,7 @@ module mod { " type Newtype = mod::test::next ", - "Typedef tests" + "Module Typedef tests" ); assert_eq!( @@ -937,4 +937,51 @@ type Newtype = mod::test::next },]) ); } + + #[test] + fn module_call() { + let pt = parse_test!( + " +@entry +fn main () = { + func () + mod::func () + ::func () +} +", + "Module call tests" + ); + + assert_eq!( + pt, + AST::File(vec![AST::Expr(Expression::Function { + name: "main".to_string(), + attributes: attr(vec!["entry"]), + type_names: vec![], + public: false, + body: Some(box Expression::Block(vec![ + Expression::Call { + name: IdentPath::Local("func".to_string()), + types: vec![], + args: vec![Expression::Atom(AtomKind::Unit)] + }, + Expression::Call { + name: IdentPath::Module(vec!["mod".to_string(), "func".to_string()]), + types: vec![], + args: vec![Expression::Atom(AtomKind::Unit)] + }, + Expression::Call { + name: IdentPath::Root(vec!["func".to_string()]), + types: vec![], + args: vec![Expression::Atom(AtomKind::Unit)] + } + ])), + ty: FunctionType { + ext: false, + ret_ty: box PrimitiveType::Unit, + params: vec![PrimitiveType::Unit], + } + })]) + ); + } } From d2e43b2f67520cfb3d4396f438a678df235fe444 Mon Sep 17 00:00:00 2001 From: chronium Date: Thu, 18 Mar 2021 19:59:55 +0200 Subject: [PATCH 11/18] The One With Modules XI --- .idea/.gitignore | 8 + .idea/aatbe-lang.iml | 17 ++ .idea/modules.xml | 8 + .idea/vcs.xml | 7 + comp-be/src/codegen/atom.rs | 1 - comp-be/src/codegen/expr/compare.rs | 61 ----- comp-be/src/codegen/expr/const_expr.rs | 119 ---------- comp-be/src/codegen/expr/eqne.rs | 55 ----- comp-be/src/codegen/expr/math.rs | 67 ------ comp-be/src/codegen/expr/mod.rs | 213 +++++++----------- comp-be/src/codegen/module.rs | 2 - comp-be/src/codegen/unit/cg/atom.rs | 24 +- comp-be/src/codegen/unit/cg/binary/bool.rs | 21 ++ comp-be/src/codegen/unit/cg/binary/comp.rs | 20 ++ comp-be/src/codegen/unit/cg/binary/eqne.rs | 20 ++ .../src/codegen/unit/cg/binary/float/arith.rs | 24 ++ .../src/codegen/unit/cg/binary/float/cmp.rs | 20 ++ .../src/codegen/unit/cg/binary/float/eqne.rs | 22 ++ .../src/codegen/unit/cg/binary/float/mod.rs | 22 ++ .../src/codegen/unit/cg/binary/int/arith.rs | 24 ++ comp-be/src/codegen/unit/cg/binary/int/cmp.rs | 22 ++ comp-be/src/codegen/unit/cg/binary/int/mod.rs | 24 ++ comp-be/src/codegen/unit/cg/binary/mod.rs | 89 ++++++++ .../src/codegen/unit/cg/binary/uint/arith.rs | 24 ++ .../src/codegen/unit/cg/binary/uint/cmp.rs | 22 ++ .../src/codegen/unit/cg/binary/uint/mod.rs | 24 ++ comp-be/src/codegen/unit/cg/consts/mod.rs | 1 + comp-be/src/codegen/unit/cg/consts/numeric.rs | 28 +++ comp-be/src/codegen/unit/cg/expr.rs | 3 +- comp-be/src/codegen/unit/cg/mod.rs | 2 + main.aat | 2 +- 31 files changed, 555 insertions(+), 441 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/aatbe-lang.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml delete mode 100644 comp-be/src/codegen/expr/compare.rs delete mode 100644 comp-be/src/codegen/expr/const_expr.rs delete mode 100644 comp-be/src/codegen/expr/eqne.rs delete mode 100644 comp-be/src/codegen/expr/math.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/bool.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/comp.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/eqne.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/float/arith.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/float/cmp.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/float/eqne.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/float/mod.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/int/arith.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/int/cmp.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/int/mod.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/mod.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/uint/arith.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/uint/cmp.rs create mode 100644 comp-be/src/codegen/unit/cg/binary/uint/mod.rs create mode 100644 comp-be/src/codegen/unit/cg/consts/mod.rs create mode 100644 comp-be/src/codegen/unit/cg/consts/numeric.rs diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/aatbe-lang.iml b/.idea/aatbe-lang.iml new file mode 100644 index 0000000..7c8cb7b --- /dev/null +++ b/.idea/aatbe-lang.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2d2e2ea --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..495fd2e --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index 69b39c3..2228d5d 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -1,7 +1,6 @@ use crate::{ codegen::{ builder::{cast, core, op, ty}, - expr::const_expr::const_atom, unit::Slot, AatbeModule, CompileError, ValueTypePair, }, diff --git a/comp-be/src/codegen/expr/compare.rs b/comp-be/src/codegen/expr/compare.rs deleted file mode 100644 index a896f42..0000000 --- a/comp-be/src/codegen/expr/compare.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::codegen::{unit::CompilerContext, ValueTypePair}; -use parser::ast::PrimitiveType; - -use llvm_sys_wrapper::LLVMValueRef; - -pub fn codegen_compare_float( - module: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "<" => module.llvm_builder.build_fcmp_ult(lhs, rhs), - ">" => module.llvm_builder.build_fcmp_ugt(lhs, rhs), - "<=" => module.llvm_builder.build_fcmp_ule(lhs, rhs), - ">=" => module.llvm_builder.build_fcmp_uge(lhs, rhs), - _ => panic!("ICE codegen_compare_float unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} - -pub fn codegen_compare_signed( - module: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "<" => module.llvm_builder.build_icmp_slt(lhs, rhs), - ">" => module.llvm_builder.build_icmp_sgt(lhs, rhs), - "<=" => module.llvm_builder.build_icmp_sle(lhs, rhs), - ">=" => module.llvm_builder.build_icmp_sge(lhs, rhs), - _ => panic!("ICE codegen_compare_signed unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} - -pub fn codegen_compare_unsigned( - module: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "<" => module.llvm_builder.build_icmp_ult(lhs, rhs), - ">" => module.llvm_builder.build_icmp_ugt(lhs, rhs), - "<=" => module.llvm_builder.build_icmp_ule(lhs, rhs), - ">=" => module.llvm_builder.build_icmp_uge(lhs, rhs), - _ => panic!("ICE codegen_compare_unsigned unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} diff --git a/comp-be/src/codegen/expr/const_expr.rs b/comp-be/src/codegen/expr/const_expr.rs deleted file mode 100644 index cd7cb12..0000000 --- a/comp-be/src/codegen/expr/const_expr.rs +++ /dev/null @@ -1,119 +0,0 @@ -use crate::{ - codegen::{ - builder::value, - unit::{CompilerContext, Mutability, Slot}, - AatbeModule, CompileError, ValueTypePair, - }, - fmt::AatbeFmt, - ty::LLVMTyInCtx, -}; -use parser::ast::{AtomKind, Expression, PrimitiveType, AST}; - -pub fn const_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option { - match atom { - AtomKind::StringLiteral(string) => Some(value::str(ctx, string.as_ref())), - AtomKind::CharLiteral(ch) => Some(value::char(ctx, *ch)), - AtomKind::Integer(val, PrimitiveType::Int(size)) => { - Some(value::sint(ctx, size.clone(), *val)) - } - AtomKind::Integer(val, PrimitiveType::UInt(size)) => { - Some(value::uint(ctx, size.clone(), *val)) - } - AtomKind::Floating(val, PrimitiveType::Float(size)) => { - Some(value::floating(ctx, size.clone(), *val)) - } - AtomKind::Cast(box AtomKind::Integer(val, _), PrimitiveType::Char) => { - Some(value::char(ctx, *val as u8 as char)) - } - AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::Int(size))) - if op == &String::from("-") => - { - Some(value::sint(ctx, size.clone(), (-(*val as i64)) as u64)) - } - AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::UInt(size))) - if op == &String::from("-") => - { - Some(value::uint(ctx, size.clone(), (-(*val as i64)) as u64)) - } - AtomKind::Parenthesized(box atom) => fold_expression(ctx, atom), - _ => panic!("ICE fold_atom {:?}", atom), - } -} - -fn fold_expression(ctx: &CompilerContext, expr: &Expression) -> Option { - match expr { - Expression::Atom(atom) => const_atom(ctx, atom), - _ => panic!("ICE fold_expression {:?}", expr), - } -} - -pub fn fold_constant(module: &mut AatbeModule, ast: &AST) -> Option { - /*match ast { - AST::Global { - ty: - PrimitiveType::NamedType { - name, - ty: Some(box ty), - }, - value, - export: _, - } => fold_expression(module, value) - .and_then(|val| { - if val.prim() != ty.inner() { - module.add_error(CompileError::AssignMismatch { - expected_ty: ty.fmt(), - found_ty: val.prim().fmt(), - value: value.fmt(), - var: name.clone(), - }); - - None - } else { - Some(val) - } - }) - .map(|val| { - let val_ref = module - .llvm_module_ref() - .add_global(ty.llvm_ty_in_ctx(module), name.as_ref()); - module.llvm_module_ref().set_initializer(val_ref, *val); - Slot::Variable { - mutable: Mutability::Global, - name: name.clone(), - ty: val.prim().clone(), - value: val_ref, - } - }), - AST::Constant { - ty: - PrimitiveType::NamedType { - name, - ty: Some(box ty), - }, - value, - export: _, - } => fold_expression(module, value) - .and_then(|val| { - if val.prim() != ty.inner() { - module.add_error(CompileError::AssignMismatch { - expected_ty: ty.fmt(), - found_ty: val.prim().fmt(), - value: value.fmt(), - var: name.clone(), - }); - - None - } else { - Some(val) - } - }) - .map(|val| Slot::Variable { - mutable: Mutability::Constant, - name: name.clone(), - ty: val.prim().clone(), - value: *val, - }), - _ => unreachable!(), - }*/ - todo!("{:?}", ast) -} diff --git a/comp-be/src/codegen/expr/eqne.rs b/comp-be/src/codegen/expr/eqne.rs deleted file mode 100644 index 46359f9..0000000 --- a/comp-be/src/codegen/expr/eqne.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::codegen::{unit::CompilerContext, ValueTypePair}; -use parser::ast::PrimitiveType; - -use llvm_sys_wrapper::LLVMValueRef; - -pub fn codegen_eq_ne( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "==" => ctx.llvm_builder.build_icmp_eq(lhs, rhs), - "!=" => ctx.llvm_builder.build_icmp_ne(lhs, rhs), - _ => panic!("ICE codegen_eq_ne unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} - -pub fn codegen_boolean( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "&&" => ctx.llvm_builder.build_and(lhs, rhs), - "||" => ctx.llvm_builder.build_or(lhs, rhs), - _ => panic!("ICE codegen_eq_ne unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} - -pub fn codegen_eq_ne_float( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> ValueTypePair { - ( - match op.as_str() { - "==" => ctx.llvm_builder.build_fcmp_ueq(lhs, rhs), - "!=" => ctx.llvm_builder.build_fcmp_une(lhs, rhs), - _ => panic!("ICE codegen_eq_ne_float unhandled op {}", op), - }, - PrimitiveType::Bool, - ) - .into() -} diff --git a/comp-be/src/codegen/expr/math.rs b/comp-be/src/codegen/expr/math.rs deleted file mode 100644 index 50ea889..0000000 --- a/comp-be/src/codegen/expr/math.rs +++ /dev/null @@ -1,67 +0,0 @@ -use crate::codegen::{unit::CompilerContext, ValueTypePair}; -use parser::ast::{FloatSize, IntSize, PrimitiveType}; - -use llvm_sys_wrapper::LLVMValueRef; - -pub fn codegen_float_ops( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - float_size: FloatSize, -) -> ValueTypePair { - ( - match op.as_str() { - "+" => ctx.llvm_builder.build_fadd(lhs, rhs), - "-" => ctx.llvm_builder.build_fsub(lhs, rhs), - "*" => ctx.llvm_builder.build_fmul(lhs, rhs), - "/" => ctx.llvm_builder.build_fdiv(lhs, rhs), - "%" => ctx.llvm_builder.build_frem(lhs, rhs), - _ => panic!("ICE codegen_float_ops unhandled op {}", op), - }, - PrimitiveType::Float(float_size), - ) - .into() -} - -pub fn codegen_signed_ops( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - int_size: IntSize, -) -> ValueTypePair { - ( - match op.as_str() { - "+" => ctx.llvm_builder.build_add(lhs, rhs), - "-" => ctx.llvm_builder.build_sub(lhs, rhs), - "*" => ctx.llvm_builder.build_mul(lhs, rhs), - "/" => ctx.llvm_builder.build_sdiv(lhs, rhs), - "%" => ctx.llvm_builder.build_srem(lhs, rhs), - _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), - }, - PrimitiveType::Int(int_size), - ) - .into() -} - -pub fn codegen_unsigned_ops( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - int_size: PrimitiveType, -) -> ValueTypePair { - ( - match op.as_str() { - "+" => ctx.llvm_builder.build_add(lhs, rhs), - "-" => ctx.llvm_builder.build_sub(lhs, rhs), - "*" => ctx.llvm_builder.build_mul(lhs, rhs), - "/" => ctx.llvm_builder.build_udiv(lhs, rhs), - "%" => ctx.llvm_builder.build_urem(lhs, rhs), - _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), - }, - int_size, - ) - .into() -} diff --git a/comp-be/src/codegen/expr/mod.rs b/comp-be/src/codegen/expr/mod.rs index 5963111..1ba369a 100644 --- a/comp-be/src/codegen/expr/mod.rs +++ b/comp-be/src/codegen/expr/mod.rs @@ -1,143 +1,100 @@ -mod eqne; -use eqne::{codegen_boolean, codegen_eq_ne, codegen_eq_ne_float}; - -mod compare; -use compare::{codegen_compare_float, codegen_compare_signed, codegen_compare_unsigned}; - -mod math; -use math::{codegen_float_ops, codegen_signed_ops, codegen_unsigned_ops}; - -pub mod const_expr; - use crate::{ - codegen::{unit::CompilerContext, CompileError, GenRes, ValueTypePair}, + codegen::{ + builder::value, + unit::{CompilerContext, Mutability, Slot}, + AatbeModule, CompileError, ValueTypePair, + }, fmt::AatbeFmt, + ty::LLVMTyInCtx, }; -use parser::ast::{Expression, FloatSize, IntSize, PrimitiveType}; - -use llvm_sys_wrapper::LLVMValueRef; - -fn dispatch_bool( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, -) -> Option { - match op.as_str() { - "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), - "&&" | "||" => Some(codegen_boolean(ctx, op, lhs, rhs)), - _ => None, - } -} +use parser::ast::{AtomKind, Expression, PrimitiveType, AST}; -fn dispatch_signed( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - int_size: IntSize, -) -> Option { - match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_signed_ops(ctx, op, lhs, rhs, int_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_signed(ctx, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), - _ => None, +pub fn const_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option { + match atom { + AtomKind::StringLiteral(string) => Some(value::str(ctx, string.as_ref())), + AtomKind::CharLiteral(ch) => Some(value::char(ctx, *ch)), + AtomKind::Cast(box AtomKind::Integer(val, _), PrimitiveType::Char) => { + Some(value::char(ctx, *val as u8 as char)) + } + AtomKind::Parenthesized(box atom) => fold_expression(ctx, atom), + _ => panic!("ICE fold_atom {:?}", atom), } } -fn dispatch_float( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - float_size: FloatSize, -) -> Option { - match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_float_ops(ctx, op, lhs, rhs, float_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_float(ctx, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne_float(ctx, op, lhs, rhs)), - _ => None, +fn fold_expression(ctx: &CompilerContext, expr: &Expression) -> Option { + match expr { + Expression::Atom(atom) => const_atom(ctx, atom), + _ => panic!("ICE fold_expression {:?}", expr), } } -fn dispatch_unsigned( - ctx: &CompilerContext, - op: &String, - lhs: LLVMValueRef, - rhs: LLVMValueRef, - int_size: PrimitiveType, -) -> Option { - match op.as_str() { - "+" | "-" | "*" | "/" | "%" => Some(codegen_unsigned_ops(ctx, op, lhs, rhs, int_size)), - ">" | "<" | ">=" | "<=" => Some(codegen_compare_unsigned(ctx, op, lhs, rhs)), - "==" | "!=" => Some(codegen_eq_ne(ctx, op, lhs, rhs)), - _ => None, - } -} +pub fn fold_constant(module: &mut AatbeModule, ast: &AST) -> Option { + /*match ast { + AST::Global { + ty: + PrimitiveType::NamedType { + name, + ty: Some(box ty), + }, + value, + export: _, + } => fold_expression(module, value) + .and_then(|val| { + if val.prim() != ty.inner() { + module.add_error(CompileError::AssignMismatch { + expected_ty: ty.fmt(), + found_ty: val.prim().fmt(), + value: value.fmt(), + var: name.clone(), + }); -pub fn codegen_binary( - module: &mut CompilerContext, - op: &String, - lhs_expr: &Expression, - rhs_expr: &Expression, -) -> GenRes { - todo!() - /*let lhs = module.codegen_expr(lhs_expr).ok_or(CompileError::Handled)?; - let rhs = module.codegen_expr(rhs_expr).ok_or(CompileError::Handled)?; + None + } else { + Some(val) + } + }) + .map(|val| { + let val_ref = module + .llvm_module_ref() + .add_global(ty.llvm_ty_in_ctx(module), name.as_ref()); + module.llvm_module_ref().set_initializer(val_ref, *val); + Slot::Variable { + mutable: Mutability::Global, + name: name.clone(), + ty: val.prim().clone(), + value: val_ref, + } + }), + AST::Constant { + ty: + PrimitiveType::NamedType { + name, + ty: Some(box ty), + }, + value, + export: _, + } => fold_expression(module, value) + .and_then(|val| { + if val.prim() != ty.inner() { + module.add_error(CompileError::AssignMismatch { + expected_ty: ty.fmt(), + found_ty: val.prim().fmt(), + value: value.fmt(), + var: name.clone(), + }); - match (lhs.prim(), rhs.prim()) { - (PrimitiveType::Bool, PrimitiveType::Bool) => match dispatch_bool(ctx, op, *lhs, *rhs) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), + None + } else { + Some(val) + } + }) + .map(|val| Slot::Variable { + mutable: Mutability::Constant, + name: name.clone(), + ty: val.prim().clone(), + value: *val, }), - }, - (PrimitiveType::Char, PrimitiveType::Char) => { - match dispatch_unsigned(ctx, op, *lhs, *rhs, PrimitiveType::Char) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }), - } - } - (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { - match dispatch_unsigned(ctx, op, *lhs, *rhs, PrimitiveType::UInt(lsz.clone())) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }), - } - } - (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { - match dispatch_signed(ctx, op, *lhs, *rhs, lsz.clone()) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }), - } - } - (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { - match dispatch_float(ctx, op, *lhs, *rhs, lsz.clone()) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }), - } - } - _ => Err(CompileError::BinaryMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }), + _ => unreachable!(), }*/ + todo!("{:?}", ast) } diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index cd2b0f2..cff4fba 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -9,9 +9,7 @@ use std::{ use crate::{ codegen::{ - codegen_binary, comp_unit::CompilationUnit, - expr::const_expr::{const_atom, fold_constant}, mangle_v1::NameMangler, unit::{ alloc_variable, declare_and_compile_function, declare_function, init_record, diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index d0dd9a5..e47bf17 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -1,19 +1,31 @@ use parser::ast::{AtomKind, Boolean}; -use crate::codegen::{ - builder::value, - expr::const_expr::const_atom, - unit::{cg::expr, CompilerContext}, - ValueTypePair, +use crate::{ + codegen::{ + builder::value, + expr::const_atom, + unit::{ + cg::{consts, expr}, + CompilerContext, + }, + ValueTypePair, + }, + fmt::AatbeFmt, }; pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { + ctx.trace(format!("Atom {}", atom.fmt())); match atom { AtomKind::Parenthesized(expr) => expr::cg(expr, ctx), AtomKind::Unit => None, AtomKind::Bool(Boolean::True) => Some(value::t(ctx)), AtomKind::Bool(Boolean::False) => Some(value::f(ctx)), - atom @ (AtomKind::StringLiteral(_) | AtomKind::CharLiteral(_)) => const_atom(ctx, atom), + atom + @ + (AtomKind::Integer(..) + | AtomKind::Floating(..) + | AtomKind::Unary(_, box AtomKind::Integer(..))) => consts::numeric::cg(atom, ctx), + atom @ (AtomKind::StringLiteral(..) | AtomKind::CharLiteral(..)) => const_atom(ctx, atom), _ => todo!("{:?}", atom), } } diff --git a/comp-be/src/codegen/unit/cg/binary/bool.rs b/comp-be/src/codegen/unit/cg/binary/bool.rs new file mode 100644 index 0000000..5ebc6db --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/bool.rs @@ -0,0 +1,21 @@ +use crate::codegen::{ + unit::{ + cg::binary::{comp, eqne}, + CompilerContext, + }, + ValueTypePair, +}; +use llvm_sys_wrapper::LLVMValueRef; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> Option { + match op.as_str() { + "==" | "!=" => Some(eqne::cg(lhs, op, rhs, ctx)), + "&&" | "||" => Some(comp::cg(lhs, op, rhs, ctx)), + _ => None, + } +} diff --git a/comp-be/src/codegen/unit/cg/binary/comp.rs b/comp-be/src/codegen/unit/cg/binary/comp.rs new file mode 100644 index 0000000..4a4e66b --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/comp.rs @@ -0,0 +1,20 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "&&" => ctx.llvm_builder.build_and(lhs, rhs), + "||" => ctx.llvm_builder.build_or(lhs, rhs), + _ => panic!("ICE codegen_eq_ne unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/eqne.rs b/comp-be/src/codegen/unit/cg/binary/eqne.rs new file mode 100644 index 0000000..699cd12 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/eqne.rs @@ -0,0 +1,20 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "==" => ctx.llvm_builder.build_icmp_eq(lhs, rhs), + "!=" => ctx.llvm_builder.build_icmp_ne(lhs, rhs), + _ => panic!("ICE codegen_eq_ne unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/float/arith.rs b/comp-be/src/codegen/unit/cg/binary/float/arith.rs new file mode 100644 index 0000000..e9bf790 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/float/arith.rs @@ -0,0 +1,24 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::{FloatSize, PrimitiveType}; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + float_size: FloatSize, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "+" => ctx.llvm_builder.build_fadd(lhs, rhs), + "-" => ctx.llvm_builder.build_fsub(lhs, rhs), + "*" => ctx.llvm_builder.build_fmul(lhs, rhs), + "/" => ctx.llvm_builder.build_fdiv(lhs, rhs), + "%" => ctx.llvm_builder.build_frem(lhs, rhs), + _ => panic!("ICE codegen_float_ops unhandled op {}", op), + }, + PrimitiveType::Float(float_size), + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/float/cmp.rs b/comp-be/src/codegen/unit/cg/binary/float/cmp.rs new file mode 100644 index 0000000..5d10688 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/float/cmp.rs @@ -0,0 +1,20 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "==" => ctx.llvm_builder.build_fcmp_ueq(lhs, rhs), + "!=" => ctx.llvm_builder.build_fcmp_une(lhs, rhs), + _ => panic!("ICE codegen_eq_ne_float unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/float/eqne.rs b/comp-be/src/codegen/unit/cg/binary/float/eqne.rs new file mode 100644 index 0000000..33c4a0c --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/float/eqne.rs @@ -0,0 +1,22 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "<" => ctx.llvm_builder.build_fcmp_ult(lhs, rhs), + ">" => ctx.llvm_builder.build_fcmp_ugt(lhs, rhs), + "<=" => ctx.llvm_builder.build_fcmp_ule(lhs, rhs), + ">=" => ctx.llvm_builder.build_fcmp_uge(lhs, rhs), + _ => panic!("ICE codegen_compare_float unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/float/mod.rs b/comp-be/src/codegen/unit/cg/binary/float/mod.rs new file mode 100644 index 0000000..5f79704 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/float/mod.rs @@ -0,0 +1,22 @@ +mod arith; +mod cmp; +mod eqne; + +use crate::codegen::{unit::CompilerContext, ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::FloatSize; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + float_size: FloatSize, + ctx: &CompilerContext, +) -> Option { + match op.as_str() { + "+" | "-" | "*" | "/" | "%" => Some(arith::cg(lhs, op, rhs, float_size, ctx)), + ">" | "<" | ">=" | "<=" => Some(cmp::cg(lhs, op, rhs, ctx)), + "==" | "!=" => Some(eqne::cg(lhs, op, rhs, ctx)), + _ => None, + } +} diff --git a/comp-be/src/codegen/unit/cg/binary/int/arith.rs b/comp-be/src/codegen/unit/cg/binary/int/arith.rs new file mode 100644 index 0000000..413ef73 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/int/arith.rs @@ -0,0 +1,24 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::{IntSize, PrimitiveType}; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + int_size: IntSize, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "+" => ctx.llvm_builder.build_add(lhs, rhs), + "-" => ctx.llvm_builder.build_sub(lhs, rhs), + "*" => ctx.llvm_builder.build_mul(lhs, rhs), + "/" => ctx.llvm_builder.build_sdiv(lhs, rhs), + "%" => ctx.llvm_builder.build_srem(lhs, rhs), + _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), + }, + PrimitiveType::Int(int_size), + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/int/cmp.rs b/comp-be/src/codegen/unit/cg/binary/int/cmp.rs new file mode 100644 index 0000000..eb34db2 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/int/cmp.rs @@ -0,0 +1,22 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "<" => ctx.llvm_builder.build_icmp_slt(lhs, rhs), + ">" => ctx.llvm_builder.build_icmp_sgt(lhs, rhs), + "<=" => ctx.llvm_builder.build_icmp_sle(lhs, rhs), + ">=" => ctx.llvm_builder.build_icmp_sge(lhs, rhs), + _ => panic!("ICE codegen_compare_signed unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/int/mod.rs b/comp-be/src/codegen/unit/cg/binary/int/mod.rs new file mode 100644 index 0000000..d061784 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/int/mod.rs @@ -0,0 +1,24 @@ +mod arith; +mod cmp; + +use crate::codegen::{ + unit::{cg::binary::eqne, CompilerContext}, + ValueTypePair, +}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::IntSize; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + int_size: IntSize, + ctx: &CompilerContext, +) -> Option { + match op.as_str() { + "+" | "-" | "*" | "/" | "%" => Some(arith::cg(lhs, op, rhs, int_size, ctx)), + ">" | "<" | ">=" | "<=" => Some(cmp::cg(lhs, op, rhs, ctx)), + "==" | "!=" => Some(eqne::cg(lhs, op, rhs, ctx)), + _ => None, + } +} diff --git a/comp-be/src/codegen/unit/cg/binary/mod.rs b/comp-be/src/codegen/unit/cg/binary/mod.rs new file mode 100644 index 0000000..bf07cb6 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/mod.rs @@ -0,0 +1,89 @@ +mod bool; +mod comp; +mod eqne; +mod float; +mod int; +mod uint; + +use parser::ast::{Expression, IntSize, PrimitiveType}; + +use crate::{ + codegen::{ + unit::{cg::expr, CompilerContext}, + CompileError, GenRes, + }, + fmt::AatbeFmt, +}; + +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { + if let Expression::Binary(box lh, op, box rh) = expr { + let lhs = expr::cg(lh, ctx).ok_or(CompileError::Handled)?; + let rhs = expr::cg(rh, ctx).ok_or(CompileError::Handled)?; + + match (lhs.prim(), rhs.prim()) { + (PrimitiveType::Bool, PrimitiveType::Bool) => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match bool::cg(*lhs, op, *rhs, ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), + } + } + (PrimitiveType::Char, PrimitiveType::Char) => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match uint::cg(*lhs, op, *rhs, IntSize::Bits8, ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), + } + } + (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match uint::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), + } + } + (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match int::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), + } + } + (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match float::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), + } + } + _ => todo!("{:?} {} {:?}", lh, op, rh), + /*_ => Err(CompileError::BinaryMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lhs_expr.fmt(), rhs_expr.fmt()), + }),*/ + } + } else { + panic!("ICE") + } +} diff --git a/comp-be/src/codegen/unit/cg/binary/uint/arith.rs b/comp-be/src/codegen/unit/cg/binary/uint/arith.rs new file mode 100644 index 0000000..a7b9635 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/uint/arith.rs @@ -0,0 +1,24 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::{IntSize, PrimitiveType}; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ty: IntSize, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "+" => ctx.llvm_builder.build_add(lhs, rhs), + "-" => ctx.llvm_builder.build_sub(lhs, rhs), + "*" => ctx.llvm_builder.build_mul(lhs, rhs), + "/" => ctx.llvm_builder.build_udiv(lhs, rhs), + "%" => ctx.llvm_builder.build_urem(lhs, rhs), + _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), + }, + PrimitiveType::UInt(ty), + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs b/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs new file mode 100644 index 0000000..1bf5ff1 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs @@ -0,0 +1,22 @@ +use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::PrimitiveType; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ctx: &CompilerContext, +) -> ValueTypePair { + ( + match op.as_str() { + "<" => ctx.llvm_builder.build_icmp_ult(lhs, rhs), + ">" => ctx.llvm_builder.build_icmp_ugt(lhs, rhs), + "<=" => ctx.llvm_builder.build_icmp_ule(lhs, rhs), + ">=" => ctx.llvm_builder.build_icmp_uge(lhs, rhs), + _ => panic!("ICE codegen_compare_unsigned unhandled op {}", op), + }, + PrimitiveType::Bool, + ) + .into() +} diff --git a/comp-be/src/codegen/unit/cg/binary/uint/mod.rs b/comp-be/src/codegen/unit/cg/binary/uint/mod.rs new file mode 100644 index 0000000..a127a3a --- /dev/null +++ b/comp-be/src/codegen/unit/cg/binary/uint/mod.rs @@ -0,0 +1,24 @@ +mod arith; +mod cmp; + +use crate::codegen::{ + unit::{cg::binary::eqne, CompilerContext}, + ValueTypePair, +}; +use llvm_sys_wrapper::LLVMValueRef; +use parser::ast::IntSize; + +pub fn cg( + lhs: LLVMValueRef, + op: &String, + rhs: LLVMValueRef, + ty: IntSize, + ctx: &CompilerContext, +) -> Option { + match op.as_str() { + "+" | "-" | "*" | "/" | "%" => Some(arith::cg(lhs, op, rhs, ty, ctx)), + ">" | "<" | ">=" | "<=" => Some(cmp::cg(lhs, op, rhs, ctx)), + "==" | "!=" => Some(eqne::cg(lhs, op, rhs, ctx)), + _ => None, + } +} diff --git a/comp-be/src/codegen/unit/cg/consts/mod.rs b/comp-be/src/codegen/unit/cg/consts/mod.rs new file mode 100644 index 0000000..4375cad --- /dev/null +++ b/comp-be/src/codegen/unit/cg/consts/mod.rs @@ -0,0 +1 @@ +pub mod numeric; diff --git a/comp-be/src/codegen/unit/cg/consts/numeric.rs b/comp-be/src/codegen/unit/cg/consts/numeric.rs new file mode 100644 index 0000000..29e086b --- /dev/null +++ b/comp-be/src/codegen/unit/cg/consts/numeric.rs @@ -0,0 +1,28 @@ +use parser::ast::{AtomKind, PrimitiveType}; + +use crate::codegen::{builder::value, unit::CompilerContext, ValueTypePair}; + +pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { + match atom { + AtomKind::Integer(val, PrimitiveType::Int(size)) => { + Some(value::sint(ctx, size.clone(), *val)) + } + AtomKind::Integer(val, PrimitiveType::UInt(size)) => { + Some(value::uint(ctx, size.clone(), *val)) + } + AtomKind::Floating(val, PrimitiveType::Float(size)) => { + Some(value::floating(ctx, size.clone(), *val)) + } + AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::Int(size))) + if op == &String::from("-") => + { + Some(value::sint(ctx, size.clone(), (-(*val as i64)) as u64)) + } + AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::UInt(size))) + if op == &String::from("-") => + { + Some(value::uint(ctx, size.clone(), (-(*val as i64)) as u64)) + } + _ => panic!("ICE Atom {:?}", atom), + } +} diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 9f7154c..dc11887 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -2,7 +2,7 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ unit::{ - cg::{atom, call}, + cg::{atom, binary, call}, declare_and_compile_function, CompilerContext, Message, }, ValueTypePair, @@ -10,6 +10,7 @@ use crate::codegen::{ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { + Expression::Binary(..) => Some(binary::cg(expr, ctx).ok().expect("todo")), Expression::Call { .. } => call::cg(expr, ctx), Expression::Atom(atom) => atom::cg(atom, ctx), Expression::Function { ty, type_names, .. } if type_names.len() == 0 => match ty { diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs index e257bb2..54848c6 100644 --- a/comp-be/src/codegen/unit/cg/mod.rs +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -4,7 +4,9 @@ use parser::ast::AST; use super::{CompilerContext, Message}; pub mod atom; +pub mod binary; pub mod call; +pub mod consts; pub mod expr; pub fn cg(ast: &AST, ctx: &CompilerContext) -> Option { diff --git a/main.aat b/main.aat index b669c2f..d9f8501 100644 --- a/main.aat +++ b/main.aat @@ -4,5 +4,5 @@ module libc { @entry fn main () = { - libc::printf "Hello World!\n" + libc::printf "%d\n", '8' - '0' } From fa11b9f118686ec839c2924ca1a4d98955840493 Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 20 Mar 2021 20:19:33 +0200 Subject: [PATCH 12/18] The One With Modules XII --- comp-be/src/codegen/atom.rs | 11 --- comp-be/src/codegen/builder/branch.rs | 10 +- comp-be/src/codegen/scope.rs | 25 +++-- comp-be/src/codegen/unit/cg/atom.rs | 18 +++- comp-be/src/codegen/unit/cg/binary/mod.rs | 7 +- .../src/codegen/unit/cg/conditional/ifelse.rs | 95 ++++++++++++++++++ .../src/codegen/unit/cg/conditional/mod.rs | 1 + comp-be/src/codegen/unit/cg/expr.rs | 3 +- comp-be/src/codegen/unit/cg/mod.rs | 1 + comp-be/src/codegen/unit/compiler.rs | 99 +++++++++++++++---- comp-be/src/codegen/unit/function.rs | 83 ++++++---------- comp-be/src/codegen/unit/mod.rs | 14 +++ comp-be/src/fmt.rs | 2 +- main.aat | 6 +- main.aat.bak | 4 + parser/src/ast.rs | 1 + parser/src/parser/conditionals.rs | 17 +++- parser/src/parser/pass/type_resolution.rs | 5 + parser/src/tests.rs | 54 ++++++++++ 19 files changed, 342 insertions(+), 114 deletions(-) create mode 100644 comp-be/src/codegen/unit/cg/conditional/ifelse.rs create mode 100644 comp-be/src/codegen/unit/cg/conditional/mod.rs diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index 2228d5d..a2c1ead 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -165,17 +165,6 @@ impl AatbeModule { .into(), ) } - AtomKind::Ident(name) => { - let var_ref = self.get_var(name)?; - - match var_ref.var_ty() { - ty @ PrimitiveType::Newtype(_) | ty @ PrimitiveType::VariantType(_) => { - let val: ValueTypePair = var_ref.into(); - Some((*val, ty).into()) - } - ty => Some((var_ref.load_var(self.llvm_builder_ref()), ty).into()), - } - } AtomKind::Ref(box AtomKind::Ident(name)) => { let var_ref = self.get_var(name)?; diff --git a/comp-be/src/codegen/builder/branch.rs b/comp-be/src/codegen/builder/branch.rs index b9c3c8f..2bfcf8b 100644 --- a/comp-be/src/codegen/builder/branch.rs +++ b/comp-be/src/codegen/builder/branch.rs @@ -1,17 +1,15 @@ use crate::codegen::unit::CompilerContext; use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMValueRef}; -pub fn branch(module: &CompilerContext, block: LLVMBasicBlockRef) -> LLVMValueRef { - module.llvm_builder.build_br(block) +pub fn branch(ctx: &CompilerContext, block: LLVMBasicBlockRef) -> LLVMValueRef { + ctx.llvm_builder.build_br(block) } pub fn cond_branch( - module: &CompilerContext, + ctx: &CompilerContext, cond: LLVMValueRef, then_block: LLVMBasicBlockRef, else_block: LLVMBasicBlockRef, ) -> LLVMValueRef { - module - .llvm_builder - .build_cond_br(cond, then_block, else_block) + ctx.llvm_builder.build_cond_br(cond, then_block, else_block) } diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index df5e444..74f49e0 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -1,9 +1,6 @@ -use crate::codegen::{ - unit::{ - function::{find_func, Func, FuncTyMap, FunctionMap}, - Slot, - }, - AatbeModule, +use crate::codegen::unit::{ + function::{find_func, Func, FuncTyMap, FunctionMap}, + CompilerUnit, Slot, }; use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc}; @@ -15,7 +12,7 @@ pub struct Scope { refs: HashMap, functions: FunctionMap, name: String, - function: Option<(String, FunctionType)>, + function: Option<(Vec, FunctionType)>, fdir: Option, } @@ -59,11 +56,11 @@ impl Scope { fdir: Some(fdir.into()), } } - pub fn with_function(func: (String, FunctionType), builder: Builder) -> Self { + pub fn with_function(func: (Vec, FunctionType), builder: Builder) -> Self { Self { refs: HashMap::new(), functions: HashMap::new(), - name: func.0.clone(), + name: func.0.join("::"), function: Some(func), fdir: None, } @@ -91,7 +88,7 @@ impl Scope { pub fn add_symbol(&mut self, name: &String, unit: Slot) { self.refs.insert(name.clone(), unit); } - pub fn function(&self) -> Option<(String, FunctionType)> { + pub fn function(&self) -> Option<(Vec, FunctionType)> { self.function.clone() } pub fn fdir(&self) -> Option { @@ -102,15 +99,17 @@ impl Scope { self.name.clone() } - /*pub fn bb(&self, module: &AatbeModule, name: &String) -> Option { + pub fn bb(&self, module: &CompilerUnit, name: &str) -> Option { let func = self.function.as_ref()?; Some( find_func(module.get_func_group(&func.0)?, &func.1) .unwrap() - .append_basic_block(name.as_ref()), + .upgrade() + .expect("ICE") + .append_basic_block(name), ) - }*/ + } } /* TODO: Implement local dropping diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index e47bf17..d95b120 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -1,4 +1,4 @@ -use parser::ast::{AtomKind, Boolean}; +use parser::ast::{AtomKind, Boolean, PrimitiveType}; use crate::{ codegen::{ @@ -6,7 +6,7 @@ use crate::{ expr::const_atom, unit::{ cg::{consts, expr}, - CompilerContext, + CompilerContext, Query, QueryResponse, }, ValueTypePair, }, @@ -26,6 +26,20 @@ pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { | AtomKind::Floating(..) | AtomKind::Unary(_, box AtomKind::Integer(..))) => consts::numeric::cg(atom, ctx), atom @ (AtomKind::StringLiteral(..) | AtomKind::CharLiteral(..)) => const_atom(ctx, atom), + AtomKind::Ident(name) => { + if let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) { + let slot = slot?; + match slot.var_ty().clone() { + ty @ PrimitiveType::Newtype(_) | ty @ PrimitiveType::VariantType(_) => { + let val: ValueTypePair = slot.into(); + Some((*val, ty).into()) + } + ty => Some((slot.load_var(ctx.llvm_builder), ty).into()), + } + } else { + panic!("ICE") + } + } _ => todo!("{:?}", atom), } } diff --git a/comp-be/src/codegen/unit/cg/binary/mod.rs b/comp-be/src/codegen/unit/cg/binary/mod.rs index bf07cb6..38bd031 100644 --- a/comp-be/src/codegen/unit/cg/binary/mod.rs +++ b/comp-be/src/codegen/unit/cg/binary/mod.rs @@ -76,12 +76,11 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { }), } } - _ => todo!("{:?} {} {:?}", lh, op, rh), - /*_ => Err(CompileError::BinaryMismatch { + _ => Err(CompileError::BinaryMismatch { op: op.clone(), types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lhs_expr.fmt(), rhs_expr.fmt()), - }),*/ + values: (lh.fmt(), rh.fmt()), + }), } } else { panic!("ICE") diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs new file mode 100644 index 0000000..a24514e --- /dev/null +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -0,0 +1,95 @@ +use crate::codegen::{ + builder::{branch, core}, + unit::{cg::expr, CompilerContext, Message}, + ValueTypePair, +}; +use llvm_sys_wrapper::LLVMBasicBlockRef; +use parser::ast::{Expression, PrimitiveType}; + +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { + if let Expression::If { + cond_expr, + then_expr, + elseif_exprs, + else_expr, + is_expr, + } = expr + { + if *is_expr { + todo!("If ret"); + } + + let then_bb = ctx.basic_block("then"); + let elseif_bbs = elseif_exprs + .iter() + .map(|e| { + ( + ( + ctx.basic_block("elseif_cond"), + ctx.basic_block("elseif_body"), + ), + e, + ) + }) + .collect::>(); + let else_bb = else_expr.as_ref().map(|_| ctx.basic_block("else")); + let end_bb = ctx.basic_block("end"); + + ctx.dispatch(Message::EnterAnonymousScope); + ctx.trace(format!("If {:?}", cond_expr)); + let cond = expr::cg(cond_expr, ctx)?; + + if *cond.prim().inner() != PrimitiveType::Bool { + todo!("NOT A BOOL"); + } + + let next_bb = |i: usize| -> LLVMBasicBlockRef { + elseif_bbs + .get(i) + .map(|e| e.0 .0) + .unwrap_or(else_bb.unwrap_or(end_bb)) + }; + + branch::cond_branch(ctx, *cond, then_bb, next_bb(0)); + + let elseif_vals = elseif_bbs + .iter() + .enumerate() + .map(|(i, ((bb_cond, bb_body), (cond, expr)))| { + ctx.trace(format!("Else If {:?}", cond)); + core::pos_at_end(ctx, *bb_cond); + + let cond = expr::cg(cond, ctx)?; + branch::cond_branch(ctx, *cond, *bb_body, next_bb(i + 1)); + + core::pos_at_end(ctx, *bb_body); + let val = expr::cg(expr, ctx); + branch::branch(ctx, end_bb); + + val + }) + .collect::>(); + + core::pos_at_end(ctx, then_bb); + let then_val = expr::cg(then_expr, ctx); + + let else_val = else_bb + .map(|bb| { + ctx.trace("Else".to_string()); + branch::branch(ctx, end_bb); + core::pos_at_end(ctx, bb); + + else_expr.as_ref().and_then(|expr| expr::cg(&expr, ctx)) + }) + .flatten(); + + ctx.dispatch(Message::ExitScope); + + branch::branch(ctx, end_bb); + + core::pos_at_end(ctx, end_bb); + None + } else { + panic!("ICE") + } +} diff --git a/comp-be/src/codegen/unit/cg/conditional/mod.rs b/comp-be/src/codegen/unit/cg/conditional/mod.rs new file mode 100644 index 0000000..4f1a6ac --- /dev/null +++ b/comp-be/src/codegen/unit/cg/conditional/mod.rs @@ -0,0 +1 @@ +pub mod ifelse; diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index dc11887..85214e1 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -2,7 +2,7 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ unit::{ - cg::{atom, binary, call}, + cg::{atom, binary, call, conditional}, declare_and_compile_function, CompilerContext, Message, }, ValueTypePair, @@ -10,6 +10,7 @@ use crate::codegen::{ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { + Expression::If { .. } => conditional::ifelse::cg(expr, ctx), Expression::Binary(..) => Some(binary::cg(expr, ctx).ok().expect("todo")), Expression::Call { .. } => call::cg(expr, ctx), Expression::Atom(atom) => atom::cg(atom, ctx), diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs index 54848c6..212d80e 100644 --- a/comp-be/src/codegen/unit/cg/mod.rs +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -6,6 +6,7 @@ use super::{CompilerContext, Message}; pub mod atom; pub mod binary; pub mod call; +pub mod conditional; pub mod consts; pub mod expr; diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index 0b90e81..6ed766b 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -1,12 +1,6 @@ -use std::{ - cell::RefCell, - collections::HashMap, - path::PathBuf, - rc::Weak, - sync::atomic::{AtomicUsize, Ordering}, -}; +use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Weak}; -use llvm_sys_wrapper::{Builder, Context, LLVMValueRef, Module}; +use llvm_sys_wrapper::{Builder, Context, LLVMBasicBlock, LLVMBasicBlockRef, LLVMValueRef, Module}; use parser::ast::{Expression, FunctionType, AST}; use crate::{ @@ -18,17 +12,19 @@ use crate::{ ty::TypeContext, }; -use super::function::{Func, FuncTyMap}; - -use log::*; +use super::{ + function::{Func, FuncTyMap}, + Slot, +}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum FunctionVisibility { Local, - Export, + Public, } pub enum Message { + PushInScope(String, Slot), DeclareFunction(Vec, Func, FunctionVisibility), EnterFunctionScope((String, FunctionType)), EnterModuleScope(String), @@ -40,7 +36,12 @@ pub enum Message { impl std::fmt::Debug for Message { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { + match &self { + Message::PushInScope(name, slot) => f + .debug_tuple("PushInScope") + .field(name) + .field(slot) + .finish(), Message::DeclareFunction(name, ty, vis) => f .debug_tuple("DeclareFunction") .field(name) @@ -68,6 +69,7 @@ impl std::fmt::Debug for Message { } pub enum Query<'cmd> { + Slot(&'cmd String), Function((Vec, &'cmd FunctionType)), FunctionGroup(Vec), Prefix, @@ -76,6 +78,7 @@ pub enum Query<'cmd> { impl std::fmt::Debug for Query<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Query::Slot(name) => f.debug_tuple("Slot").field(name).finish(), Query::Function(func) => f .debug_tuple("Function") .field(&func.0.join("::")) @@ -88,6 +91,7 @@ impl std::fmt::Debug for Query<'_> { } pub enum QueryResponse { + Slot(Option), Function(Option>), FunctionGroup(Option>), Prefix(Vec), @@ -96,6 +100,7 @@ pub enum QueryResponse { impl std::fmt::Debug for QueryResponse { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + QueryResponse::Slot(slot) => f.debug_tuple("Slot").field(slot).finish(), QueryResponse::Function(ref func) => f .debug_tuple("Function") .field( @@ -131,6 +136,7 @@ pub struct CompilerContext<'ctx> { dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, trace: &'ctx dyn Fn(String) -> (), + basic_block: &'ctx dyn Fn(&str) -> LLVMBasicBlockRef, } impl<'ctx> CompilerContext<'ctx> { @@ -142,6 +148,7 @@ impl<'ctx> CompilerContext<'ctx> { dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, trace: &'ctx dyn Fn(String) -> (), + basic_block: &'ctx dyn Fn(&str) -> LLVMBasicBlockRef, ) -> Self where P: Into, @@ -154,6 +161,7 @@ impl<'ctx> CompilerContext<'ctx> { dispatch, query, trace, + basic_block, function_templates: HashMap::new(), } } @@ -167,10 +175,15 @@ impl<'ctx> CompilerContext<'ctx> { dispatch: self.dispatch, query: self.query, trace: self.trace, + basic_block: self.basic_block, function_templates: HashMap::new(), } } + pub fn basic_block(&self, name: &str) -> LLVMBasicBlockRef { + (self.basic_block)(name) + } + pub fn trace(&self, message: String) { (self.trace)(message) } @@ -199,7 +212,7 @@ impl<'ctx> CompilerContext<'ctx> { pub struct CompilerUnit<'ctx> { modules: HashMap>, ast: Box, - typectx: TypeContext, + _typectx: TypeContext, llvm_context: &'ctx Context, llvm_module: &'ctx Module, scope_stack: RefCell>, @@ -224,7 +237,7 @@ impl<'ctx> CompilerUnit<'ctx> { llvm_context, llvm_module, modules: HashMap::new(), - typectx: TypeContext::new(), + _typectx: TypeContext::new(), scope_stack: RefCell::new(vec![]), module_scopes: RefCell::new(HashMap::new()), ident: RefCell::new(0), @@ -253,9 +266,12 @@ impl<'ctx> CompilerUnit<'ctx> { } fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { + let mut prefix = self.get_prefix(); + prefix.push(func.0); + self.scope_stack .borrow_mut() - .push(Scope::with_function(func, builder)); + .push(Scope::with_function((prefix, func.1), builder)); } fn enter_module_scope(&self, name: String) { @@ -280,6 +296,34 @@ impl<'ctx> CompilerUnit<'ctx> { self.scope_stack.borrow_mut().push(scope); } + pub fn push_in_scope(&self, name: &String, unit: Slot) { + self.scope_stack + .borrow_mut() + .last_mut() + .expect("Compiler broke. Scope stack is corrupted.") + .add_symbol(name, unit); + } + + pub fn get_from_scope(&self, name: &String) -> Option { + for scope in self.scope_stack.borrow().iter().rev() { + if let Some(sym) = scope.find_symbol(name) { + return Some(sym.clone()); + } + } + + None + } + + pub fn get_slot(&self, name: &String) -> Option { + if let Some(slot @ (Slot::Variable { .. } | Slot::FunctionArgument(..))) = + self.get_from_scope(name) + { + Some(slot) + } else { + None + } + } + fn exit_scope(&self) { self.scope_stack .borrow_mut() @@ -290,6 +334,10 @@ impl<'ctx> CompilerUnit<'ctx> { fn dispatch(&self, message: Message) { print!("{}", "│ ".repeat(*self.ident.borrow())); match message { + Message::PushInScope(ref name, ref unit) => { + println!("├── {:?}", message); + self.push_in_scope(name, unit.clone()); + } Message::DeclareFunction(ref name, ref func, ty) => { println!("├── {:?}", message); let mut scope_stack = self.scope_stack.borrow_mut(); @@ -340,8 +388,9 @@ impl<'ctx> CompilerUnit<'ctx> { println!("├── Query {:?}", query); let response = match query { Query::Function(func) => QueryResponse::Function(self.get_func(func)), - Query::FunctionGroup(name) => QueryResponse::FunctionGroup(self.get_func_group(name)), + Query::FunctionGroup(name) => QueryResponse::FunctionGroup(self.get_func_group(&name)), Query::Prefix => QueryResponse::Prefix(self.get_prefix()), + Query::Slot(name) => QueryResponse::Slot(self.get_slot(name)), }; print!("{}", "│ ".repeat(*self.ident.borrow())); println!("├── Response {:?}", response); @@ -370,6 +419,7 @@ impl<'ctx> CompilerUnit<'ctx> { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); let trace = &|message: String| self.trace(message); + let basic_block = &|name: &str| self.basic_block(name); decl::decl( &*ast, @@ -381,6 +431,7 @@ impl<'ctx> CompilerUnit<'ctx> { dispatch, query, trace, + basic_block, ), ); } @@ -390,6 +441,7 @@ impl<'ctx> CompilerUnit<'ctx> { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); let trace = &|message: String| self.trace(message); + let basic_block = &|name: &str| self.basic_block(name); cg::cg( &*ast, @@ -401,11 +453,12 @@ impl<'ctx> CompilerUnit<'ctx> { dispatch, query, trace, + basic_block, ), ) } - pub fn get_func_group(&self, name: Vec) -> Option> { + pub fn get_func_group(&self, name: &Vec) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { if let Some(func) = scope.func_by_name(&name) { return Some(func); @@ -437,6 +490,16 @@ impl<'ctx> CompilerUnit<'ctx> { .filter(|n| n != &String::default()) .collect::>() } + + pub fn basic_block(&self, name: &str) -> LLVMBasicBlockRef { + for scope in self.scope_stack.borrow().iter().rev() { + let bb = scope.bb(self, &name); + if let Some(bb) = bb { + return bb; + } + } + panic!("Compiler broke. Scope stack is corrupted."); + } } #[macro_export] diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 2e6e2f8..f11c2b7 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -7,7 +7,7 @@ use crate::{ cg::expr, CompilerContext, FunctionVisibility, Message, Mutability, Query, QueryResponse, Slot, }, - AatbeModule, CompileError, ValueTypePair, + CompileError, ValueTypePair, }, fmt::AatbeFmt, prefix, @@ -157,7 +157,7 @@ pub fn declare_function(ctx: &CompilerContext, function: &Expression) { ctx.dispatch(Message::DeclareFunction( name, func, - FunctionVisibility::Export, + FunctionVisibility::Public, )); } } @@ -178,6 +178,8 @@ pub fn declare_and_compile_function<'ctx>( } => None, _ => { ctx.in_function_scope((name.clone(), ty.clone()), |ctx| { + inject_function_in_scope(&ctx, func); + codegen_function(&ctx, func); let ret_val = expr::cg( @@ -196,49 +198,18 @@ pub fn declare_and_compile_function<'ctx>( _ => core::ret(&ctx, val), }; } else { + // TODO: Error + /* + module.add_error(CompileError::ExpectedReturn { + function: func.clone().fmt(), + ty: ty.fmt(), + }) */ todo!() } } None }) - /* - inject_function_in_scope(module, func); - let ret_val = module.codegen_expr( - &body - .as_ref() - .expect("ICE Function with no body but not external"), - ); - - // TODO: Typechecks - if has_return_type(ty) { - if let Some(val) = ret_val { - match val.prim() { - PrimitiveType::VariantType(variant) => { - let parent_ty = module - .typectx_ref() - .get_parent_for_variant(variant) - .expect("ICE: Variant without parent"); - let ret_ty = *ty.ret_ty.clone(); - core::ret( - module, - (cast::child_to_parent(module, val, parent_ty), ret_ty) - .into(), - ) - } - _ => core::ret(module, val), - }; - } else { - module.add_error(CompileError::ExpectedReturn { - function: func.clone().fmt(), - ty: ty.fmt(), - }) - } - } else { - core::ret_void(module); - } - - module.exit_scope();*/ } }, _ => unreachable!(), @@ -274,9 +245,8 @@ pub fn codegen_function(ctx: &CompilerContext, function: &Expression) { } } -pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) { - todo!() - /*match function { +pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { + match function { Expression::Function { name: fname, ty, .. } => { @@ -305,7 +275,7 @@ pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) | box PrimitiveType::Array { .. }, ), } => { - let arg = module + /*let arg = module .get_func((fname.clone(), fty.clone())) .expect("Compiler borked. Functions borked") .get_param(pos as u32); @@ -326,22 +296,25 @@ pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) ty: ty.clone(), value: ptr, }, - ); + );*/ + todo!() } PrimitiveType::NamedType { name, ty: Some(box PrimitiveType::Ref(ty) | ty), } => { - module.push_in_scope( - name, - Slot::FunctionArgument( - module - .get_func((fname.clone(), fty.clone())) - .expect("Compiler borked. Functions borked") - .get_param(pos as u32), - *ty.clone(), - ), - ); + if let QueryResponse::Function(Some(func)) = + ctx.query(Query::Function((prefix!(ctx), fty))) + { + let func = func.upgrade().expect("ICE"); + ctx.dispatch(Message::PushInScope( + name.clone(), + Slot::FunctionArgument( + func.get_param(pos as u32), + *ty.clone(), + ), + )) + } } PrimitiveType::Unit | PrimitiveType::Symbol(_) => {} _ => unimplemented!("{:?}", ty), @@ -352,7 +325,7 @@ pub fn inject_function_in_scope(module: &mut AatbeModule, function: &Expression) }; } _ => unreachable!(), - }*/ + } } fn has_return_type(func: &FunctionType) -> bool { diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 6382daa..3f74256 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -65,6 +65,20 @@ impl Into for &Slot { } } +impl Into for Slot { + fn into(self) -> ValueTypePair { + match self { + Slot::FunctionArgument(arg, ty) => (arg, ty).into(), + Slot::Variable { + mutable: _, + name: _, + ty, + value, + } => (value, ty).into(), + } + } +} + impl Into for &Slot { fn into(self) -> LLVMValueRef { match self { diff --git a/comp-be/src/fmt.rs b/comp-be/src/fmt.rs index df839dd..0517bb8 100644 --- a/comp-be/src/fmt.rs +++ b/comp-be/src/fmt.rs @@ -106,7 +106,7 @@ impl AatbeFmt for &AtomKind { fn fmt(self) -> String { match self { AtomKind::StringLiteral(lit) => format!("{:?}", lit), - AtomKind::CharLiteral(lit) => format!("{}", lit), + AtomKind::CharLiteral(lit) => format!("{:?}", lit), AtomKind::Integer(val, ty) => format!("{}{}", val, ty.fmt()), AtomKind::Floating(val, ty) => format!("{}{}", val, ty.fmt()), AtomKind::Bool(Boolean::True) => String::from("true"), diff --git a/main.aat b/main.aat index d9f8501..d57a57f 100644 --- a/main.aat +++ b/main.aat @@ -4,5 +4,7 @@ module libc { @entry fn main () = { - libc::printf "%d\n", '8' - '0' -} + if false then libc::printf "true\n" + else if true then libc::printf "false\n" + else libc::printf "wtf\n" +} \ No newline at end of file diff --git a/main.aat.bak b/main.aat.bak index 9678ebb..75b2a61 100644 --- a/main.aat.bak +++ b/main.aat.bak @@ -1,3 +1,7 @@ +module libc { + public extern fn printf str, ... -> i32 +} + fn test() -> () = () @entry diff --git a/parser/src/ast.rs b/parser/src/ast.rs index b7a1a38..a5313b2 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -71,6 +71,7 @@ pub enum Expression { If { cond_expr: Box, then_expr: Box, + elseif_exprs: Vec<(Expression, Expression)>, else_expr: Option>, is_expr: bool, }, diff --git a/parser/src/parser/conditionals.rs b/parser/src/parser/conditionals.rs index 0126b43..0d97e76 100644 --- a/parser/src/parser/conditionals.rs +++ b/parser/src/parser/conditionals.rs @@ -16,7 +16,21 @@ impl Parser { box capture!(self, parse_expression).ok_or(ParseError::ExpectedThenExpression)?; let mut else_expr = None; - let has_else = kw!(bool Else, self); + let mut chain = vec![]; + + let mut has_else = false; + while kw!(bool Else, self) && { + has_else = !kw!(bool If, self); + !has_else + } { + let cond_expr = + capture!(self, parse_expression).ok_or(ParseError::ExpectedCondition)?; + kw!(bool Then, self); + let then_expr = + capture!(self, parse_expression).ok_or(ParseError::ExpectedThenExpression)?; + + chain.push((cond_expr, then_expr)); + } if has_else { else_expr = @@ -26,6 +40,7 @@ impl Parser { Ok(Expression::If { cond_expr, then_expr, + elseif_exprs: chain, else_expr, is_expr, }) diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 2dd2d57..358e072 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -96,11 +96,16 @@ fn resolve_expr(variants: &Vec, ast: &Expression) -> Expression { Expression::If { is_expr, cond_expr: box cond_expr, + elseif_exprs, else_expr, then_expr: box then_expr, } => Expression::If { is_expr: *is_expr, cond_expr: box resolve_expr(variants, cond_expr), + elseif_exprs: elseif_exprs + .iter() + .map(|(cond, block)| (resolve_expr(variants, cond), resolve_expr(variants, block))) + .collect(), else_expr: else_expr .as_ref() .map(|box ex| box resolve_expr(variants, &ex)), diff --git a/parser/src/tests.rs b/parser/src/tests.rs index 41abe93..d377cdc 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -1,5 +1,6 @@ #[cfg(test)] mod parser_tests { + use crate::ast::AST::Expr; use crate::{ ast::{AtomKind, BindType, Boolean, FunctionType, IdentPath, IntSize, LValue, TypeKind}, lexer::{token::Token, Lexer}, @@ -434,6 +435,56 @@ fn main () -> () = { ); } + #[test] + fn if_else_if() { + let pt = parse_test!( + " +@entry +fn main () = { + if true then false + else if false then true + else if !false then false + else false +} +", + "If Else If chain" + ); + + assert_eq!( + pt, + AST::File(vec![AST::Expr(Expression::Function { + name: "main".to_string(), + attributes: attr(vec!["entry"]), + type_names: vec![], + public: false, + body: Some(box Expression::Block(vec![Expression::If { + is_expr: false, + cond_expr: box Expression::Atom(AtomKind::Bool(Boolean::True)), + then_expr: box Expression::Atom(AtomKind::Bool(Boolean::False)), + elseif_exprs: vec![ + ( + Expression::Atom(AtomKind::Bool(Boolean::False)), + Expression::Atom(AtomKind::Bool(Boolean::True)) + ), + ( + Expression::Atom(AtomKind::Unary( + "!".to_string(), + box AtomKind::Bool(Boolean::False) + ),), + Expression::Atom(AtomKind::Bool(Boolean::False)) + ) + ], + else_expr: Some(box Expression::Atom(AtomKind::Bool(Boolean::False))), + }])), + ty: FunctionType { + ext: false, + ret_ty: box PrimitiveType::Unit, + params: vec![PrimitiveType::Unit], + } + }),]) + ); + } + #[test] fn if_else() { let pt = parse_test!( @@ -480,6 +531,7 @@ fn main () -> () = { "bar".to_string() ))] }]), + elseif_exprs: vec![], else_expr: Some(box Expression::Block(vec![Expression::Call { name: IdentPath::Local("bar".to_string()), types: vec![], @@ -503,6 +555,7 @@ fn main () -> () = { types: vec![], args: vec![Expression::Atom(AtomKind::Bool(Boolean::True))] }, + elseif_exprs: vec![], else_expr: None, is_expr: false, }, @@ -512,6 +565,7 @@ fn main () -> () = { box AtomKind::Bool(Boolean::True) )), then_expr: box Expression::Atom(AtomKind::Bool(Boolean::False)), + elseif_exprs: vec![], else_expr: Some(box Expression::Atom(AtomKind::Bool(Boolean::True))), is_expr: false, }, From 3dc1b712a49fa5e2177f66d2f7963c0d51d54416 Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 20 Mar 2021 21:16:16 +0200 Subject: [PATCH 13/18] The One With Modules XIII --- .../src/codegen/unit/cg/conditional/ifelse.rs | 112 +++++++++++++++--- comp-be/src/codegen/unit/compiler.rs | 25 +++- parser/src/ast.rs | 1 - parser/src/parser/conditionals.rs | 2 - parser/src/parser/pass/type_resolution.rs | 2 - parser/src/tests.rs | 4 - 6 files changed, 117 insertions(+), 29 deletions(-) diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index a24514e..cecd39f 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -1,9 +1,13 @@ -use crate::codegen::{ - builder::{branch, core}, - unit::{cg::expr, CompilerContext, Message}, - ValueTypePair, +use crate::{ + codegen::{ + builder::{branch, core}, + unit::{cg::expr, CompilerContext, Message}, + ValueTypePair, + }, + fmt::AatbeFmt, + ty::LLVMTyInCtx, }; -use llvm_sys_wrapper::LLVMBasicBlockRef; +use llvm_sys_wrapper::{LLVMBasicBlockRef, Phi}; use parser::ast::{Expression, PrimitiveType}; pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { @@ -12,13 +16,8 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { then_expr, elseif_exprs, else_expr, - is_expr, } = expr { - if *is_expr { - todo!("If ret"); - } - let then_bb = ctx.basic_block("then"); let elseif_bbs = elseif_exprs .iter() @@ -35,11 +34,16 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { let else_bb = else_expr.as_ref().map(|_| ctx.basic_block("else")); let end_bb = ctx.basic_block("end"); - ctx.dispatch(Message::EnterAnonymousScope); - ctx.trace(format!("If {:?}", cond_expr)); + ctx.dispatch(Message::EnterIfScope(cond_expr.fmt())); let cond = expr::cg(cond_expr, ctx)?; if *cond.prim().inner() != PrimitiveType::Bool { + /* + self.add_error(CompileError::ExpectedType { + expected_ty: PrimitiveType::Bool.fmt(), + found_ty: cond.prim().fmt(), + value: cond_expr.fmt(), + }); */ todo!("NOT A BOOL"); } @@ -52,43 +56,113 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { branch::cond_branch(ctx, *cond, then_bb, next_bb(0)); + core::pos_at_end(ctx, then_bb); + let then_val = expr::cg(then_expr, ctx)?; + + ctx.dispatch(Message::ExitScope); + let elseif_vals = elseif_bbs .iter() .enumerate() .map(|(i, ((bb_cond, bb_body), (cond, expr)))| { - ctx.trace(format!("Else If {:?}", cond)); + ctx.dispatch(Message::EnterElseIfScope(cond.fmt())); core::pos_at_end(ctx, *bb_cond); let cond = expr::cg(cond, ctx)?; + + if *cond.prim().inner() != PrimitiveType::Bool { + /* + self.add_error(CompileError::ExpectedType { + expected_ty: PrimitiveType::Bool.fmt(), + found_ty: cond.prim().fmt(), + value: cond_expr.fmt(), + }); */ + todo!("NOT A BOOL"); + } + branch::cond_branch(ctx, *cond, *bb_body, next_bb(i + 1)); core::pos_at_end(ctx, *bb_body); let val = expr::cg(expr, ctx); branch::branch(ctx, end_bb); + ctx.dispatch(Message::ExitScope); val }) .collect::>(); core::pos_at_end(ctx, then_bb); - let then_val = expr::cg(then_expr, ctx); let else_val = else_bb .map(|bb| { - ctx.trace("Else".to_string()); + ctx.dispatch(Message::EnterElseScope); branch::branch(ctx, end_bb); core::pos_at_end(ctx, bb); - else_expr.as_ref().and_then(|expr| expr::cg(&expr, ctx)) + let res = else_expr.as_ref().and_then(|expr| expr::cg(&expr, ctx)); + ctx.dispatch(Message::ExitScope); + res }) .flatten(); - ctx.dispatch(Message::ExitScope); - branch::branch(ctx, end_bb); core::pos_at_end(ctx, end_bb); - None + + let ty = then_val.prim().inner().clone(); + let mut values = vec![*then_val]; + let mut blocks = vec![then_bb]; + + // Else If type failed to compile + if elseif_vals.len() != 0 && elseif_vals.iter().any(|v| v.is_none()) { + // TODO: Error + return None; + } else { + let velseif = elseif_vals + .iter() + .map(|e| e.as_ref().unwrap()) + .collect::>(); + + // Else If types do not match if type + if !velseif + .iter() + .fold(true, |a, b| a && b.prim().inner() == &ty) + { + // TODO: Error + return None; + } else { + for (i, val) in velseif.iter().enumerate() { + values.push(***val); + blocks.push(elseif_bbs[i].0 .1); + } + } + } + + // Else type does not match if type + if else_val + .as_ref() + .map(|v| v.prim().inner().clone()) + .unwrap_or(ty.clone()) + != ty + { + // TODO: Error + return None; + } else if let Some(velse) = else_val { + values.push(*velse); + blocks.push(else_bb.unwrap()); + } + + match values.len() { + 0 => None, + 1 => Some(then_val), + _ => { + let phi = Phi::new(ctx.llvm_builder.as_ref(), ty.llvm_ty_in_ctx(ctx), ""); + + phi.add_incomings(&mut values, &mut blocks); + + Some((phi.as_ref(), ty).into()) + } + } } else { panic!("ICE") } diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index 6ed766b..2e7970a 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Weak}; -use llvm_sys_wrapper::{Builder, Context, LLVMBasicBlock, LLVMBasicBlockRef, LLVMValueRef, Module}; +use llvm_sys_wrapper::{Builder, Context, LLVMBasicBlockRef, LLVMValueRef, Module}; use parser::ast::{Expression, FunctionType, AST}; use crate::{ @@ -30,6 +30,9 @@ pub enum Message { EnterModuleScope(String), ExitModuleScope(String), RestoreModuleScope(String), + EnterIfScope(String), + EnterElseIfScope(String), + EnterElseScope, EnterAnonymousScope, ExitScope, } @@ -62,6 +65,11 @@ impl std::fmt::Debug for Message { Message::RestoreModuleScope(name) => { f.debug_tuple("RestoreModuleScope").field(&name).finish() } + Message::EnterIfScope(cond) => f.debug_tuple("EnterIfScope").field(cond).finish(), + Message::EnterElseIfScope(cond) => { + f.debug_tuple("EnterElseIfScope").field(cond).finish() + } + Message::EnterElseScope => write!(f, "EnterElseScope"), Message::EnterAnonymousScope => write!(f, "EnterAnonymousScope"), Message::ExitScope => write!(f, "ExitScope"), } @@ -370,6 +378,21 @@ impl<'ctx> CompilerUnit<'ctx> { *self.ident.borrow_mut() += 1; self.restore_module_scope(name.clone()) } + Message::EnterIfScope(_) => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.enter_anonymous_scope() + } + Message::EnterElseIfScope(_) => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.enter_anonymous_scope() + } + Message::EnterElseScope => { + println!("├── {:?}", message); + *self.ident.borrow_mut() += 1; + self.enter_anonymous_scope() + } Message::EnterAnonymousScope => { println!("├── {:?}", message); *self.ident.borrow_mut() += 1; diff --git a/parser/src/ast.rs b/parser/src/ast.rs index a5313b2..dbc706b 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -73,7 +73,6 @@ pub enum Expression { then_expr: Box, elseif_exprs: Vec<(Expression, Expression)>, else_expr: Option>, - is_expr: bool, }, RecordInit { record: String, diff --git a/parser/src/parser/conditionals.rs b/parser/src/parser/conditionals.rs index 0d97e76..d05a631 100644 --- a/parser/src/parser/conditionals.rs +++ b/parser/src/parser/conditionals.rs @@ -8,7 +8,6 @@ impl Parser { pub fn parse_if_else(&mut self) -> ParseResult { kw!(If, self); - let is_expr = kw!(bool Ret, self); let cond_expr = box capture!(self, parse_expression).ok_or(ParseError::ExpectedCondition)?; kw!(bool Then, self); @@ -42,7 +41,6 @@ impl Parser { then_expr, elseif_exprs: chain, else_expr, - is_expr, }) } diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 358e072..650e616 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -94,13 +94,11 @@ fn resolve_expr(variants: &Vec, ast: &Expression) -> Expression { value: box resolve_expr(variants, value), }, Expression::If { - is_expr, cond_expr: box cond_expr, elseif_exprs, else_expr, then_expr: box then_expr, } => Expression::If { - is_expr: *is_expr, cond_expr: box resolve_expr(variants, cond_expr), elseif_exprs: elseif_exprs .iter() diff --git a/parser/src/tests.rs b/parser/src/tests.rs index d377cdc..c232c3f 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -458,7 +458,6 @@ fn main () = { type_names: vec![], public: false, body: Some(box Expression::Block(vec![Expression::If { - is_expr: false, cond_expr: box Expression::Atom(AtomKind::Bool(Boolean::True)), then_expr: box Expression::Atom(AtomKind::Bool(Boolean::False)), elseif_exprs: vec![ @@ -539,7 +538,6 @@ fn main () -> () = { "foo".to_string() ))] }])), - is_expr: false, }, Expression::If { cond_expr: box Expression::Atom(AtomKind::Unary( @@ -557,7 +555,6 @@ fn main () -> () = { }, elseif_exprs: vec![], else_expr: None, - is_expr: false, }, Expression::If { cond_expr: box Expression::Atom(AtomKind::Unary( @@ -567,7 +564,6 @@ fn main () -> () = { then_expr: box Expression::Atom(AtomKind::Bool(Boolean::False)), elseif_exprs: vec![], else_expr: Some(box Expression::Atom(AtomKind::Bool(Boolean::True))), - is_expr: false, }, ])), ty: FunctionType { From fa866f6018287ba34cd4198cf0427c9311c454bb Mon Sep 17 00:00:00 2001 From: chronium Date: Mon, 22 Mar 2021 14:39:05 +0200 Subject: [PATCH 14/18] The One With Modules XIV --- Cargo.lock | 9 + comp-be/Cargo.toml | 1 + comp-be/src/codegen/atom.rs | 2 +- .../src/codegen/builder/{core.rs => base.rs} | 0 comp-be/src/codegen/builder/mod.rs | 2 +- comp-be/src/codegen/call.rs | 2 +- comp-be/src/codegen/conditional.rs | 2 +- comp-be/src/codegen/module.rs | 46 +--- comp-be/src/codegen/unit/cg/assign.rs | 20 ++ comp-be/src/codegen/unit/cg/atom.rs | 19 +- comp-be/src/codegen/unit/cg/binary/mod.rs | 122 ++++----- comp-be/src/codegen/unit/cg/call.rs | 120 ++++----- .../src/codegen/unit/cg/conditional/ifelse.rs | 255 +++++++++--------- comp-be/src/codegen/unit/cg/decl.rs | 40 +++ comp-be/src/codegen/unit/cg/expr.rs | 4 +- comp-be/src/codegen/unit/cg/mod.rs | 2 + comp-be/src/codegen/unit/function.rs | 48 ++-- comp-be/src/codegen/unit/variable.rs | 211 ++++++++------- comp-be/src/fmt.rs | 4 + comp-be/src/ty/infer.rs | 57 ++-- comp-be/src/ty/record.rs | 10 +- comp-be/src/ty/variant.rs | 4 +- main.aat | 9 +- parser/src/parser/macros.rs | 13 +- spec/compiler/020_if_expression.aat | 4 +- 25 files changed, 533 insertions(+), 473 deletions(-) rename comp-be/src/codegen/builder/{core.rs => base.rs} (100%) create mode 100644 comp-be/src/codegen/unit/cg/assign.rs create mode 100644 comp-be/src/codegen/unit/cg/decl.rs diff --git a/Cargo.lock b/Cargo.lock index 83a71d0..37f5221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aatboot" version = "0.1.0" @@ -102,6 +104,7 @@ dependencies = [ name = "comp-be" version = "0.0.1" dependencies = [ + "guard", "llvm-sys-wrapper", "log", "parser", @@ -136,6 +139,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "guard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f3d64ec55b293a2ddfee276c6d7733616925b55dd337ddc0dc83aba96fbbb1" + [[package]] name = "hermit-abi" version = "0.1.8" diff --git a/comp-be/Cargo.toml b/comp-be/Cargo.toml index 7475990..4da0039 100644 --- a/comp-be/Cargo.toml +++ b/comp-be/Cargo.toml @@ -14,3 +14,4 @@ llvm-sys-wrapper = { path = "../llvm-sys-wrapper" } tuple-combinator = "0.2.1" parser = { path = "../parser" } log = "0.4.14" +guard = "0.5" diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index a2c1ead..36294c3 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - builder::{cast, core, op, ty}, + builder::{base, cast, op, ty}, unit::Slot, AatbeModule, CompileError, ValueTypePair, }, diff --git a/comp-be/src/codegen/builder/core.rs b/comp-be/src/codegen/builder/base.rs similarity index 100% rename from comp-be/src/codegen/builder/core.rs rename to comp-be/src/codegen/builder/base.rs diff --git a/comp-be/src/codegen/builder/mod.rs b/comp-be/src/codegen/builder/mod.rs index 9933d62..0845b08 100644 --- a/comp-be/src/codegen/builder/mod.rs +++ b/comp-be/src/codegen/builder/mod.rs @@ -1,6 +1,6 @@ +pub mod base; pub mod branch; pub mod cast; -pub mod core; pub mod op; pub mod ty; pub mod value; diff --git a/comp-be/src/codegen/call.rs b/comp-be/src/codegen/call.rs index ab3dbbc..3c24fcb 100644 --- a/comp-be/src/codegen/call.rs +++ b/comp-be/src/codegen/call.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - builder::{cast, core, ty, value}, + builder::{base, cast, ty, value}, unit::function::find_function, AatbeModule, CompileError, ValueTypePair, }, diff --git a/comp-be/src/codegen/conditional.rs b/comp-be/src/codegen/conditional.rs index 3fb1a69..7ec604c 100644 --- a/comp-be/src/codegen/conditional.rs +++ b/comp-be/src/codegen/conditional.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - builder::{branch, core}, + builder::{base, branch}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index cff4fba..f2924b9 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -27,7 +27,7 @@ use crate::{ }; use super::{ - builder::{cast, core}, + builder::{base, cast}, unit::function::{find_func, FuncTyMap}, }; use parser::{ @@ -512,43 +512,7 @@ impl AatbeModule { ), _ => store_value(self, lval, value), }, - Expression::Decl { - ty: PrimitiveType::NamedType { name, ty: Some(ty) }, - value: _, - exterior_bind: _, - } => { - alloc_variable(self, expr); - - Some( - ( - self.get_var(name).expect("Compiler crapped out.").into(), - *ty.clone(), - ) - .into(), - ) - } - Expression::Decl { - ty: PrimitiveType::NamedType { name, ty: None }, - value, - exterior_bind: _, - } => { - if value.is_none() { - self.add_error(CompileError::ExpectedValue { name: name.clone() }); - return None; - } - - alloc_variable(self, expr).and_then(|ty| { - Some( - ( - self.get_var(name).expect("Compiler crapped out.").into(), - ty, - ) - .into(), - ) - }) - } Expression::Loop { .. } => self.codegen_basic_loop(expr), - Expression::If { .. } => self.codegen_if(expr), Expression::Binary(lhs, op, rhs) => match codegen_binary(self, op, lhs, rhs) { Ok(val) => Some(val), Err(_) => { @@ -560,14 +524,6 @@ impl AatbeModule { None } }, - Expression::Function { ty, type_names, .. } if type_names.len() == 0 => match ty { - FunctionType { - ret_ty: _, - params: _, - ext: true, - } => None, - _ => declare_and_compile_function(self, expr), - }, Expression::Function { .. } => None, Expression::Block(nodes) if nodes.len() == 0 => None, Expression::Block(nodes) => { diff --git a/comp-be/src/codegen/unit/cg/assign.rs b/comp-be/src/codegen/unit/cg/assign.rs new file mode 100644 index 0000000..33fa065 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/assign.rs @@ -0,0 +1,20 @@ +use guard::guard; +use parser::ast::Expression; + +use crate::codegen::{ + unit::{store_value, CompilerContext}, + ValueTypePair, +}; + +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { + guard!(let Expression::Assign { lval, value } = expr else { unreachable!() }); + + match value { + box Expression::RecordInit { + record, + types, + values, + } => todo!(), + _ => store_value(ctx, lval, value), + } +} diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index d95b120..5f93656 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -1,5 +1,7 @@ use parser::ast::{AtomKind, Boolean, PrimitiveType}; +use guard::guard; + use crate::{ codegen::{ builder::value, @@ -27,17 +29,14 @@ pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { | AtomKind::Unary(_, box AtomKind::Integer(..))) => consts::numeric::cg(atom, ctx), atom @ (AtomKind::StringLiteral(..) | AtomKind::CharLiteral(..)) => const_atom(ctx, atom), AtomKind::Ident(name) => { - if let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) { - let slot = slot?; - match slot.var_ty().clone() { - ty @ PrimitiveType::Newtype(_) | ty @ PrimitiveType::VariantType(_) => { - let val: ValueTypePair = slot.into(); - Some((*val, ty).into()) - } - ty => Some((slot.load_var(ctx.llvm_builder), ty).into()), + guard!(let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) else { unreachable!(); }); + let slot = slot?; + match slot.var_ty().clone() { + ty @ PrimitiveType::Newtype(_) | ty @ PrimitiveType::VariantType(_) => { + let val: ValueTypePair = slot.into(); + Some((*val, ty).into()) } - } else { - panic!("ICE") + ty => Some((slot.load_var(ctx.llvm_builder), ty).into()), } } _ => todo!("{:?}", atom), diff --git a/comp-be/src/codegen/unit/cg/binary/mod.rs b/comp-be/src/codegen/unit/cg/binary/mod.rs index 38bd031..f303aa0 100644 --- a/comp-be/src/codegen/unit/cg/binary/mod.rs +++ b/comp-be/src/codegen/unit/cg/binary/mod.rs @@ -7,6 +7,8 @@ mod uint; use parser::ast::{Expression, IntSize, PrimitiveType}; +use guard::guard; + use crate::{ codegen::{ unit::{cg::expr, CompilerContext}, @@ -16,73 +18,71 @@ use crate::{ }; pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { - if let Expression::Binary(box lh, op, box rh) = expr { - let lhs = expr::cg(lh, ctx).ok_or(CompileError::Handled)?; - let rhs = expr::cg(rh, ctx).ok_or(CompileError::Handled)?; + guard!(let Expression::Binary(box lh, op, box rh) = expr else { unreachable!() }); + + let lhs = expr::cg(lh, ctx).ok_or(CompileError::Handled)?; + let rhs = expr::cg(rh, ctx).ok_or(CompileError::Handled)?; - match (lhs.prim(), rhs.prim()) { - (PrimitiveType::Bool, PrimitiveType::Bool) => { - ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); - match bool::cg(*lhs, op, *rhs, ctx) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), - } + match (lhs.prim(), rhs.prim()) { + (PrimitiveType::Bool, PrimitiveType::Bool) => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match bool::cg(*lhs, op, *rhs, ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } - (PrimitiveType::Char, PrimitiveType::Char) => { - ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); - match uint::cg(*lhs, op, *rhs, IntSize::Bits8, ctx) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), - } + } + (PrimitiveType::Char, PrimitiveType::Char) => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match uint::cg(*lhs, op, *rhs, IntSize::Bits8, ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } - (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { - ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); - match uint::cg(*lhs, op, *rhs, lsz.clone(), ctx) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), - } + } + (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match uint::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } - (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { - ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); - match int::cg(*lhs, op, *rhs, lsz.clone(), ctx) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), - } + } + (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match int::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } - (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { - ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); - match float::cg(*lhs, op, *rhs, lsz.clone(), ctx) { - Some(res) => Ok(res), - None => Err(CompileError::OpMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), - } + } + (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { + ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); + match float::cg(*lhs, op, *rhs, lsz.clone(), ctx) { + Some(res) => Ok(res), + None => Err(CompileError::OpMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } - _ => Err(CompileError::BinaryMismatch { - op: op.clone(), - types: (lhs.prim().fmt(), rhs.prim().fmt()), - values: (lh.fmt(), rh.fmt()), - }), } - } else { - panic!("ICE") + _ => Err(CompileError::BinaryMismatch { + op: op.clone(), + types: (lhs.prim().fmt(), rhs.prim().fmt()), + values: (lh.fmt(), rh.fmt()), + }), } } diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index dd4a9a2..192929f 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -4,7 +4,7 @@ use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; use crate::{ codegen::{ - builder::core, + builder::base, unit::{cg::expr, function::find_function, CompilerContext, Query, QueryResponse}, ValueTypePair, }, @@ -12,77 +12,75 @@ use crate::{ prefix, }; +use guard::guard; use log::*; pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { - if let Expression::Call { + guard!(let Expression::Call { name, types: _, args, - } = expr - { - ctx.trace(format!("Call {}", AatbeFmt::fmt(expr))); - let mut call_types = vec![]; + } = expr else { unreachable!() }); - let mut error = false; - let mut call_args = args - .iter() - .filter_map(|arg| match arg { - Expression::Atom(AtomKind::SymbolLiteral(sym)) => { - call_types.push(PrimitiveType::Symbol(sym.clone())); - None - } - Expression::Atom(AtomKind::Unit) => { - call_types.push(PrimitiveType::Unit); - None - } - _ => { - let expr = expr::cg(arg, ctx); + ctx.trace(format!("Call {}", AatbeFmt::fmt(expr))); + let mut call_types = vec![]; - if expr.is_none() { - error = true; - - None - } else { - expr.map_or(None, |arg| match arg.prim().clone() { - ref ty @ PrimitiveType::VariantType(ref _name) => todo!("{:?}", ty), - ref ty @ PrimitiveType::Array { .. } => todo!("{:?}", ty), - ref ty @ PrimitiveType::Ref(box PrimitiveType::Array { .. }) => { - todo!("{:?}", ty) - } - ref ty @ _ => { - call_types.push(ty.clone()); - Some(*arg) - } - }) - } - } - }) - .collect::>(); + let mut error = false; + let mut call_args = args + .iter() + .filter_map(|arg| match arg { + Expression::Atom(AtomKind::SymbolLiteral(sym)) => { + call_types.push(PrimitiveType::Symbol(sym.clone())); + None + } + Expression::Atom(AtomKind::Unit) => { + call_types.push(PrimitiveType::Unit); + None + } + _ => { + let expr = expr::cg(&arg, ctx); - if error { - trace!("Got error"); - return None; - } + if expr.is_none() { + error = true; - let prefix = |path: &IdentPath| -> Vec { - match path { - IdentPath::Local(name) => prefix!(call ctx, name.clone()), - IdentPath::Module(name) => prefix!(call module ctx, name.clone()), - _ => todo!(), + None + } else { + expr.map_or(None, |arg| match arg.prim().clone() { + ref ty @ PrimitiveType::VariantType(ref _name) => todo!("{:?}", ty), + ref ty @ PrimitiveType::Array { .. } => todo!("{:?}", ty), + ref ty @ PrimitiveType::Ref(box PrimitiveType::Array { .. }) => { + todo!("{:?}", ty) + } + ref ty @ _ => { + call_types.push(ty.clone()); + Some(*arg) + } + }) + } } - }; + }) + .collect::>(); - find_function( - match ctx.query(Query::FunctionGroup(prefix(name))) { - QueryResponse::FunctionGroup(Some(group)) => group, - QueryResponse::FunctionGroup(None) => todo!("no function found"), - _ => panic!("ICE"), - }, - &call_types, - ) - .map(|func| core::call(ctx, func.upgrade().expect("ICE").borrow(), &mut call_args)) - } else { - unreachable!() + if error { + trace!("Got error"); + return None; } + + let prefix = |path: &IdentPath| -> Vec { + match path { + IdentPath::Local(name) => prefix!(call ctx, name.clone()), + IdentPath::Module(name) => prefix!(call module ctx, name.clone()), + _ => todo!(), + } + }; + + find_function( + match ctx.query(Query::FunctionGroup(prefix(name))) { + QueryResponse::FunctionGroup(Some(group)) => group, + QueryResponse::FunctionGroup(None) => todo!("no function found"), + _ => unreachable!(), + }, + &call_types, + ) + .map(|func| base::call(ctx, func.upgrade().expect("ICE").borrow(), &mut call_args)) } diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index cecd39f..eca1b03 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -1,6 +1,6 @@ use crate::{ codegen::{ - builder::{branch, core}, + builder::{base, branch}, unit::{cg::expr, CompilerContext, Message}, ValueTypePair, }, @@ -10,160 +10,159 @@ use crate::{ use llvm_sys_wrapper::{LLVMBasicBlockRef, Phi}; use parser::ast::{Expression, PrimitiveType}; +use guard::guard; + pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { - if let Expression::If { + guard!(let Expression::If { cond_expr, then_expr, elseif_exprs, else_expr, - } = expr - { - let then_bb = ctx.basic_block("then"); - let elseif_bbs = elseif_exprs - .iter() - .map(|e| { + } = expr else { unreachable!() }); + + let then_bb = ctx.basic_block("then"); + let elseif_bbs = elseif_exprs + .iter() + .map(|e| { + ( ( - ( - ctx.basic_block("elseif_cond"), - ctx.basic_block("elseif_body"), - ), - e, - ) - }) - .collect::>(); - let else_bb = else_expr.as_ref().map(|_| ctx.basic_block("else")); - let end_bb = ctx.basic_block("end"); - - ctx.dispatch(Message::EnterIfScope(cond_expr.fmt())); - let cond = expr::cg(cond_expr, ctx)?; - - if *cond.prim().inner() != PrimitiveType::Bool { - /* - self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), - found_ty: cond.prim().fmt(), - value: cond_expr.fmt(), - }); */ - todo!("NOT A BOOL"); - } + ctx.basic_block("elseif_cond"), + ctx.basic_block("elseif_body"), + ), + e, + ) + }) + .collect::>(); + let else_bb = else_expr.as_ref().map(|_| ctx.basic_block("else")); + let end_bb = ctx.basic_block("end"); + + ctx.dispatch(Message::EnterIfScope(cond_expr.fmt())); + let cond = expr::cg(cond_expr, ctx)?; + + if *cond.prim().inner() != PrimitiveType::Bool { + /* + self.add_error(CompileError::ExpectedType { + expected_ty: PrimitiveType::Bool.fmt(), + found_ty: cond.prim().fmt(), + value: cond_expr.fmt(), + }); */ + todo!("NOT A BOOL"); + } - let next_bb = |i: usize| -> LLVMBasicBlockRef { - elseif_bbs - .get(i) - .map(|e| e.0 .0) - .unwrap_or(else_bb.unwrap_or(end_bb)) - }; + let next_bb = |i: usize| -> LLVMBasicBlockRef { + elseif_bbs + .get(i) + .map(|e| e.0 .0) + .unwrap_or(else_bb.unwrap_or(end_bb)) + }; + + branch::cond_branch(ctx, *cond, then_bb, next_bb(0)); + + base::pos_at_end(ctx, then_bb); + let then_val = expr::cg(then_expr, ctx)?; + + ctx.dispatch(Message::ExitScope); + + let elseif_vals = elseif_bbs + .iter() + .enumerate() + .map(|(i, ((bb_cond, bb_body), (cond, expr)))| { + ctx.dispatch(Message::EnterElseIfScope(cond.fmt())); + base::pos_at_end(ctx, *bb_cond); + + let cond = expr::cg(cond, ctx)?; + + if *cond.prim().inner() != PrimitiveType::Bool { + /* + self.add_error(CompileError::ExpectedType { + expected_ty: PrimitiveType::Bool.fmt(), + found_ty: cond.prim().fmt(), + value: cond_expr.fmt(), + }); */ + todo!("NOT A BOOL"); + } - branch::cond_branch(ctx, *cond, then_bb, next_bb(0)); + branch::cond_branch(ctx, *cond, *bb_body, next_bb(i + 1)); - core::pos_at_end(ctx, then_bb); - let then_val = expr::cg(then_expr, ctx)?; + base::pos_at_end(ctx, *bb_body); + let val = expr::cg(expr, ctx); + branch::branch(ctx, end_bb); + ctx.dispatch(Message::ExitScope); - ctx.dispatch(Message::ExitScope); + val + }) + .collect::>(); - let elseif_vals = elseif_bbs - .iter() - .enumerate() - .map(|(i, ((bb_cond, bb_body), (cond, expr)))| { - ctx.dispatch(Message::EnterElseIfScope(cond.fmt())); - core::pos_at_end(ctx, *bb_cond); - - let cond = expr::cg(cond, ctx)?; - - if *cond.prim().inner() != PrimitiveType::Bool { - /* - self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), - found_ty: cond.prim().fmt(), - value: cond_expr.fmt(), - }); */ - todo!("NOT A BOOL"); - } - - branch::cond_branch(ctx, *cond, *bb_body, next_bb(i + 1)); - - core::pos_at_end(ctx, *bb_body); - let val = expr::cg(expr, ctx); - branch::branch(ctx, end_bb); - ctx.dispatch(Message::ExitScope); - - val - }) - .collect::>(); + base::pos_at_end(ctx, then_bb); - core::pos_at_end(ctx, then_bb); + let else_val = else_bb + .map(|bb| { + ctx.dispatch(Message::EnterElseScope); + branch::branch(ctx, end_bb); + base::pos_at_end(ctx, bb); - let else_val = else_bb - .map(|bb| { - ctx.dispatch(Message::EnterElseScope); - branch::branch(ctx, end_bb); - core::pos_at_end(ctx, bb); + let res = else_expr.as_ref().and_then(|expr| expr::cg(&expr, ctx)); + ctx.dispatch(Message::ExitScope); + res + }) + .flatten(); - let res = else_expr.as_ref().and_then(|expr| expr::cg(&expr, ctx)); - ctx.dispatch(Message::ExitScope); - res - }) - .flatten(); + branch::branch(ctx, end_bb); - branch::branch(ctx, end_bb); + base::pos_at_end(ctx, end_bb); - core::pos_at_end(ctx, end_bb); + let ty = then_val.prim().inner().clone(); + let mut values = vec![*then_val]; + let mut blocks = vec![then_bb]; - let ty = then_val.prim().inner().clone(); - let mut values = vec![*then_val]; - let mut blocks = vec![then_bb]; + // Else If type failed to compile + if elseif_vals.len() != 0 && elseif_vals.iter().any(|v| v.is_none()) { + // TODO: Error + return None; + } else { + let velseif = elseif_vals + .iter() + .map(|e| e.as_ref().unwrap()) + .collect::>(); - // Else If type failed to compile - if elseif_vals.len() != 0 && elseif_vals.iter().any(|v| v.is_none()) { + // Else If types do not match if type + if !velseif + .iter() + .fold(true, |a, b| a && b.prim().inner() == &ty) + { // TODO: Error return None; } else { - let velseif = elseif_vals - .iter() - .map(|e| e.as_ref().unwrap()) - .collect::>(); - - // Else If types do not match if type - if !velseif - .iter() - .fold(true, |a, b| a && b.prim().inner() == &ty) - { - // TODO: Error - return None; - } else { - for (i, val) in velseif.iter().enumerate() { - values.push(***val); - blocks.push(elseif_bbs[i].0 .1); - } + for (i, val) in velseif.iter().enumerate() { + values.push(***val); + blocks.push(elseif_bbs[i].0 .1); } } + } - // Else type does not match if type - if else_val - .as_ref() - .map(|v| v.prim().inner().clone()) - .unwrap_or(ty.clone()) - != ty - { - // TODO: Error - return None; - } else if let Some(velse) = else_val { - values.push(*velse); - blocks.push(else_bb.unwrap()); - } + // Else type does not match if type + if else_val + .as_ref() + .map(|v| v.prim().inner().clone()) + .unwrap_or(ty.clone()) + != ty + { + // TODO: Error + return None; + } else if let Some(velse) = else_val { + values.push(*velse); + blocks.push(else_bb.unwrap()); + } - match values.len() { - 0 => None, - 1 => Some(then_val), - _ => { - let phi = Phi::new(ctx.llvm_builder.as_ref(), ty.llvm_ty_in_ctx(ctx), ""); + match values.len() { + 0 => None, + 1 => Some(then_val), + _ => { + let phi = Phi::new(ctx.llvm_builder.as_ref(), ty.llvm_ty_in_ctx(ctx), ""); - phi.add_incomings(&mut values, &mut blocks); + phi.add_incomings(&mut values, &mut blocks); - Some((phi.as_ref(), ty).into()) - } + Some((phi.as_ref(), ty).into()) } - } else { - panic!("ICE") } } diff --git a/comp-be/src/codegen/unit/cg/decl.rs b/comp-be/src/codegen/unit/cg/decl.rs new file mode 100644 index 0000000..ca179d0 --- /dev/null +++ b/comp-be/src/codegen/unit/cg/decl.rs @@ -0,0 +1,40 @@ +use parser::ast::{Expression, PrimitiveType}; + +use guard::guard; + +use crate::codegen::{ + unit::{alloc_variable, CompilerContext, Query, QueryResponse}, + ValueTypePair, +}; + +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { + match expr { + Expression::Decl { + ty: PrimitiveType::NamedType { name, ty: Some(ty) }, + value: _, + exterior_bind: _, + } => { + alloc_variable(expr, ctx); + + guard!(let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) else { unreachable!() }); + let slot = slot?; + Some((slot.into(), *ty.clone()).into()) + } + Expression::Decl { + ty: PrimitiveType::NamedType { name, ty: None }, + value, + exterior_bind: _, + } => { + if value.is_none() { + todo!("ERROR") + } + + alloc_variable(expr, ctx).and_then(|ty| { + guard!(let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) else { unreachable!() }); + let slot = slot?; + Some((slot.into(), ty).into()) + }) + } + _ => unreachable!(), + } +} diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 85214e1..900017c 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -2,7 +2,7 @@ use parser::ast::{Expression, FunctionType}; use crate::codegen::{ unit::{ - cg::{atom, binary, call, conditional}, + cg::{assign, atom, binary, call, conditional, decl}, declare_and_compile_function, CompilerContext, Message, }, ValueTypePair, @@ -10,6 +10,8 @@ use crate::codegen::{ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { + Expression::Assign { .. } => assign::cg(expr, ctx), + Expression::Decl { .. } => decl::cg(expr, ctx), Expression::If { .. } => conditional::ifelse::cg(expr, ctx), Expression::Binary(..) => Some(binary::cg(expr, ctx).ok().expect("todo")), Expression::Call { .. } => call::cg(expr, ctx), diff --git a/comp-be/src/codegen/unit/cg/mod.rs b/comp-be/src/codegen/unit/cg/mod.rs index 212d80e..0ea5b69 100644 --- a/comp-be/src/codegen/unit/cg/mod.rs +++ b/comp-be/src/codegen/unit/cg/mod.rs @@ -3,11 +3,13 @@ use parser::ast::AST; use super::{CompilerContext, Message}; +pub mod assign; pub mod atom; pub mod binary; pub mod call; pub mod conditional; pub mod consts; +pub mod decl; pub mod expr; pub fn cg(ast: &AST, ctx: &CompilerContext) -> Option { diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index f11c2b7..82ad888 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -1,7 +1,7 @@ use crate::{ codegen::builder::cast, codegen::{ - builder::core, + builder::base, mangle_v1::NameMangler, unit::{ cg::expr, CompilerContext, FunctionVisibility, Message, Mutability, Query, @@ -21,6 +21,8 @@ use std::{ rc::{Rc, Weak}, }; +use guard::guard; + use parser::ast::{Expression, FunctionType, PrimitiveType}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; @@ -190,12 +192,12 @@ pub fn declare_and_compile_function<'ctx>( ); if !has_return_type(ty) { - core::ret_void(&ctx); + base::ret_void(&ctx); } else { if let Some(val) = ret_val { match val.prim() { PrimitiveType::VariantType(_variant) => todo!(), - _ => core::ret(&ctx, val), + _ => base::ret(&ctx, val), }; } else { // TODO: Error @@ -226,19 +228,18 @@ pub fn codegen_function(ctx: &CompilerContext, function: &Expression) { } => { let func = ctx.query(Query::Function((prefix!(ctx), ty))); - if let QueryResponse::Function(Some(func)) = func { - let func = func.upgrade().expect("ICE"); + guard!(let QueryResponse::Function(Some(func)) = func else { unreachable!(); }); + let func = func.upgrade().expect("ICE"); - if !attributes.is_empty() { - for attr in attributes { - match attr.to_lowercase().as_ref() { - "entry" => core::pos_at_end(ctx, func.bb("entry".to_string())), - _ => panic!("Cannot decorate function with {}", name), - }; - } - } else { - core::pos_at_end(ctx, func.bb(String::default())); + if !attributes.is_empty() { + for attr in attributes { + match attr.to_lowercase().as_ref() { + "entry" => base::pos_at_end(ctx, func.bb("entry".to_string())), + _ => panic!("Cannot decorate function with {}", name), + }; } + } else { + base::pos_at_end(ctx, func.bb(String::default())); } } _ => unreachable!(), @@ -303,18 +304,15 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { name, ty: Some(box PrimitiveType::Ref(ty) | ty), } => { - if let QueryResponse::Function(Some(func)) = + guard!(let QueryResponse::Function(Some(func)) = ctx.query(Query::Function((prefix!(ctx), fty))) - { - let func = func.upgrade().expect("ICE"); - ctx.dispatch(Message::PushInScope( - name.clone(), - Slot::FunctionArgument( - func.get_param(pos as u32), - *ty.clone(), - ), - )) - } + else { unreachable!() }); + + let func = func.upgrade().expect("ICE"); + ctx.dispatch(Message::PushInScope( + name.clone(), + Slot::FunctionArgument(func.get_param(pos as u32), *ty.clone()), + )) } PrimitiveType::Unit | PrimitiveType::Symbol(_) => {} _ => unimplemented!("{:?}", ty), diff --git a/comp-be/src/codegen/unit/variable.rs b/comp-be/src/codegen/unit/variable.rs index d3da812..0a1556f 100644 --- a/comp-be/src/codegen/unit/variable.rs +++ b/comp-be/src/codegen/unit/variable.rs @@ -1,13 +1,15 @@ use crate::ty::infer::infer_type; use crate::{ codegen::{ - unit::{Mutability, Slot}, + builder::{base, value}, + unit::{cg::expr, CompilerContext, Message, Mutability, Query, QueryResponse, Slot}, AatbeModule, CompileError, ValueTypePair, }, fmt::AatbeFmt, ty::{record::store_named_field, LLVMTyInCtx, TypeKind}, }; +use guard::guard; use parser::ast::{AtomKind, Expression, LValue, PrimitiveType}; macro_rules! rec_name { @@ -31,25 +33,26 @@ macro_rules! rec_name { }}; } -pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option { +pub fn alloc_variable(variable: &Expression, ctx: &CompilerContext) -> Option { match variable { Expression::Decl { ty: PrimitiveType::NamedType { name, ty }, value, exterior_bind, } => { - /*let mut vtp = None; + let mut vtp = None; let ty = match ty { Some(ty) => match ty { box PrimitiveType::GenericTypeRef(name, types) => { - let rec = rec_name!(name.clone(), types); + /*let rec = rec_name!(name.clone(), types); if !module.typectx_ref().get_record(&rec).is_ok() { module.propagate_types_in_record(name, types.clone()); } - PrimitiveType::TypeRef(rec.clone()) + PrimitiveType::TypeRef(rec.clone())*/ + todo!() } box PrimitiveType::VariantType(_) => { - if let Some(e) = value { + /*if let Some(e) = value { let pair = module.codegen_expr(e)?; let ty = pair.prim().clone(); @@ -57,7 +60,8 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option ty } else { unreachable!(); - } + }*/ + todo!() } _ => *ty.clone(), }, @@ -69,7 +73,7 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option values: _, } = e { - let rec = rec_name!(record.clone(), types); + /*let rec = rec_name!(record.clone(), types); if types.len() == 0 { PrimitiveType::TypeRef(rec.clone()) } else { @@ -78,9 +82,10 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option } PrimitiveType::TypeRef(rec.clone()) - } + }*/ + todo!() } else { - let pair = module.codegen_expr(e)?; + let pair = expr::cg(e, ctx)?; let ty = pair.prim().clone(); vtp = Some(pair); @@ -90,10 +95,10 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option unreachable!(); } } - };*/ + }; - /*if let PrimitiveType::Newtype(..) | PrimitiveType::VariantType(..) = ty { - module.push_in_scope( + if let PrimitiveType::Newtype(..) | PrimitiveType::VariantType(..) = ty { + /*module.push_in_scope( name, Slot::Variable { mutable: Mutability::from(exterior_bind), @@ -102,68 +107,54 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option value: *vtp.unwrap(), }, ); - return Some(ty.clone()); - }*/ - - todo!(); + return Some(ty.clone());*/ + todo!() + } - /*if value.is_none() { - let ty = ty.as_ref().expect("ICE: Ty none for none value"); - let val_ref = module.llvm_builder_ref().build_alloca_with_name( - todo!(), /*ty.llvm_ty_in_ctx(module)*/ - name.as_ref(), - ); + if value.is_none() { + let val_ref = base::alloca_with_name(ctx, ty.llvm_ty_in_ctx(ctx), name.as_ref()); - module.push_in_scope( - name, + ctx.dispatch(Message::PushInScope( + name.clone(), Slot::Variable { mutable: Mutability::from(exterior_bind), name: name.clone(), - ty: *ty.clone(), + ty: ty.clone(), value: val_ref, }, - ); + )); - return Some(*ty.clone()); - }*/ + return Some(ty); + } // TODO: Variants, generic records - let ty = infer_type( - module, - &*(value.as_ref().expect("ICE: Value cannot be none")), - ); + let ty = infer_type(ctx, &*(value.as_ref().expect("ICE: Value cannot be none"))); if ty.is_none() { panic!("ICE: ty is none {:?} value", value); } let (ty, constant) = ty.unwrap(); - /* - let var_ref = module - .llvm_builder_ref() - .build_alloca_with_name(todo!() /*ty.llvm_ty_in_ctx(module)*/, name.as_ref());*/ - todo!(); - /* - module.push_in_scope( - name, + let var_ref = base::alloca_with_name(ctx, ty.llvm_ty_in_ctx(ctx), name.as_ref()); + + ctx.dispatch(Message::PushInScope( + name.clone(), Slot::Variable { mutable: Mutability::from(exterior_bind), name: name.clone(), ty: ty.clone(), value: var_ref, }, - ); - */ + )); - todo!() - /*if let Some(e) = value { + if let Some(e) = value { if let box Expression::RecordInit { record, types, values, } = e { - if ty.inner() != &PrimitiveType::TypeRef(rec_name!(record.clone(), types)) { + /*if ty.inner() != &PrimitiveType::TypeRef(rec_name!(record.clone(), types)) { module.add_error(CompileError::ExpectedType { expected_ty: ty.inner().fmt(), found_ty: record.clone(), @@ -178,11 +169,12 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option types: types.clone(), values: values.to_vec(), }, - ); + );*/ + todo!() } else { match ty.clone() { PrimitiveType::Array { ref ty, len } if !constant => { - if let box Expression::Atom(AtomKind::Array(exprs)) = e { + /*if let box Expression::Atom(AtomKind::Array(exprs)) = e { let vals = exprs .iter() .filter_map(|e| module.codegen_expr(e)) @@ -214,25 +206,27 @@ pub fn alloc_variable(module: &mut AatbeModule, variable: &Expression) -> Option }); } else { panic!("ICE: arr ty not arr val"); - } + }*/ + todo!() } _ => { - let val = module.codegen_expr(e)?; + let val = expr::cg(e, ctx)?; if val.prim() != ty.inner() { - module.add_error(CompileError::ExpectedType { + /*module.add_error(CompileError::ExpectedType { expected_ty: ty.inner().fmt(), found_ty: val.prim().fmt(), value: value.as_ref().unwrap().fmt(), - }); + });*/ + todo!("Error") }; - module.llvm_builder_ref().build_store(*val, var_ref); + base::store(ctx, *val, var_ref); } }; } - }*/ - //Some(ty.clone()) + } + Some(ty.clone()) } _ => unreachable!(), } @@ -337,61 +331,65 @@ pub fn init_record( } pub fn store_value( - module: &mut AatbeModule, + ctx: &CompilerContext, lval: &LValue, value: &Expression, ) -> Option { - fn get_lval(module: &mut AatbeModule, lvalue: &LValue) -> Option { - todo!() - /*match lvalue { - LValue::Ident(name) => match module.get_var(name) { - None => panic!("Cannot find variable {}", name), - Some(var) => { - match var.get_mutability() { - Mutability::Mutable | Mutability::Global => {} - _ => panic!("Cannot reassign to immutable/constant {}", name), - }; - Some(var.into()) - } - }, - LValue::Accessor(parts) => Some(module.get_interior_pointer(parts.clone())?), + fn get_lval(ctx: &CompilerContext, lvalue: &LValue) -> Option { + match lvalue { + LValue::Ident(name) => { + guard!(let QueryResponse::Slot(Some(slot)) = ctx.query(Query::Slot(name)) else { panic!("Cannot find variable {}", name) }); + match slot.get_mutability() { + Mutability::Mutable | Mutability::Global => {} + _ => panic!("Cannot reassign to immutable/constant {}", name), + }; + Some(slot.into()) + } + LValue::Accessor(parts) => todo!(), //Some(module.get_interior_pointer(parts.clone())?), LValue::Deref(_) => unimplemented!("{:?}", lvalue), LValue::Index(lval, index) => { - let val = get_lval(module, lval); - let index = module.codegen_expr(index).expect("ICE store_value index"); + let val = get_lval(ctx, lval); + let index = expr::cg(index, ctx)?; if let Some(val) = val { match val.ty() { - TypeKind::Primitive(PrimitiveType::Str) => { - let load = module.llvm_builder_ref().build_load(*val); - let gep = module - .llvm_builder_ref() - .build_inbounds_gep(load, &mut [*index]); - - Some((gep, PrimitiveType::Char).into()) - } - TypeKind::Primitive(PrimitiveType::Array { ty: box ty, .. }) => { - let gep = module.llvm_builder_ref().build_inbounds_gep( - *val, - &mut [module.llvm_context_ref().SInt32(0), *index], - ); - - Some((gep, ty).into()) - } - TypeKind::Primitive(PrimitiveType::Slice { ty: box ty }) => { - let arr = module.llvm_builder_ref().build_struct_gep(*val, 0); - let gep = module.llvm_builder_ref().build_inbounds_gep( - module.llvm_builder_ref().build_load(arr), - &mut [module.llvm_context_ref().SInt32(0), *index], - ); - - Some((gep, ty).into()) - } + TypeKind::Primitive(PrimitiveType::Str) => Some( + ( + base::inbounds_gep(ctx, base::load(ctx, *val), &mut vec![*index]), + PrimitiveType::Char, + ) + .into(), + ), + TypeKind::Primitive(PrimitiveType::Array { ty: box ty, .. }) => Some( + ( + base::inbounds_gep( + ctx, + *val, + &mut vec![*value::s32(ctx, 0), *index], + ), + ty, + ) + .into(), + ), + TypeKind::Primitive(PrimitiveType::Slice { ty: box ty }) => Some( + ( + base::inbounds_gep( + ctx, + base::load(ctx, base::struct_gep(ctx, *val, 0)), + &mut vec![*value::s32(ctx, 0), *index], + ), + ty, + ) + .into(), + ), _ => { + // TODO: Error + /* module.add_error(CompileError::NotIndexable { ty: val.prim().fmt(), lval: lvalue.fmt(), - }); + });*/ + todo!(); None } } @@ -399,23 +397,24 @@ pub fn store_value( None } } - }*/ + } } - todo!() - /*get_lval(module, lval).and_then(|var| { - let val = module.codegen_expr(value)?; + get_lval(ctx, lval).and_then(|var| { + let val = expr::cg(value, ctx)?; if var.prim() != val.prim().inner() { - module.add_error(CompileError::AssignMismatch { + // TODO: Error + todo!("ERROR"); + /*module.add_error(CompileError::AssignMismatch { expected_ty: var.prim().fmt(), found_ty: val.prim().fmt(), value: value.fmt(), var: lval.fmt(), - }); + });*/ None } else { - Some((module.llvm_builder_ref().build_store(*val, *var), var.ty()).into()) + Some((base::store(ctx, *val, *var), var.ty()).into()) } - })*/ + }) } diff --git a/comp-be/src/fmt.rs b/comp-be/src/fmt.rs index 0517bb8..3ff8cc2 100644 --- a/comp-be/src/fmt.rs +++ b/comp-be/src/fmt.rs @@ -196,6 +196,10 @@ impl AatbeFmt for &Expression { name, ty.fmt(), ), + Expression::Assign { + lval, + value: box value, + } => format!("{} = {}", lval.fmt(), value.fmt()), _ => panic!("ICE fmt {:?}", self), } } diff --git a/comp-be/src/ty/infer.rs b/comp-be/src/ty/infer.rs index 29800ef..fdcd6d1 100644 --- a/comp-be/src/ty/infer.rs +++ b/comp-be/src/ty/infer.rs @@ -1,18 +1,23 @@ -use parser::ast::{AtomKind, Expression, PrimitiveType}; +use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; -use crate::codegen::{unit::function::find_function, AatbeModule}; +use guard::guard; -pub fn infer_type(module: &AatbeModule, expr: &Expression) -> Option<(PrimitiveType, bool)> { +use crate::{ + codegen::unit::{function::find_function, CompilerContext, Query, QueryResponse}, + prefix, +}; + +pub fn infer_type(ctx: &CompilerContext, expr: &Expression) -> Option<(PrimitiveType, bool)> { match expr { - Expression::Atom(atom) => infer_atom(module, &atom), - /*Expression::Call { + Expression::Atom(atom) => infer_atom(ctx, &atom), + Expression::Call { name, args: call_args, .. } => { let args = call_args .iter() - .filter_map(|e| infer_type(module, e)) + .filter_map(|e| infer_type(ctx, e)) .map(|ty| ty.0) .collect::>(); @@ -20,11 +25,25 @@ pub fn infer_type(module: &AatbeModule, expr: &Expression) -> Option<(PrimitiveT return None; } - let group = module.get_func_group(name)?; - let func = find_function(group, &args)?; + let prefix = |path: &IdentPath| -> Vec { + match path { + IdentPath::Local(name) => prefix!(call ctx, name.clone()), + IdentPath::Module(name) => prefix!(call module ctx, name.clone()), + _ => todo!(), + } + }; - return Some((func.ret_ty().clone(), false)); - }*/ + find_function( + match ctx.query(Query::FunctionGroup(prefix(name))) { + QueryResponse::FunctionGroup(Some(group)) => group, + QueryResponse::FunctionGroup(None) => todo!("no function found"), + _ => unreachable!(), + }, + &args, + ) + .map(|func| Some((func.upgrade().expect("ICE").ret_ty().clone(), false))) + .flatten() + } Expression::RecordInit { record, types, .. } if types.len() == 0 => { Some((PrimitiveType::TypeRef(record.clone()), true)) } @@ -36,7 +55,7 @@ pub fn infer_type(module: &AatbeModule, expr: &Expression) -> Option<(PrimitiveT } } -pub fn infer_atom(module: &AatbeModule, atom: &AtomKind) -> Option<(PrimitiveType, bool)> { +pub fn infer_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option<(PrimitiveType, bool)> { match atom { AtomKind::Integer(_, sz) => Some((sz.clone(), true)), AtomKind::Unit => Some((PrimitiveType::Unit, true)), @@ -45,8 +64,8 @@ pub fn infer_atom(module: &AatbeModule, atom: &AtomKind) -> Option<(PrimitiveTyp AtomKind::Bool(_) => Some((PrimitiveType::Bool, true)), AtomKind::SymbolLiteral(s) => Some((PrimitiveType::Symbol(s.clone()), true)), AtomKind::Array(vals) => { - let fst = vals.first().and_then(|v| infer_type(module, v)); - if !vals.iter().all(|v| infer_type(module, v) == fst) { + let fst = vals.first().and_then(|v| infer_type(ctx, v)); + if !vals.iter().all(|v| infer_type(ctx, v) == fst) { None } else if let Some((ty, constant)) = fst { Some(( @@ -60,13 +79,13 @@ pub fn infer_atom(module: &AatbeModule, atom: &AtomKind) -> Option<(PrimitiveTyp None } } - /*AtomKind::Ident(name) => { - let var = module.get_var(name)?; - - Some((var.var_ty().clone(), false)) - }*/ + AtomKind::Ident(name) => { + guard!(let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) else { unreachable!() }); + let slot = slot?; + Some((slot.var_ty().clone(), false).into()) + } AtomKind::Cast(_, ty) => Some((ty.clone(), false)), - AtomKind::Parenthesized(box expr) => infer_type(module, expr), + AtomKind::Parenthesized(box expr) => infer_type(ctx, expr), _ => unimplemented!("{:?}", atom), } } diff --git a/comp-be/src/ty/record.rs b/comp-be/src/ty/record.rs index 602ce57..516712b 100644 --- a/comp-be/src/ty/record.rs +++ b/comp-be/src/ty/record.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, unit::CompilerContext, AatbeModule, ValueTypePair}, + codegen::{builder::base, unit::CompilerContext, AatbeModule, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; use parser::ast::PrimitiveType; @@ -62,7 +62,7 @@ impl Aggregate for Record { aggregate_ref: LLVMValueRef, ) -> TypeResult { Ok(( - core::struct_gep(ctx, aggregate_ref, index), + base::struct_gep(ctx, aggregate_ref, index), self.types .get(&index) .ok_or(TypeError::RecordIndexOOB(self.name.clone(), index))? @@ -84,7 +84,7 @@ impl Aggregate for Record { )), Some(index) => { let ty = self.types.get(index).cloned().unwrap(); - let gep = core::struct_gep(ctx, aggregate_ref, *index); + let gep = base::struct_gep(ctx, aggregate_ref, *index); Ok((gep, ty).into()) } } @@ -103,7 +103,7 @@ pub fn store_named_field( .get_field_index_ty(name) .expect(format!("Cannot find field {:?} in {:?}\0", name, rec.name).as_str()); - let gep = core::struct_gep_with_name( + let gep = base::struct_gep_with_name( ctx, struct_ref, index.0, @@ -113,7 +113,7 @@ pub fn store_named_field( if value.prim() != &index.1 { Err(index.1) } else { - core::store(ctx, *value, gep); + base::store(ctx, *value, gep); Ok(()) } } diff --git a/comp-be/src/ty/variant.rs b/comp-be/src/ty/variant.rs index facd8ec..b008bad 100644 --- a/comp-be/src/ty/variant.rs +++ b/comp-be/src/ty/variant.rs @@ -1,5 +1,5 @@ use crate::{ - codegen::{builder::core, unit::CompilerContext, ValueTypePair}, + codegen::{builder::base, unit::CompilerContext, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; @@ -64,7 +64,7 @@ impl Aggregate for Variant { Err(TypeError::VariantOOB(self.name.clone(), index)) } Some(types) => Ok(( - core::struct_gep(ctx, aggregate_ref, index + 1), + base::struct_gep(ctx, aggregate_ref, index + 1), types[index as usize].clone(), ) .into()), diff --git a/main.aat b/main.aat index d57a57f..6062d10 100644 --- a/main.aat +++ b/main.aat @@ -4,7 +4,10 @@ module libc { @entry fn main () = { - if false then libc::printf "true\n" - else if true then libc::printf "false\n" - else libc::printf "wtf\n" + var i = 128 + + libc::printf "%d\n", i + i = 256 + + libc::printf "%d\n", i } \ No newline at end of file diff --git a/parser/src/parser/macros.rs b/parser/src/parser/macros.rs index c595268..13ccad6 100644 --- a/parser/src/parser/macros.rs +++ b/parser/src/parser/macros.rs @@ -113,13 +113,24 @@ macro_rules! kw { #[macro_export] macro_rules! path { (required $self:ident) => {{ - use crate::{ast::IdentPath, lexer::token::TokenKind}; + use crate::{ + ast::IdentPath, + lexer::token::{Token, TokenKind}, + }; let prev_ind = $self.index; let token = $self.next(); if let Some(tok) = token { match tok.kind { TokenKind::Identifier(id) => { let mut res = vec![id.clone()]; + if let Some(Token { + kind: TokenKind::EOL, + .. + }) = $self.peek_rel(0) + { + $self.index = prev_ind; + return Err(ParseError::ExpectedIdent); + } while matches!($self.peek_symbol(Symbol::Doubly), Some(true)) { $self.next(); diff --git a/spec/compiler/020_if_expression.aat b/spec/compiler/020_if_expression.aat index 0f93d5d..a4f178e 100644 --- a/spec/compiler/020_if_expression.aat +++ b/spec/compiler/020_if_expression.aat @@ -1,9 +1,9 @@ -// spector:name If/Else expressions using `if ret` +// spector:name If/Else expressions extern fn puts str -> i32 fn should_return b: bool -> str = - if ret b then "true" + if b then "true" else "false" @entry From 4c9ca93509435f83f8710a53cb6264fd691602d1 Mon Sep 17 00:00:00 2001 From: chronium Date: Mon, 22 Mar 2021 16:49:49 +0200 Subject: [PATCH 15/18] The One With Modules XV Milestone II: FizzBuzz --- bench/fizzbuzz.aat | 20 ++++++++ .../src/codegen/unit/cg/conditional/ifelse.rs | 2 +- .../src/codegen/unit/cg/conditional/loops.rs | 47 +++++++++++++++++++ .../src/codegen/unit/cg/conditional/mod.rs | 1 + comp-be/src/codegen/unit/cg/expr.rs | 1 + main.aat | 15 ++++-- parser/src/ast.rs | 2 +- parser/src/parser/pass/type_resolution.rs | 9 ++++ parser/src/tests.rs | 1 - 9 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 bench/fizzbuzz.aat create mode 100644 comp-be/src/codegen/unit/cg/conditional/loops.rs diff --git a/bench/fizzbuzz.aat b/bench/fizzbuzz.aat new file mode 100644 index 0000000..7c020f2 --- /dev/null +++ b/bench/fizzbuzz.aat @@ -0,0 +1,20 @@ +module libc { + public extern fn printf str, ... -> i32 +} + +@entry +fn main () = { + var i = 1 + + until i > 128 { + if i % 3 == 0 && i % 5 == 0 then + libc::printf "FizzBuzz\n" + else if i % 3 == 0 then + libc::printf "Fizz\n" + else if i % 5 == 0 then + libc::printf "Buzz\n" + else libc::printf "%d\n", i + + i = i + 1 + } +} \ No newline at end of file diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index eca1b03..24dd5a8 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -17,7 +17,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { cond_expr, then_expr, elseif_exprs, - else_expr, + else_expr } = expr else { unreachable!() }); let then_bb = ctx.basic_block("then"); diff --git a/comp-be/src/codegen/unit/cg/conditional/loops.rs b/comp-be/src/codegen/unit/cg/conditional/loops.rs new file mode 100644 index 0000000..e689c9c --- /dev/null +++ b/comp-be/src/codegen/unit/cg/conditional/loops.rs @@ -0,0 +1,47 @@ +use parser::ast::{Expression, LoopType, PrimitiveType}; + +use guard::guard; + +use crate::codegen::{ + builder::{base, branch}, + unit::{cg::expr, CompilerContext}, + ValueTypePair, +}; + +pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { + guard!(let Expression::Loop { + loop_type, + cond_expr, + body + } = expr else { unreachable!() }); + + let cond_bb = ctx.basic_block(""); + let body_bb = ctx.basic_block(""); + let end_bb = ctx.basic_block(""); + + branch::branch(ctx, cond_bb); + base::pos_at_end(ctx, cond_bb); + let cond = expr::cg(cond_expr, ctx)?; + + if *cond.prim().inner() != PrimitiveType::Bool { + // TODO: Error + /*self.add_error(CompileError::ExpectedType { + expected_ty: PrimitiveType::Bool.fmt(), + found_ty: cond.prim().fmt(), + value: cond_expr.fmt(), + });*/ + }; + + match loop_type { + LoopType::While => branch::cond_branch(ctx, *cond, body_bb, end_bb), + LoopType::Until => branch::cond_branch(ctx, *cond, end_bb, body_bb), + }; + + base::pos_at_end(ctx, body_bb); + expr::cg(body, ctx); + + branch::branch(ctx, cond_bb); + base::pos_at_end(ctx, end_bb); + + None +} diff --git a/comp-be/src/codegen/unit/cg/conditional/mod.rs b/comp-be/src/codegen/unit/cg/conditional/mod.rs index 4f1a6ac..0ae47bc 100644 --- a/comp-be/src/codegen/unit/cg/conditional/mod.rs +++ b/comp-be/src/codegen/unit/cg/conditional/mod.rs @@ -1 +1,2 @@ pub mod ifelse; +pub mod loops; diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 900017c..290f19d 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -12,6 +12,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { Expression::Assign { .. } => assign::cg(expr, ctx), Expression::Decl { .. } => decl::cg(expr, ctx), + Expression::Loop { .. } => conditional::loops::cg(expr, ctx), Expression::If { .. } => conditional::ifelse::cg(expr, ctx), Expression::Binary(..) => Some(binary::cg(expr, ctx).ok().expect("todo")), Expression::Call { .. } => call::cg(expr, ctx), diff --git a/main.aat b/main.aat index 6062d10..7c020f2 100644 --- a/main.aat +++ b/main.aat @@ -4,10 +4,17 @@ module libc { @entry fn main () = { - var i = 128 + var i = 1 - libc::printf "%d\n", i - i = 256 + until i > 128 { + if i % 3 == 0 && i % 5 == 0 then + libc::printf "FizzBuzz\n" + else if i % 3 == 0 then + libc::printf "Fizz\n" + else if i % 5 == 0 then + libc::printf "Buzz\n" + else libc::printf "%d\n", i - libc::printf "%d\n", i + i = i + 1 + } } \ No newline at end of file diff --git a/parser/src/ast.rs b/parser/src/ast.rs index dbc706b..c47867f 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -101,7 +101,7 @@ pub enum BindType { Constant, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum LoopType { While, Until, diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 650e616..77502c3 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -109,6 +109,15 @@ fn resolve_expr(variants: &Vec, ast: &Expression) -> Expression { .map(|box ex| box resolve_expr(variants, &ex)), then_expr: box resolve_expr(variants, then_expr), }, + Expression::Loop { + loop_type, + cond_expr: box cond_expr, + body: box body, + } => Expression::Loop { + cond_expr: box resolve_expr(variants, cond_expr), + body: box resolve_expr(variants, body), + loop_type: *loop_type, + }, Expression::RecordInit { record, types, diff --git a/parser/src/tests.rs b/parser/src/tests.rs index c232c3f..bd3664b 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod parser_tests { - use crate::ast::AST::Expr; use crate::{ ast::{AtomKind, BindType, Boolean, FunctionType, IdentPath, IntSize, LValue, TypeKind}, lexer::{token::Token, Lexer}, From f55c134e734a4864a3c62df8cdac54f692885081 Mon Sep 17 00:00:00 2001 From: chronium Date: Fri, 26 Mar 2021 09:14:46 +0200 Subject: [PATCH 16/18] The One With Modules XVI Generics --- comp-be/src/codegen/module.rs | 8 +- comp-be/src/codegen/scope.rs | 31 ++++-- comp-be/src/codegen/unit/cg/call.rs | 58 ++++++---- .../src/codegen/unit/cg/conditional/ifelse.rs | 2 +- .../src/codegen/unit/cg/conditional/loops.rs | 15 +-- comp-be/src/codegen/unit/cg/expr.rs | 1 + comp-be/src/codegen/unit/compiler.rs | 104 ++++++++++-------- comp-be/src/codegen/unit/decl/expr.rs | 6 +- comp-be/src/codegen/unit/function.rs | 14 +-- comp-be/src/codegen/unit/generic/gen.rs | 103 +++++++++++++++++ comp-be/src/codegen/unit/generic/mod.rs | 94 ++++++++++++++++ comp-be/src/codegen/unit/mod.rs | 2 + comp-be/src/ty/infer.rs | 2 +- main.aat | 18 +-- main.aat.bak | 6 +- parser/src/ast.rs | 2 +- 16 files changed, 349 insertions(+), 117 deletions(-) create mode 100644 comp-be/src/codegen/unit/generic/gen.rs create mode 100644 comp-be/src/codegen/unit/generic/mod.rs diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index f2924b9..ee7d5a1 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -90,13 +90,15 @@ impl AatbeModule { CompilerUnit::new( base_cu.path().clone(), - box main_ast, &self.llvm_context, &self.llvm_module, ) .in_root_scope(|root_module| { - root_module.decl(&root_builder); - root_module.codegen(&root_builder); + //root_module.decl(&root_builder, &main_ast); + root_module.generics(&root_builder, &main_ast); + root_module.decl(&root_builder, &main_ast); + root_module.codegen(&root_builder, &main_ast); + //root_module.codegen(&root_builder, &main_ast); }); } diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 74f49e0..727d02d 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -5,15 +5,16 @@ use crate::codegen::unit::{ use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; -use parser::ast::FunctionType; +use parser::ast::{Expression, FunctionType}; #[derive(Debug)] pub struct Scope { refs: HashMap, functions: FunctionMap, name: String, - function: Option<(Vec, FunctionType)>, + function: Option<(String, FunctionType)>, fdir: Option, + function_templates: HashMap, } impl Scope { @@ -24,6 +25,7 @@ impl Scope { name: String::default(), function: None, fdir: None, + function_templates: HashMap::new(), } } pub fn with_name(name: &String) -> Self { @@ -33,6 +35,7 @@ impl Scope { name: name.clone(), function: None, fdir: None, + function_templates: HashMap::new(), } } pub fn with_builder(builder: Builder) -> Self { @@ -42,6 +45,7 @@ impl Scope { name: String::default(), function: None, fdir: None, + function_templates: HashMap::new(), } } pub fn with_fdir

(fdir: P) -> Self @@ -54,23 +58,36 @@ impl Scope { name: String::default(), function: None, fdir: Some(fdir.into()), + function_templates: HashMap::new(), } } - pub fn with_function(func: (Vec, FunctionType), builder: Builder) -> Self { + pub fn with_function(func: (String, FunctionType)) -> Self { Self { refs: HashMap::new(), functions: HashMap::new(), - name: func.0.join("::"), + name: func.0.clone(), function: Some(func), fdir: None, + function_templates: HashMap::new(), } } - pub fn func_by_name(&self, name: &Vec) -> Option> { + pub fn func_by_name(&self, name: &String) -> Option> { self.functions.get(name).cloned() } - pub fn add_function(&mut self, name: &Vec, func: Func) { + pub fn get_template(&self, name: &String) -> Option { + self.function_templates.get(name).map(|expr| expr.clone()) + } + + pub fn add_template(&mut self, name: String, func: Expression) { + if self.function_templates.insert(name, func).is_some() { + // TODO: Error + panic!("ERROR"); + } + } + + pub fn add_function(&mut self, name: &String, func: Func) { if !self.functions.contains_key(name) { self.functions.insert(name.clone(), RefCell::new(vec![])); } @@ -88,7 +105,7 @@ impl Scope { pub fn add_symbol(&mut self, name: &String, unit: Slot) { self.refs.insert(name.clone(), unit); } - pub fn function(&self) -> Option<(Vec, FunctionType)> { + pub fn function(&self) -> Option<(String, FunctionType)> { self.function.clone() } pub fn fdir(&self) -> Option { diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index 192929f..96987f2 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -2,6 +2,8 @@ use std::borrow::Borrow; use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; +use llvm_sys_wrapper::LLVMValueRef; + use crate::{ codegen::{ builder::base, @@ -23,10 +25,39 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { } = expr else { unreachable!() }); ctx.trace(format!("Call {}", AatbeFmt::fmt(expr))); - let mut call_types = vec![]; + guard!(let Some((call_types, mut call_args)) = compute_arguments(args, ctx) else { + trace!("Got error"); + return None + }); + + let prefix = |path: &IdentPath| -> Vec { + match path { + IdentPath::Local(name) => prefix!(call ctx, name.clone()), + IdentPath::Module(name) => prefix!(call module ctx, name.clone()), + _ => todo!(), + } + }; + + find_function( + match ctx.query(Query::FunctionGroup(prefix(name).join("::"))) { + QueryResponse::FunctionGroup(Some(group)) => group, + QueryResponse::FunctionGroup(None) => todo!("no function found"), + _ => unreachable!(), + }, + &call_types, + ) + .map(|func| base::call(ctx, func.upgrade().expect("ICE").borrow(), &mut call_args)) +} + +fn compute_arguments( + args: &Vec, + ctx: &CompilerContext, +) -> Option<(Vec, Vec)> { + let mut call_types = vec![]; let mut error = false; - let mut call_args = args + + let call_args = args .iter() .filter_map(|arg| match arg { Expression::Atom(AtomKind::SymbolLiteral(sym)) => { @@ -62,25 +93,8 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { .collect::>(); if error { - trace!("Got error"); - return None; + None + } else { + Some((call_types, call_args)) } - - let prefix = |path: &IdentPath| -> Vec { - match path { - IdentPath::Local(name) => prefix!(call ctx, name.clone()), - IdentPath::Module(name) => prefix!(call module ctx, name.clone()), - _ => todo!(), - } - }; - - find_function( - match ctx.query(Query::FunctionGroup(prefix(name))) { - QueryResponse::FunctionGroup(Some(group)) => group, - QueryResponse::FunctionGroup(None) => todo!("no function found"), - _ => unreachable!(), - }, - &call_types, - ) - .map(|func| base::call(ctx, func.upgrade().expect("ICE").borrow(), &mut call_args)) } diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index 24dd5a8..fc973b3 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -34,7 +34,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { }) .collect::>(); let else_bb = else_expr.as_ref().map(|_| ctx.basic_block("else")); - let end_bb = ctx.basic_block("end"); + let end_bb = ctx.basic_block("if_end"); ctx.dispatch(Message::EnterIfScope(cond_expr.fmt())); let cond = expr::cg(cond_expr, ctx)?; diff --git a/comp-be/src/codegen/unit/cg/conditional/loops.rs b/comp-be/src/codegen/unit/cg/conditional/loops.rs index e689c9c..5001cd7 100644 --- a/comp-be/src/codegen/unit/cg/conditional/loops.rs +++ b/comp-be/src/codegen/unit/cg/conditional/loops.rs @@ -15,9 +15,8 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { body } = expr else { unreachable!() }); - let cond_bb = ctx.basic_block(""); - let body_bb = ctx.basic_block(""); - let end_bb = ctx.basic_block(""); + let cond_bb = ctx.basic_block("while_cond"); + let body_bb = ctx.basic_block("while_body"); branch::branch(ctx, cond_bb); base::pos_at_end(ctx, cond_bb); @@ -32,15 +31,17 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { });*/ }; + base::pos_at_end(ctx, body_bb); + expr::cg(body, ctx); + branch::branch(ctx, cond_bb); + + base::pos_at_end(ctx, cond_bb); + let end_bb = ctx.basic_block("while_end"); match loop_type { LoopType::While => branch::cond_branch(ctx, *cond, body_bb, end_bb), LoopType::Until => branch::cond_branch(ctx, *cond, end_bb, body_bb), }; - base::pos_at_end(ctx, body_bb); - expr::cg(body, ctx); - - branch::branch(ctx, cond_bb); base::pos_at_end(ctx, end_bb); None diff --git a/comp-be/src/codegen/unit/cg/expr.rs b/comp-be/src/codegen/unit/cg/expr.rs index 290f19d..36006bb 100644 --- a/comp-be/src/codegen/unit/cg/expr.rs +++ b/comp-be/src/codegen/unit/cg/expr.rs @@ -25,6 +25,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { } => None, _ => declare_and_compile_function(ctx, expr), }, + Expression::Function { .. } => None, Expression::Block(body) if body.len() == 0 => None, Expression::Block(body) => { ctx.dispatch(Message::EnterAnonymousScope); diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index 2e7970a..0e0fe79 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -5,7 +5,7 @@ use parser::ast::{Expression, FunctionType, AST}; use crate::{ codegen::{ - unit::{cg, decl, function::find_func}, + unit::{cg, decl, function::find_func, generic}, Scope, ValueTypePair, }, fmt::AatbeFmt, @@ -24,8 +24,9 @@ pub enum FunctionVisibility { } pub enum Message { + PushFunctionTemplate(String, Expression), PushInScope(String, Slot), - DeclareFunction(Vec, Func, FunctionVisibility), + DeclareFunction(String, Func, FunctionVisibility), EnterFunctionScope((String, FunctionType)), EnterModuleScope(String), ExitModuleScope(String), @@ -40,6 +41,9 @@ pub enum Message { impl std::fmt::Debug for Message { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match &self { + Message::PushFunctionTemplate(name, expr) => { + f.debug_tuple("PushFunctionTemplate").field(name).finish() + } Message::PushInScope(name, slot) => f .debug_tuple("PushInScope") .field(name) @@ -78,8 +82,8 @@ impl std::fmt::Debug for Message { pub enum Query<'cmd> { Slot(&'cmd String), - Function((Vec, &'cmd FunctionType)), - FunctionGroup(Vec), + Function((String, &'cmd FunctionType)), + FunctionGroup(String), Prefix, } @@ -89,7 +93,7 @@ impl std::fmt::Debug for Query<'_> { Query::Slot(name) => f.debug_tuple("Slot").field(name).finish(), Query::Function(func) => f .debug_tuple("Function") - .field(&func.0.join("::")) + .field(&func.0) .field(&AatbeFmt::fmt(func.1)) .finish(), Query::FunctionGroup(name) => f.debug_tuple("FunctionGroup").field(name).finish(), @@ -140,7 +144,6 @@ pub struct CompilerContext<'ctx> { pub llvm_context: &'ctx Context, pub llvm_module: &'ctx Module, pub llvm_builder: &'ctx Builder, - pub function_templates: HashMap, dispatch: &'ctx dyn Fn(Message) -> (), query: &'ctx dyn Fn(Query) -> QueryResponse, trace: &'ctx dyn Fn(String) -> (), @@ -170,7 +173,6 @@ impl<'ctx> CompilerContext<'ctx> { query, trace, basic_block, - function_templates: HashMap::new(), } } @@ -184,7 +186,6 @@ impl<'ctx> CompilerContext<'ctx> { query: self.query, trace: self.trace, basic_block: self.basic_block, - function_templates: HashMap::new(), } } @@ -219,7 +220,6 @@ impl<'ctx> CompilerContext<'ctx> { pub struct CompilerUnit<'ctx> { modules: HashMap>, - ast: Box, _typectx: TypeContext, llvm_context: &'ctx Context, llvm_module: &'ctx Module, @@ -227,21 +227,16 @@ pub struct CompilerUnit<'ctx> { module_scopes: RefCell>, path: PathBuf, ident: RefCell, + generic_processor: RefCell, } impl<'ctx> CompilerUnit<'ctx> { - pub fn new

( - path: P, - ast: Box, - llvm_context: &'ctx Context, - llvm_module: &'ctx Module, - ) -> Self + pub fn new

(path: P, llvm_context: &'ctx Context, llvm_module: &'ctx Module) -> Self where P: Into, { Self { path: path.into(), - ast, llvm_context, llvm_module, modules: HashMap::new(), @@ -249,6 +244,7 @@ impl<'ctx> CompilerUnit<'ctx> { scope_stack: RefCell::new(vec![]), module_scopes: RefCell::new(HashMap::new()), ident: RefCell::new(0), + generic_processor: RefCell::new(generic::Processor::new()), } } @@ -273,13 +269,13 @@ impl<'ctx> CompilerUnit<'ctx> { self.scope_stack.borrow_mut().push(Scope::new()); } - fn enter_function_scope(&self, func: (String, FunctionType), builder: Builder) { + fn enter_function_scope(&self, func: (String, FunctionType)) { let mut prefix = self.get_prefix(); prefix.push(func.0); self.scope_stack .borrow_mut() - .push(Scope::with_function((prefix, func.1), builder)); + .push(Scope::with_function((prefix.join("::"), func.1))); } fn enter_module_scope(&self, name: String) { @@ -312,6 +308,14 @@ impl<'ctx> CompilerUnit<'ctx> { .add_symbol(name, unit); } + pub fn push_function_template(&self, name: String, func: Expression) { + self.scope_stack + .borrow_mut() + .last_mut() + .expect("Compiler broke. Scope stack is corrupted.") + .add_template(name, func); + } + pub fn get_from_scope(&self, name: &String) -> Option { for scope in self.scope_stack.borrow().iter().rev() { if let Some(sym) = scope.find_symbol(name) { @@ -341,13 +345,15 @@ impl<'ctx> CompilerUnit<'ctx> { fn dispatch(&self, message: Message) { print!("{}", "│ ".repeat(*self.ident.borrow())); + println!("├── {:?}", message); match message { - Message::PushInScope(ref name, ref unit) => { - println!("├── {:?}", message); + Message::PushFunctionTemplate(name, func) => { + self.push_function_template(name, func); + } + Message::PushInScope(ref name, unit) => { self.push_in_scope(name, unit.clone()); } - Message::DeclareFunction(ref name, ref func, ty) => { - println!("├── {:?}", message); + Message::DeclareFunction(name, func, ty) => { let mut scope_stack = self.scope_stack.borrow_mut(); if ty == FunctionVisibility::Local { scope_stack.last_mut() @@ -357,49 +363,39 @@ impl<'ctx> CompilerUnit<'ctx> { .expect("ICE: Scope stack is corrupted.") .add_function(&name, func.clone()); } - Message::EnterFunctionScope(ref func) => { - println!("├── {:?}", message); + Message::EnterFunctionScope(func) => { *self.ident.borrow_mut() += 1; - let builder = Builder::new_in_context(self.llvm_context.as_ref()); - self.enter_function_scope(func.clone(), builder); + self.enter_function_scope(func.clone()); } - Message::EnterModuleScope(ref name) => { - println!("├── {:?}", message); + Message::EnterModuleScope(name) => { *self.ident.borrow_mut() += 1; self.enter_module_scope(name.clone()) } - Message::ExitModuleScope(ref name) => { - println!("└── {:?}", message); + Message::ExitModuleScope(name) => { *self.ident.borrow_mut() -= 1; self.exit_module_scope(name.clone()) } - Message::RestoreModuleScope(ref name) => { - println!("├── {:?}", message); + Message::RestoreModuleScope(name) => { *self.ident.borrow_mut() += 1; self.restore_module_scope(name.clone()) } Message::EnterIfScope(_) => { - println!("├── {:?}", message); *self.ident.borrow_mut() += 1; self.enter_anonymous_scope() } Message::EnterElseIfScope(_) => { - println!("├── {:?}", message); *self.ident.borrow_mut() += 1; self.enter_anonymous_scope() } Message::EnterElseScope => { - println!("├── {:?}", message); *self.ident.borrow_mut() += 1; self.enter_anonymous_scope() } Message::EnterAnonymousScope => { - println!("├── {:?}", message); *self.ident.borrow_mut() += 1; self.enter_anonymous_scope() } Message::ExitScope => { - println!("└── {:?}", message); *self.ident.borrow_mut() -= 1; self.exit_scope() } @@ -437,15 +433,14 @@ impl<'ctx> CompilerUnit<'ctx> { self.modules.get_mut(name) } - pub fn decl(&'ctx self, root_builder: &Builder) { - let ast = self.ast.clone(); + pub fn decl(&'ctx self, root_builder: &Builder, ast: &AST) { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); let trace = &|message: String| self.trace(message); let basic_block = &|name: &str| self.basic_block(name); decl::decl( - &*ast, + ast, &mut CompilerContext::new( self.path.clone(), self.llvm_context, @@ -459,15 +454,28 @@ impl<'ctx> CompilerUnit<'ctx> { ); } - pub fn codegen(&'ctx self, root_builder: &Builder) -> Option { - let ast = self.ast.clone(); + pub fn generics(&'ctx self, root_builder: &Builder, ast: &AST) { + let mut proc = self.generic_processor.borrow_mut(); + let ast = proc + .extract_function_calls(ast) + .extract_tree(ast) + .generate_tree() + .generated_tree + .as_ref() + .unwrap(); + + self.decl(root_builder, ast); + self.codegen(root_builder, ast); + } + + pub fn codegen(&'ctx self, root_builder: &Builder, ast: &AST) -> Option { let dispatch = &|command: Message| self.dispatch(command); let query = &|query: Query| self.query(query); let trace = &|message: String| self.trace(message); let basic_block = &|name: &str| self.basic_block(name); cg::cg( - &*ast, + ast, &CompilerContext::new( self.path.clone(), self.llvm_context, @@ -481,17 +489,23 @@ impl<'ctx> CompilerUnit<'ctx> { ) } - pub fn get_func_group(&self, name: &Vec) -> Option> { + pub fn get_func_group(&self, name: &String) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { if let Some(func) = scope.func_by_name(&name) { return Some(func); } } + for scope in self.scope_stack.borrow().iter().rev() { + if let Some(func) = scope.get_template(&name) { + println!("Found template!"); + } + } + None } - pub fn get_func(&self, func: (Vec, &FunctionType)) -> Option> { + pub fn get_func(&self, func: (String, &FunctionType)) -> Option> { for scope in self.scope_stack.borrow().iter().rev() { if let Some(group) = scope.func_by_name(&func.0) { return find_func(group, func.1); diff --git a/comp-be/src/codegen/unit/decl/expr.rs b/comp-be/src/codegen/unit/decl/expr.rs index 04e54f0..15370d0 100644 --- a/comp-be/src/codegen/unit/decl/expr.rs +++ b/comp-be/src/codegen/unit/decl/expr.rs @@ -1,6 +1,6 @@ use parser::ast::Expression; -use crate::codegen::unit::{declare_function, CompilerContext}; +use crate::codegen::unit::{declare_function, CompilerContext, Message}; pub fn decl(expr: &Expression, ctx: &mut CompilerContext) { match expr { @@ -8,9 +8,7 @@ pub fn decl(expr: &Expression, ctx: &mut CompilerContext) { declare_function(ctx, expr) } Expression::Function { name, .. } => { - if !ctx.function_templates.contains_key(name) { - ctx.function_templates.insert(name.clone(), expr.clone()); - } + ctx.dispatch(Message::PushFunctionTemplate(name.clone(), expr.clone())); } _ => panic!("Top level {:?} unsupported", expr), } diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 82ad888..4cfa499 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -30,7 +30,7 @@ use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; #[derive(Clone)] pub struct Func { ty: FunctionType, - ident: Vec, + ident: String, inner: Function, } @@ -49,14 +49,14 @@ impl AatbeFmt for &Func { } else { String::default() }, - self.ident.join("::"), + self.ident, (&self.ty).fmt() ) } } pub type FuncTyMap = Vec>; -pub type FunctionMap = HashMap, RefCell>; +pub type FunctionMap = HashMap>; pub fn find_func<'a>(map: RefCell, ty: &FunctionType) -> Option> { for func in map.borrow().iter() { @@ -84,7 +84,7 @@ impl Deref for Func { } impl Func { - pub fn new(ty: FunctionType, ident: Vec, inner: Function) -> Self { + pub fn new(ty: FunctionType, ident: String, inner: Function) -> Self { Self { ty, ident, inner } } @@ -147,7 +147,7 @@ pub fn declare_function(ctx: &CompilerContext, function: &Expression) { .llvm_module .get_or_add_function(&function.mangle(&ctx), ty.llvm_ty_in_ctx(&ctx)); - let name = prefix!(ctx, name.clone()); + let name = prefix!(ctx, name.clone()).join("::"); let func = Func::new(ty.clone(), name.clone(), func); if !public { ctx.dispatch(Message::DeclareFunction( @@ -226,7 +226,7 @@ pub fn codegen_function(ctx: &CompilerContext, function: &Expression) { ty, .. } => { - let func = ctx.query(Query::Function((prefix!(ctx), ty))); + let func = ctx.query(Query::Function((prefix!(ctx).join("::"), ty))); guard!(let QueryResponse::Function(Some(func)) = func else { unreachable!(); }); let func = func.upgrade().expect("ICE"); @@ -305,7 +305,7 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { ty: Some(box PrimitiveType::Ref(ty) | ty), } => { guard!(let QueryResponse::Function(Some(func)) = - ctx.query(Query::Function((prefix!(ctx), fty))) + ctx.query(Query::Function((prefix!(ctx).join("::"), fty))) else { unreachable!() }); let func = func.upgrade().expect("ICE"); diff --git a/comp-be/src/codegen/unit/generic/gen.rs b/comp-be/src/codegen/unit/generic/gen.rs new file mode 100644 index 0000000..89e0b33 --- /dev/null +++ b/comp-be/src/codegen/unit/generic/gen.rs @@ -0,0 +1,103 @@ +use std::collections::HashMap; + +use parser::ast::{Expression, FunctionType, IdentPath, PrimitiveType, AST}; + +use super::Processor; + +use guard::guard; + +pub fn gen(ast: &AST, proc: &Processor) -> Option { + match ast { + AST::Module(..) => { + // TODO: Module + None + } + AST::File(body) => Some(AST::File( + body.iter() + .filter_map(|ast| gen_tree(ast, proc)) + .flatten() + .collect::>(), + )), + _ => todo!("{:?}", ast), + } +} + +fn gen_tree(ast: &AST, proc: &Processor) -> Option> { + match ast { + AST::Module(..) => { + // TODO: Module + None + } + AST::Expr(expr) => gen_expr(expr, proc).and_then(|exprs| { + Some( + exprs + .iter() + .map(|expr| AST::Expr(expr.clone())) + .collect::>(), + ) + }), + _ => todo!("{:?}", ast), + } +} + +fn gen_expr(expr: &Expression, proc: &Processor) -> Option> { + match expr { + Expression::Function { + type_names, + name, + ty: + FunctionType { + ext, + ret_ty, + params, + }, + body, + attributes, + public, + } => { + guard!(let Some(types) = proc + .function_calls + .get(&IdentPath::Local(name.clone())) else { return None; }); + + Some( + types + .iter() + .map(|set| { + let map = type_names.iter().zip(set).collect::>(); + + Expression::Function { + type_names: vec![], + name: name.clone(), + ty: FunctionType { + ext: *ext, + ret_ty: box resolve_type(ret_ty, &map), + params: params + .iter() + .map(|ty| resolve_type(ty, &map)) + .collect::>(), + }, + body: body.clone(), + attributes: attributes.clone(), + public: *public, + } + }) + .collect(), + ) + } + _ => todo!("{:?}", expr), + } +} + +fn resolve_type(ty: &PrimitiveType, map: &HashMap<&String, &PrimitiveType>) -> PrimitiveType { + match ty { + PrimitiveType::NamedType { + name, + ty: Some(box ty), + } => PrimitiveType::NamedType { + name: name.clone(), + ty: Some(box resolve_type(ty, map)), + }, + PrimitiveType::TypeRef(name) => map.get(name).cloned().unwrap().clone(), + _ => ty.clone(), + } +} diff --git a/comp-be/src/codegen/unit/generic/mod.rs b/comp-be/src/codegen/unit/generic/mod.rs new file mode 100644 index 0000000..50786f6 --- /dev/null +++ b/comp-be/src/codegen/unit/generic/mod.rs @@ -0,0 +1,94 @@ +use std::collections::{HashMap, HashSet}; + +use parser::ast::{Expression, IdentPath, PrimitiveType, AST}; + +mod gen; + +#[derive(Debug)] +pub struct Processor { + pub(super) function_calls: HashMap>>, + extracted_tree: Option, + pub generated_tree: Option, +} + +impl Processor { + pub fn new() -> Self { + Self { + function_calls: HashMap::new(), + extracted_tree: None, + generated_tree: None, + } + } + + pub fn extract_function_calls(&mut self, ast: &AST) -> &mut Self { + match ast { + AST::Module(..) => { + // TODO: Module + } + AST::File(body) => body.iter().for_each(|ast| { + self.extract_function_calls(ast); + }), + AST::Expr(expr) => self.from_expression(expr), + _ => todo!("{:?}", ast), + }; + + self + } + + fn from_expression(&mut self, expr: &Expression) { + match expr { + Expression::Function { + body: Some(box body), + .. + } => self.from_expression(body), + Expression::Call { name, types, .. } if types.len() > 0 => { + self.insert_function_call(name, types.clone()) + } + Expression::Block(body) => body.iter().for_each(|e| self.from_expression(e)), + _ => {} + } + } + + pub fn extract_tree(&mut self, ast: &AST) -> &mut Self { + println!("{:#?}", ast); + self.extracted_tree = extract_ast(ast); + println!("{:#?}", self.extracted_tree); + self + } + + pub fn generate_tree(&mut self) -> &mut Self { + let ast = self.extracted_tree.as_ref().unwrap(); + self.generated_tree = gen::gen(ast, &self); + println!("{:#?}", self.generated_tree); + self + } + + fn insert_function_call(&mut self, name: &IdentPath, types: Vec) { + if !self.function_calls.contains_key(name) { + self.function_calls.insert(name.clone(), HashSet::new()); + } + + self.function_calls.get_mut(name).unwrap().insert(types); + } +} + +fn extract_ast(ast: &AST) -> Option { + match ast { + AST::Module(..) => { + // TODO: Module + None + } + AST::File(body) => Some(AST::File( + body.iter().filter_map(extract_ast).collect::>(), + )), + AST::Expr(expr) => extract_expr(expr).and_then(|expr| Some(AST::Expr(expr))), + _ => todo!("{:?}", ast), + } +} + +fn extract_expr(expr: &Expression) -> Option { + match expr { + Expression::Function { type_names, .. } if type_names.len() > 0 => Some(expr.clone()), + _ => None, + } +} diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 3f74256..17e8726 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -22,6 +22,8 @@ pub use decl::decl; pub mod cg; pub use cg::cg; +pub mod generic; + #[derive(Debug, Clone)] pub enum Mutability { Immutable, diff --git a/comp-be/src/ty/infer.rs b/comp-be/src/ty/infer.rs index fdcd6d1..987ab2c 100644 --- a/comp-be/src/ty/infer.rs +++ b/comp-be/src/ty/infer.rs @@ -34,7 +34,7 @@ pub fn infer_type(ctx: &CompilerContext, expr: &Expression) -> Option<(Primitive }; find_function( - match ctx.query(Query::FunctionGroup(prefix(name))) { + match ctx.query(Query::FunctionGroup(prefix(name).join("::"))) { QueryResponse::FunctionGroup(Some(group)) => group, QueryResponse::FunctionGroup(None) => todo!("no function found"), _ => unreachable!(), diff --git a/main.aat b/main.aat index 7c020f2..ae95bf0 100644 --- a/main.aat +++ b/main.aat @@ -1,20 +1,6 @@ -module libc { - public extern fn printf str, ... -> i32 -} +fn test[T] a: T, b: T = a + b @entry fn main () = { - var i = 1 - - until i > 128 { - if i % 3 == 0 && i % 5 == 0 then - libc::printf "FizzBuzz\n" - else if i % 3 == 0 then - libc::printf "Fizz\n" - else if i % 5 == 0 then - libc::printf "Buzz\n" - else libc::printf "%d\n", i - - i = i + 1 - } + test[i32] 1, 2 } \ No newline at end of file diff --git a/main.aat.bak b/main.aat.bak index 75b2a61..d6a93c9 100644 --- a/main.aat.bak +++ b/main.aat.bak @@ -2,9 +2,9 @@ module libc { public extern fn printf str, ... -> i32 } -fn test() -> () = () +fn add[I] a: I, b: I -> I = a + b @entry fn main () = { - test() -} + libc::printf "%d\n", add[i32] 10, 8 +} \ No newline at end of file diff --git a/parser/src/ast.rs b/parser/src/ast.rs index c47867f..d752d56 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -2,7 +2,7 @@ use std::fmt; type ModPath = Vec; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq, Hash)] pub enum IdentPath { Local(String), Module(ModPath), From 42a79ec451c1d5225d3f06cc857e1b4963f437a2 Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 27 Mar 2021 07:53:50 +0200 Subject: [PATCH 17/18] The One With Modules XVII --- comp-be/src/codegen/builder/value.rs | 8 ++++++ comp-be/src/codegen/module.rs | 6 ++-- comp-be/src/codegen/scope.rs | 4 +-- comp-be/src/codegen/unit/cg/atom.rs | 2 +- comp-be/src/codegen/unit/cg/call.rs | 2 +- .../src/codegen/unit/cg/conditional/ifelse.rs | 4 +++ comp-be/src/codegen/unit/compiler.rs | 5 +--- main.aat | 28 +++++++++++++++++-- main.aat.bak | 16 +++++++++++ parser/src/parser/macros.rs | 4 +++ 10 files changed, 66 insertions(+), 13 deletions(-) diff --git a/comp-be/src/codegen/builder/value.rs b/comp-be/src/codegen/builder/value.rs index 06df75a..a1170ff 100644 --- a/comp-be/src/codegen/builder/value.rs +++ b/comp-be/src/codegen/builder/value.rs @@ -135,3 +135,11 @@ pub fn str(ctx: &CompilerContext, string: &str) -> ValueTypePair { ) .into() } + +pub fn unit(ctx: &CompilerContext) -> ValueTypePair { + ( + ctx.llvm_context.Null(ctx.llvm_context.VoidType()), + PrimitiveType::Unit, + ) + .into() +} diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index ee7d5a1..c079847 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -94,11 +94,11 @@ impl AatbeModule { &self.llvm_module, ) .in_root_scope(|root_module| { - //root_module.decl(&root_builder, &main_ast); - root_module.generics(&root_builder, &main_ast); root_module.decl(&root_builder, &main_ast); - root_module.codegen(&root_builder, &main_ast); + //root_module.generics(&root_builder, &main_ast); + //root_module.decl(&root_builder, &main_ast); //root_module.codegen(&root_builder, &main_ast); + root_module.codegen(&root_builder, &main_ast); }); } diff --git a/comp-be/src/codegen/scope.rs b/comp-be/src/codegen/scope.rs index 727d02d..41f01f8 100644 --- a/comp-be/src/codegen/scope.rs +++ b/comp-be/src/codegen/scope.rs @@ -117,10 +117,10 @@ impl Scope { } pub fn bb(&self, module: &CompilerUnit, name: &str) -> Option { - let func = self.function.as_ref()?; + let (_, ty) = self.function.as_ref()?; Some( - find_func(module.get_func_group(&func.0)?, &func.1) + find_func(module.get_func_group(&module.get_prefix().join("::"))?, &ty) .unwrap() .upgrade() .expect("ICE") diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index 5f93656..48f5051 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -19,7 +19,7 @@ pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { ctx.trace(format!("Atom {}", atom.fmt())); match atom { AtomKind::Parenthesized(expr) => expr::cg(expr, ctx), - AtomKind::Unit => None, + AtomKind::Unit => Some(value::unit(ctx)), AtomKind::Bool(Boolean::True) => Some(value::t(ctx)), AtomKind::Bool(Boolean::False) => Some(value::f(ctx)), atom diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index 96987f2..cd133cb 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -35,7 +35,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match path { IdentPath::Local(name) => prefix!(call ctx, name.clone()), IdentPath::Module(name) => prefix!(call module ctx, name.clone()), - _ => todo!(), + IdentPath::Root(name) => name.clone(), } }; diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index fc973b3..6e6f36a 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -154,6 +154,10 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { blocks.push(else_bb.unwrap()); } + if ty == PrimitiveType::Unit { + return None; + } + match values.len() { 0 => None, 1 => Some(then_val), diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index 0e0fe79..cb430ef 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -270,12 +270,9 @@ impl<'ctx> CompilerUnit<'ctx> { } fn enter_function_scope(&self, func: (String, FunctionType)) { - let mut prefix = self.get_prefix(); - prefix.push(func.0); - self.scope_stack .borrow_mut() - .push(Scope::with_function((prefix.join("::"), func.1))); + .push(Scope::with_function((func.0, func.1))); } fn enter_module_scope(&self, name: String) { diff --git a/main.aat b/main.aat index ae95bf0..f35f6f7 100644 --- a/main.aat +++ b/main.aat @@ -1,6 +1,30 @@ -fn test[T] a: T, b: T = a + b +module libc { + public extern fn printf str, ... -> i32 +} + +module std { + public fn println s: str = ::libc::printf "%s\n", s + public fn println c: char = ::libc::printf "%c\n", c + + public fn println b: bool = + if b then println "true" + else println "false" + + public fn println i: i8 = ::libc::printf "%hhi\n", i + public fn println i: i16 = ::libc::printf "%hi\n", i + public fn println i: i32 = ::libc::printf "%i\n", i + public fn println i: i64 = ::libc::printf "%li\n", i + public fn println u: u8 = ::libc::printf "%hhu\n", u + public fn println u: u16 = ::libc::printf "%hu\n", u + public fn println u: u32 = ::libc::printf "%u\n", u + public fn println u: u64 = ::libc::printf "%lu\n", u + public fn println f: f64 = ::libc::printf "%f\n", f + public fn println f: f64 = ::libc::printf "%f\n", f +} @entry fn main () = { - test[i32] 1, 2 + std::println false + std::println 128u16 + std::println 'A' } \ No newline at end of file diff --git a/main.aat.bak b/main.aat.bak index d6a93c9..b13e9ff 100644 --- a/main.aat.bak +++ b/main.aat.bak @@ -2,6 +2,22 @@ module libc { public extern fn printf str, ... -> i32 } +module std { + public fn println s: str -> () = ::libc::printf "%s\n", s + public fn println c: char -> () = ::libc::printf "%c\n", c + + public fn println i: i8 -> () = ::libc::printf "%hhi\n", i + public fn println i: i16 -> () = ::libc::printf "%hi\n", i + public fn println i: i32 -> () = ::libc::printf "%i\n", i + public fn println i: i64 -> () = ::libc::printf "%li\n", i + public fn println u: u8 -> () = ::libc::printf "%hhu\n", u + public fn println u: u16 -> () = ::libc::printf "%hu\n", u + public fn println u: u32 -> () = ::libc::printf "%u\n", u + public fn println u: u64 -> () = ::libc::printf "%lu\n", u + public fn println f: f64 -> () = ::libc::printf "%f\n", f + public fn println f: f64 -> () = ::libc::printf "%f\n", f +} + fn add[I] a: I, b: I -> I = a + b @entry diff --git a/parser/src/parser/macros.rs b/parser/src/parser/macros.rs index 13ccad6..8912656 100644 --- a/parser/src/parser/macros.rs +++ b/parser/src/parser/macros.rs @@ -160,6 +160,10 @@ macro_rules! path { } } + if !matches!($self.peek_symbol(Symbol::LBracket), Some(true)) { + $self.index -= 1; + } + IdentPath::Root(res) } _ => { From 8fb981988931ae61f7f3083eea0081c4857651f2 Mon Sep 17 00:00:00 2001 From: chronium Date: Sat, 1 May 2021 23:30:28 +0300 Subject: [PATCH 18/18] Rename PrimitiveType to Type --- aatboot/src/main.rs | 2 +- comp-be/src/codegen/atom.rs | 76 +++--- comp-be/src/codegen/builder/base.rs | 24 +- comp-be/src/codegen/builder/cast.rs | 22 +- comp-be/src/codegen/builder/op.rs | 4 +- comp-be/src/codegen/builder/value.rs | 51 ++--- comp-be/src/codegen/call.rs | 28 +-- comp-be/src/codegen/conditional.rs | 12 +- comp-be/src/codegen/expr/mod.rs | 10 +- comp-be/src/codegen/mangle_v1.rs | 38 +-- comp-be/src/codegen/mod.rs | 20 +- comp-be/src/codegen/module.rs | 58 ++--- comp-be/src/codegen/unit/cg/atom.rs | 4 +- comp-be/src/codegen/unit/cg/binary/comp.rs | 4 +- comp-be/src/codegen/unit/cg/binary/eqne.rs | 4 +- .../src/codegen/unit/cg/binary/float/arith.rs | 4 +- .../src/codegen/unit/cg/binary/float/cmp.rs | 4 +- .../src/codegen/unit/cg/binary/float/eqne.rs | 4 +- .../src/codegen/unit/cg/binary/int/arith.rs | 4 +- comp-be/src/codegen/unit/cg/binary/int/cmp.rs | 4 +- comp-be/src/codegen/unit/cg/binary/mod.rs | 12 +- .../src/codegen/unit/cg/binary/uint/arith.rs | 4 +- .../src/codegen/unit/cg/binary/uint/cmp.rs | 4 +- comp-be/src/codegen/unit/cg/call.rs | 14 +- .../src/codegen/unit/cg/conditional/ifelse.rs | 12 +- .../src/codegen/unit/cg/conditional/loops.rs | 6 +- comp-be/src/codegen/unit/cg/consts/numeric.rs | 12 +- comp-be/src/codegen/unit/cg/decl.rs | 6 +- comp-be/src/codegen/unit/compiler.rs | 3 +- comp-be/src/codegen/unit/function.rs | 46 ++-- comp-be/src/codegen/unit/generic/gen.rs | 10 +- comp-be/src/codegen/unit/generic/mod.rs | 6 +- comp-be/src/codegen/unit/mod.rs | 50 ++-- comp-be/src/codegen/unit/variable.rs | 38 +-- comp-be/src/fmt.rs | 44 ++-- comp-be/src/ty/infer.rs | 22 +- comp-be/src/ty/mod.rs | 88 +++---- comp-be/src/ty/record.rs | 16 +- comp-be/src/ty/size.rs | 30 +-- comp-be/src/ty/variant.rs | 6 +- libc.aat | 1 + main.aat | 4 +- parser/src/ast.rs | 73 +++--- parser/src/lexer/mod.rs | 20 +- parser/src/lexer/tests.rs | 26 +-- parser/src/lexer/token.rs | 14 +- parser/src/lib.rs | 83 +++---- parser/src/parser/atom.rs | 42 ++-- parser/src/parser/macros.rs | 45 ++++ parser/src/parser/pass/type_resolution.rs | 12 +- parser/src/tests.rs | 216 ++++++++---------- 51 files changed, 668 insertions(+), 674 deletions(-) create mode 100644 libc.aat diff --git a/aatboot/src/main.rs b/aatboot/src/main.rs index 43a1fc7..910247f 100644 --- a/aatboot/src/main.rs +++ b/aatboot/src/main.rs @@ -67,7 +67,7 @@ fn main() -> io::Result<()> { if let Some(libs) = matches.values_of("LIB") { for lib in libs { - let globs = glob(format!("/usr/lib/x86_64-linux-gnu/lib{}.so", lib).as_ref()) + let globs = glob(&format!("/usr/lib/x86_64-linux-gnu/lib{}.so", lib)) .unwrap() .filter_map(Result::ok) .collect::>(); diff --git a/comp-be/src/codegen/atom.rs b/comp-be/src/codegen/atom.rs index 36294c3..dad1cc4 100644 --- a/comp-be/src/codegen/atom.rs +++ b/comp-be/src/codegen/atom.rs @@ -9,7 +9,7 @@ use crate::{ }; use super::builder::value; -use parser::ast::{AtomKind, Boolean, FloatSize, PrimitiveType}; +use parser::ast::{AtomKind, Boolean, FloatSize, Type}; impl AatbeModule { pub fn codegen_atom(&mut self, atom: &AtomKind) -> Option { @@ -18,67 +18,67 @@ impl AatbeModule { AtomKind::Cast(box val, ty) => { let val = self.codegen_atom(val)?; match (val.prim(), ty) { - (PrimitiveType::Char, PrimitiveType::UInt(_)) - | (PrimitiveType::Char, PrimitiveType::Int(_)) => { + (Type::Char, Type::UInt(_)) + | (Type::Char, Type::Int(_)) => { return Some(cast::zext(self, val, ty)) } - (PrimitiveType::Int(from), PrimitiveType::Int(to)) if from < to => { + (Type::Int(from), Type::Int(to)) if from < to => { return Some(cast::zext(self, val, ty)) } - (PrimitiveType::Int(from), PrimitiveType::Int(to)) if from > to => { + (Type::Int(from), Type::Int(to)) if from > to => { return Some(cast::trunc(self, val, ty)) } - (PrimitiveType::Int(from), PrimitiveType::UInt(to)) if from < to => { + (Type::Int(from), Type::UInt(to)) if from < to => { return Some(cast::zext(self, val, ty)) } - (PrimitiveType::Int(from), PrimitiveType::UInt(to)) if from > to => { + (Type::Int(from), Type::UInt(to)) if from > to => { return Some(cast::trunc(self, val, ty)) } - (PrimitiveType::UInt(from), PrimitiveType::Int(to)) if from < to => { + (Type::UInt(from), Type::Int(to)) if from < to => { return Some(cast::zext(self, val, ty)) } - (PrimitiveType::UInt(from), PrimitiveType::Int(to)) if from > to => { + (Type::UInt(from), Type::Int(to)) if from > to => { return Some(cast::trunc(self, val, ty)) } - (PrimitiveType::Int(_), PrimitiveType::Pointer(_)) => { + (Type::Int(_), Type::Pointer(_)) => { return Some(cast::itop(self, val, ty)) } - (PrimitiveType::Pointer(_), PrimitiveType::Int(_)) => { + (Type::Pointer(_), Type::Int(_)) => { return Some(cast::ptoi(self, val, ty)) } - (PrimitiveType::Str, PrimitiveType::Int(_)) => { + (Type::Str, Type::Int(_)) => { return Some(cast::ptoi(self, val, ty)) } - (PrimitiveType::Str, PrimitiveType::UInt(_)) => { + (Type::Str, Type::UInt(_)) => { return Some(cast::ptoi(self, val, ty)) } - (PrimitiveType::UInt(_), PrimitiveType::Pointer(_)) => { + (Type::UInt(_), Type::Pointer(_)) => { return Some(cast::itop(self, val, ty)) } - (PrimitiveType::Pointer(_), PrimitiveType::UInt(_)) => { + (Type::Pointer(_), Type::UInt(_)) => { return Some(cast::ptoi(self, val, ty)) } - (PrimitiveType::Int(_), PrimitiveType::Str) => { + (Type::Int(_), Type::Str) => { return Some(cast::itop(self, val, ty)) } - (PrimitiveType::Int(_), PrimitiveType::Float(_)) => { + (Type::Int(_), Type::Float(_)) => { return Some(cast::stof(self, val, ty)) } - (PrimitiveType::UInt(_), PrimitiveType::Float(_)) => { + (Type::UInt(_), Type::Float(_)) => { return Some(cast::utof(self, val, ty)) } ( - PrimitiveType::Float(FloatSize::Bits64), - PrimitiveType::Float(FloatSize::Bits32), + Type::Float(FloatSize::Bits64), + Type::Float(FloatSize::Bits32), ) => return Some(cast::ftrunc(self, val, ty)), - (PrimitiveType::Float(_), PrimitiveType::Int(_)) => { + (Type::Float(_), Type::Int(_)) => { return Some(cast::ftos(self, val, ty)) } - (PrimitiveType::Float(_), PrimitiveType::UInt(_)) => { + (Type::Float(_), Type::UInt(_)) => { return Some(cast::ftou(self, val, ty)) } // FIXME: Huge hack to work for llvm test - (PrimitiveType::Array { .. }, PrimitiveType::Slice { ty: box ty }) => { + (Type::Array { .. }, Type::Slice { ty: box ty }) => { return Some( ( self.llvm_builder_ref().build_inbounds_gep( @@ -88,7 +88,7 @@ impl AatbeModule { self.llvm_context_ref().SInt32(0), ], ), - PrimitiveType::Pointer(box ty.clone()), + Type::Pointer(box ty.clone()), ) .into(), ) @@ -109,15 +109,15 @@ impl AatbeModule { let mut arr = false; let ty = match ty { - TypeKind::Primitive(PrimitiveType::Str) => { - TypeKind::Primitive(PrimitiveType::Char) + TypeKind::Primitive(Type::Str) => { + TypeKind::Primitive(Type::Char) } - TypeKind::Primitive(PrimitiveType::Array { ty: box ty, .. }) => { + TypeKind::Primitive(Type::Array { ty: box ty, .. }) => { arr = true; TypeKind::Primitive(ty) } - TypeKind::Primitive(PrimitiveType::Slice { ty: box ty }) => { + TypeKind::Primitive(Type::Slice { ty: box ty }) => { arr = true; TypeKind::Primitive(ty) @@ -141,7 +141,7 @@ impl AatbeModule { AtomKind::Deref(path) => { let acc = self.codegen_atom(path)?; match acc.prim() { - PrimitiveType::Newtype(name) => { + Type::Newtype(name) => { let val = core::struct_gep(self, *acc, 0); match self.typectx_ref().get_type(name) { Some(TypeKind::Typedef(TypedefKind::Newtype(_, ty))) => { @@ -150,7 +150,7 @@ impl AatbeModule { _ => unimplemented!(), } } - PrimitiveType::Box(box ty) => Some(core::load_prim(self, *acc, ty.clone())), + Type::Box(box ty) => Some(core::load_prim(self, *acc, ty.clone())), _ => unimplemented!(), } } @@ -170,7 +170,7 @@ impl AatbeModule { let var: ValueTypePair = var_ref.into(); - Some((*var, PrimitiveType::Ref(box var.prim().clone())).into()) + Some((*var, Type::Ref(box var.prim().clone())).into()) } atom @ AtomKind::Integer(_, _) => const_atom(self, atom), atom @ AtomKind::Floating(_, _) => const_atom(self, atom), @@ -182,8 +182,8 @@ impl AatbeModule { .expect(format!("ICE Cannot negate {:?}", val).as_str()); match value.prim() { - PrimitiveType::Int(_) | PrimitiveType::UInt(_) => Some(op::neg(self, value)), - PrimitiveType::Float(_) => Some(op::fneg(self, value)), + Type::Int(_) | Type::UInt(_) => Some(op::neg(self, value)), + Type::Float(_) => Some(op::fneg(self, value)), _ => { self.add_error(CompileError::UnaryMismatch { op: op.clone(), @@ -200,10 +200,10 @@ impl AatbeModule { .codegen_atom(val) .expect(format!("ICE Cannot negate {:?}", val).as_str()); - if value.prim() != &PrimitiveType::Bool { + if value.prim() != &Type::Bool { self.add_error(CompileError::UnaryMismatch { op: op.clone(), - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: value.prim().fmt(), value: val.fmt(), }) @@ -250,7 +250,7 @@ impl AatbeModule { &mut values.iter().map(|val| **val).collect::>(), len, ), - PrimitiveType::Array { + Type::Array { ty: box fst.clone(), len: len, }, @@ -261,7 +261,7 @@ impl AatbeModule { AtomKind::Is(box val, ty) => match val { AtomKind::Ident(val) => { let var_ref = self.get_var(val).expect("").clone(); - if let PrimitiveType::TypeRef(var) = var_ref.var_ty().clone() { + if let Type::TypeRef(var) = var_ref.var_ty().clone() { let variant_ty = self.typectx_ref().get_typedef(&var); match variant_ty { Ok(TypedefKind::VariantType(variant)) if variant.has_variant(ty) => { @@ -289,7 +289,7 @@ impl AatbeModule { Slot::Variable { mutable: var_ref.get_mutability().clone(), name: val.clone(), - ty: PrimitiveType::Variant { + ty: Type::Variant { parent: var, variant: ty.clone(), }, diff --git a/comp-be/src/codegen/builder/base.rs b/comp-be/src/codegen/builder/base.rs index cef1704..a9ace42 100644 --- a/comp-be/src/codegen/builder/base.rs +++ b/comp-be/src/codegen/builder/base.rs @@ -6,7 +6,7 @@ use crate::{ ty::{LLVMTyInCtx, TypeKind}, }; use llvm_sys_wrapper::{LLVMBasicBlockRef, LLVMTypeRef, LLVMValueRef}; -use parser::ast::{IntSize, PrimitiveType}; +use parser::ast::{IntSize, Type}; pub fn load(ctx: &CompilerContext, pointer: LLVMValueRef) -> LLVMValueRef { ctx.llvm_builder.build_load(pointer) @@ -16,7 +16,7 @@ pub fn load_ty(ctx: &CompilerContext, pointer: LLVMValueRef, ty: TypeKind) -> Va (ctx.llvm_builder.build_load(pointer), ty).into() } -pub fn load_prim(ctx: &CompilerContext, pointer: LLVMValueRef, ty: PrimitiveType) -> ValueTypePair { +pub fn load_prim(ctx: &CompilerContext, pointer: LLVMValueRef, ty: Type) -> ValueTypePair { (ctx.llvm_builder.build_load(pointer), ty).into() } @@ -55,11 +55,11 @@ pub fn alloca_with_name(ctx: &CompilerContext, ty: LLVMTypeRef, name: &str) -> L ctx.llvm_builder.build_alloca_with_name(ty, name) } -pub fn alloca_ty(ctx: &CompilerContext, ty: &PrimitiveType) -> LLVMValueRef { +pub fn alloca_ty(ctx: &CompilerContext, ty: &Type) -> LLVMValueRef { ctx.llvm_builder.build_alloca(ty.llvm_ty_in_ctx(ctx)) } -pub fn alloca_with_name_ty(ctx: &CompilerContext, ty: &PrimitiveType, name: &str) -> LLVMValueRef { +pub fn alloca_with_name_ty(ctx: &CompilerContext, ty: &Type, name: &str) -> LLVMValueRef { ctx.llvm_builder .build_alloca_with_name(ty.llvm_ty_in_ctx(ctx), name) } @@ -80,7 +80,7 @@ pub fn call( pub fn extract_i8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::Int(IntSize::Bits8), + Type::Int(IntSize::Bits8), ) .into() } @@ -88,7 +88,7 @@ pub fn extract_i8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> V pub fn extract_i16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::Int(IntSize::Bits16), + Type::Int(IntSize::Bits16), ) .into() } @@ -96,7 +96,7 @@ pub fn extract_i16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> pub fn extract_i32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::Int(IntSize::Bits32), + Type::Int(IntSize::Bits32), ) .into() } @@ -104,7 +104,7 @@ pub fn extract_i32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> pub fn extract_i64(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::Int(IntSize::Bits64), + Type::Int(IntSize::Bits64), ) .into() } @@ -112,7 +112,7 @@ pub fn extract_i64(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> pub fn extract_u8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::UInt(IntSize::Bits8), + Type::UInt(IntSize::Bits8), ) .into() } @@ -120,7 +120,7 @@ pub fn extract_u8(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> V pub fn extract_u16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::UInt(IntSize::Bits16), + Type::UInt(IntSize::Bits16), ) .into() } @@ -128,7 +128,7 @@ pub fn extract_u16(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> pub fn extract_u32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::UInt(IntSize::Bits32), + Type::UInt(IntSize::Bits32), ) .into() } @@ -136,7 +136,7 @@ pub fn extract_u32(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> pub fn extract_u64(ctx: &CompilerContext, agg_val: LLVMValueRef, index: u32) -> ValueTypePair { ( ctx.llvm_builder.build_extract_value(agg_val, index), - PrimitiveType::UInt(IntSize::Bits64), + Type::UInt(IntSize::Bits64), ) .into() } diff --git a/comp-be/src/codegen/builder/cast.rs b/comp-be/src/codegen/builder/cast.rs index 425ba55..76c7efd 100644 --- a/comp-be/src/codegen/builder/cast.rs +++ b/comp-be/src/codegen/builder/cast.rs @@ -4,9 +4,9 @@ use crate::{ ty::LLVMTyInCtx, }; use llvm_sys_wrapper::{LLVMTypeRef, LLVMValueRef}; -use parser::ast::PrimitiveType; +use parser::ast::Type; -pub fn zext(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn zext(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder.build_zext(*val, ty.llvm_ty_in_ctx(ctx)), ty, @@ -14,7 +14,7 @@ pub fn zext(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn trunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn trunc(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder.build_trunc(*val, ty.llvm_ty_in_ctx(ctx)), ty, @@ -22,7 +22,7 @@ pub fn trunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> V .into() } -pub fn ftrunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftrunc(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_fp_trunc(*val, ty.llvm_ty_in_ctx(ctx)), @@ -31,7 +31,7 @@ pub fn ftrunc(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> .into() } -pub fn itop(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn itop(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_int_to_ptr(*val, ty.llvm_ty_in_ctx(ctx)), @@ -40,7 +40,7 @@ pub fn itop(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn ptoi(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ptoi(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_ptr_to_int(*val, ty.llvm_ty_in_ctx(ctx)), @@ -49,7 +49,7 @@ pub fn ptoi(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn stof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn stof(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_si_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), @@ -58,7 +58,7 @@ pub fn stof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn utof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn utof(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_ui_to_fp(*val, ty.llvm_ty_in_ctx(ctx)), @@ -67,7 +67,7 @@ pub fn utof(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn ftos(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftos(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_fp_to_si(*val, ty.llvm_ty_in_ctx(ctx)), @@ -76,7 +76,7 @@ pub fn ftos(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> Va .into() } -pub fn ftou(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn ftou(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder .build_fp_to_ui(*val, ty.llvm_ty_in_ctx(ctx)), @@ -89,7 +89,7 @@ pub fn bitcast(ctx: &CompilerContext, val: ValueTypePair, ty: &dyn LLVMTyInCtx) ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)) } -pub fn bitcast_ty(ctx: &CompilerContext, val: ValueTypePair, ty: &PrimitiveType) -> ValueTypePair { +pub fn bitcast_ty(ctx: &CompilerContext, val: ValueTypePair, ty: &Type) -> ValueTypePair { ( ctx.llvm_builder.build_bitcast(*val, ty.llvm_ty_in_ctx(ctx)), ty, diff --git a/comp-be/src/codegen/builder/op.rs b/comp-be/src/codegen/builder/op.rs index 84b8480..fa1594c 100644 --- a/comp-be/src/codegen/builder/op.rs +++ b/comp-be/src/codegen/builder/op.rs @@ -1,6 +1,6 @@ use crate::codegen::{unit::CompilerContext, ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn neg(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { (ctx.llvm_builder.build_neg(*val), val.prim()).into() @@ -17,7 +17,7 @@ pub fn not(ctx: &CompilerContext, val: ValueTypePair) -> ValueTypePair { pub fn ieq(ctx: &CompilerContext, lhs: LLVMValueRef, rhs: LLVMValueRef) -> ValueTypePair { ( ctx.llvm_builder.build_icmp_eq(lhs, rhs), - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/builder/value.rs b/comp-be/src/codegen/builder/value.rs index a1170ff..8fa5b52 100644 --- a/comp-be/src/codegen/builder/value.rs +++ b/comp-be/src/codegen/builder/value.rs @@ -1,23 +1,23 @@ use crate::codegen::{unit::CompilerContext, ValueTypePair}; use llvm_sys_wrapper::{LLVMValueRef, Struct}; -use parser::ast::{FloatSize, IntSize, PrimitiveType}; +use parser::ast::{FloatSize, IntSize, Type}; pub fn t(ctx: &CompilerContext) -> ValueTypePair { - (ctx.llvm_context.SInt1(1), PrimitiveType::Bool).into() + (ctx.llvm_context.SInt1(1), Type::Bool).into() } pub fn f(ctx: &CompilerContext) -> ValueTypePair { - (ctx.llvm_context.SInt1(0), PrimitiveType::Bool).into() + (ctx.llvm_context.SInt1(0), Type::Bool).into() } pub fn char(ctx: &CompilerContext, c: char) -> ValueTypePair { - (ctx.llvm_context.SInt8(c as u64), PrimitiveType::Char).into() + (ctx.llvm_context.SInt8(c as u64), Type::Char).into() } pub fn s8(ctx: &CompilerContext, value: i8) -> ValueTypePair { ( ctx.llvm_context.SInt8(value as u64), - PrimitiveType::Int(IntSize::Bits8), + Type::Int(IntSize::Bits8), ) .into() } @@ -25,7 +25,7 @@ pub fn s8(ctx: &CompilerContext, value: i8) -> ValueTypePair { pub fn s16(ctx: &CompilerContext, value: i16) -> ValueTypePair { ( ctx.llvm_context.SInt16(value as u64), - PrimitiveType::Int(IntSize::Bits16), + Type::Int(IntSize::Bits16), ) .into() } @@ -33,7 +33,7 @@ pub fn s16(ctx: &CompilerContext, value: i16) -> ValueTypePair { pub fn s32(ctx: &CompilerContext, value: i32) -> ValueTypePair { ( ctx.llvm_context.SInt32(value as u64), - PrimitiveType::Int(IntSize::Bits32), + Type::Int(IntSize::Bits32), ) .into() } @@ -41,7 +41,7 @@ pub fn s32(ctx: &CompilerContext, value: i32) -> ValueTypePair { pub fn s64(ctx: &CompilerContext, value: i64) -> ValueTypePair { ( ctx.llvm_context.SInt64(value as u64), - PrimitiveType::Int(IntSize::Bits64), + Type::Int(IntSize::Bits64), ) .into() } @@ -49,7 +49,7 @@ pub fn s64(ctx: &CompilerContext, value: i64) -> ValueTypePair { pub fn u8(ctx: &CompilerContext, value: u8) -> ValueTypePair { ( ctx.llvm_context.UInt8(value as u64), - PrimitiveType::UInt(IntSize::Bits8), + Type::UInt(IntSize::Bits8), ) .into() } @@ -57,7 +57,7 @@ pub fn u8(ctx: &CompilerContext, value: u8) -> ValueTypePair { pub fn u16(ctx: &CompilerContext, value: u16) -> ValueTypePair { ( ctx.llvm_context.UInt16(value as u64), - PrimitiveType::UInt(IntSize::Bits16), + Type::UInt(IntSize::Bits16), ) .into() } @@ -65,28 +65,19 @@ pub fn u16(ctx: &CompilerContext, value: u16) -> ValueTypePair { pub fn u32(ctx: &CompilerContext, value: u32) -> ValueTypePair { ( ctx.llvm_context.UInt32(value as u64), - PrimitiveType::UInt(IntSize::Bits32), + Type::UInt(IntSize::Bits32), ) .into() } pub fn u64(ctx: &CompilerContext, value: u64) -> ValueTypePair { - ( - ctx.llvm_context.UInt64(value), - PrimitiveType::UInt(IntSize::Bits64), - ) - .into() + (ctx.llvm_context.UInt64(value), Type::UInt(IntSize::Bits64)).into() } -pub fn slice( - ctx: &CompilerContext, - pointer: LLVMValueRef, - ty: PrimitiveType, - len: u32, -) -> ValueTypePair { +pub fn slice(ctx: &CompilerContext, pointer: LLVMValueRef, ty: Type, len: u32) -> ValueTypePair { ( Struct::new_const_struct(&mut [pointer, *u32(ctx, len)], false), - PrimitiveType::Slice { ty: box ty }, + Type::Slice { ty: box ty }, ) .into() } @@ -99,7 +90,7 @@ pub fn sint(ctx: &CompilerContext, size: IntSize, value: u64) -> ValueTypePair { IntSize::Bits32 => ctx.llvm_context.SInt32(value), IntSize::Bits64 => ctx.llvm_context.SInt64(value), }, - PrimitiveType::Int(size), + Type::Int(size), ) .into() } @@ -112,7 +103,7 @@ pub fn uint(ctx: &CompilerContext, size: IntSize, value: u64) -> ValueTypePair { IntSize::Bits32 => ctx.llvm_context.UInt32(value), IntSize::Bits64 => ctx.llvm_context.UInt64(value), }, - PrimitiveType::UInt(size), + Type::UInt(size), ) .into() } @@ -123,23 +114,19 @@ pub fn floating(ctx: &CompilerContext, size: FloatSize, value: f64) -> ValueType FloatSize::Bits32 => ctx.llvm_context.Float(value), FloatSize::Bits64 => ctx.llvm_context.Double(value), }, - PrimitiveType::Float(size), + Type::Float(size), ) .into() } pub fn str(ctx: &CompilerContext, string: &str) -> ValueTypePair { - ( - ctx.llvm_builder.build_global_string_ptr(string), - PrimitiveType::Str, - ) - .into() + (ctx.llvm_builder.build_global_string_ptr(string), Type::Str).into() } pub fn unit(ctx: &CompilerContext) -> ValueTypePair { ( ctx.llvm_context.Null(ctx.llvm_context.VoidType()), - PrimitiveType::Unit, + Type::Unit, ) .into() } diff --git a/comp-be/src/codegen/call.rs b/comp-be/src/codegen/call.rs index 3c24fcb..413fe0e 100644 --- a/comp-be/src/codegen/call.rs +++ b/comp-be/src/codegen/call.rs @@ -7,7 +7,7 @@ use crate::{ fmt::AatbeFmt, ty::LLVMTyInCtx, }; -use parser::ast::{AtomKind, Expression, PrimitiveType}; +use parser::ast::{AtomKind, Expression, Type}; impl AatbeModule { pub fn codegen_call(&mut self, call_expr: &Expression) -> Option { @@ -31,11 +31,11 @@ impl AatbeModule { .iter() .filter_map(|arg| match arg { Expression::Atom(AtomKind::SymbolLiteral(sym)) => { - call_types.push(PrimitiveType::Symbol(sym.clone())); + call_types.push(Type::Symbol(sym.clone())); None } Expression::Atom(AtomKind::Unit) => { - call_types.push(PrimitiveType::Unit); + call_types.push(Type::Unit); None } _ => { @@ -47,8 +47,8 @@ impl AatbeModule { None } else { expr.map_or(None, |arg| match arg.prim().clone() { - PrimitiveType::VariantType(name) => { - call_types.push(PrimitiveType::VariantType(name.clone())); + Type::VariantType(name) => { + call_types.push(Type::VariantType(name.clone())); let ty = self.typectx_ref().get_parent_for_variant(&name)?; Some(core::load( @@ -56,15 +56,15 @@ impl AatbeModule { cast::bitcast_to(self, *arg, ty::pointer(self, ty)), )) } - PrimitiveType::Array { ty: box ty, len } => { + Type::Array { ty: box ty, len } => { let arr = cast::bitcast_to(self, *arg, ty::slice_ptr(self, &ty)); let slice = value::slice(self, arr, ty.clone(), len); - call_types.push(PrimitiveType::Slice { ty: box ty }); + call_types.push(Type::Slice { ty: box ty }); Some(*slice) } - PrimitiveType::Ref(box PrimitiveType::Array { + Type::Ref(box Type::Array { ty: box ty, len, }) => { @@ -77,8 +77,8 @@ impl AatbeModule { core::store(self, arr, arr_ptr); core::store(self, *value::u32(self, len), len_ptr); - call_types.push(PrimitiveType::Ref( - box PrimitiveType::Slice { ty: box ty }, + call_types.push(Type::Ref( + box Type::Slice { ty: box ty }, )); Some(slice) } @@ -149,8 +149,8 @@ impl AatbeModule { } let arr = module.codegen_expr(&values[0])?; match arr.prim() { - PrimitiveType::Array { len, .. } => Some(value::u32(module, *len)), - PrimitiveType::Slice { .. } => Some(core::extract_u32(module, *arr, 1)), + Type::Array { len, .. } => Some(value::u32(module, *len)), + Type::Slice { .. } => Some(core::extract_u32(module, *arr, 1)), _ => { module.add_error(CompileError::MismatchedArguments { function: String::from("len"), @@ -178,7 +178,7 @@ impl AatbeModule { .llvm_builder_ref() .build_malloc(val_ty.clone().llvm_ty_in_ctx(module)); - if let PrimitiveType::VariantType(_) = val_ty.inner() { + if let Type::VariantType(_) = val_ty.inner() { unimplemented!(); } @@ -187,6 +187,6 @@ impl AatbeModule { core::inbounds_gep(module, ptr, &mut vec![*value::s64(module, 0)]), ); - Some((ptr, PrimitiveType::Box(box val_ty.clone())).into())*/ + Some((ptr, Type::Box(box val_ty.clone())).into())*/ } } diff --git a/comp-be/src/codegen/conditional.rs b/comp-be/src/codegen/conditional.rs index 7ec604c..7b20b0b 100644 --- a/comp-be/src/codegen/conditional.rs +++ b/comp-be/src/codegen/conditional.rs @@ -7,7 +7,7 @@ use crate::{ ty::LLVMTyInCtx, }; -use parser::ast::{Expression, LoopType, PrimitiveType}; +use parser::ast::{Expression, LoopType, Type}; use llvm_sys_wrapper::Phi; @@ -32,9 +32,9 @@ impl AatbeModule { self.start_scope(); let cond = self.codegen_expr(cond_expr)?; - if *cond.prim().inner() != PrimitiveType::Bool { + if *cond.prim().inner() != Type::Bool { self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: cond.prim().fmt(), value: cond_expr.fmt(), }); @@ -69,7 +69,7 @@ impl AatbeModule { if let Some(then_val) = then_val { let ty = then_val.prim().clone(); - if ty != PrimitiveType::Unit { + if ty != Type::Unit { if else_val.is_some() { let phi = Phi::new( self.llvm_builder_ref().as_ref(), @@ -121,9 +121,9 @@ impl AatbeModule { core::pos_at_end(self, cond_bb); let cond = self.codegen_expr(cond_expr)?; - if *cond.prim().inner() != PrimitiveType::Bool { + if *cond.prim().inner() != Type::Bool { self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: cond.prim().fmt(), value: cond_expr.fmt(), }); diff --git a/comp-be/src/codegen/expr/mod.rs b/comp-be/src/codegen/expr/mod.rs index 1ba369a..8c94b08 100644 --- a/comp-be/src/codegen/expr/mod.rs +++ b/comp-be/src/codegen/expr/mod.rs @@ -7,13 +7,13 @@ use crate::{ fmt::AatbeFmt, ty::LLVMTyInCtx, }; -use parser::ast::{AtomKind, Expression, PrimitiveType, AST}; +use parser::ast::{AtomKind, Expression, Type, AST}; pub fn const_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option { match atom { - AtomKind::StringLiteral(string) => Some(value::str(ctx, string.as_ref())), + AtomKind::StringLiteral(string) => Some(value::str(ctx, &string)), AtomKind::CharLiteral(ch) => Some(value::char(ctx, *ch)), - AtomKind::Cast(box AtomKind::Integer(val, _), PrimitiveType::Char) => { + AtomKind::Cast(box AtomKind::Integer(val, _), Type::Char) => { Some(value::char(ctx, *val as u8 as char)) } AtomKind::Parenthesized(box atom) => fold_expression(ctx, atom), @@ -32,7 +32,7 @@ pub fn fold_constant(module: &mut AatbeModule, ast: &AST) -> Option { /*match ast { AST::Global { ty: - PrimitiveType::NamedType { + Type::NamedType { name, ty: Some(box ty), }, @@ -67,7 +67,7 @@ pub fn fold_constant(module: &mut AatbeModule, ast: &AST) -> Option { }), AST::Constant { ty: - PrimitiveType::NamedType { + Type::NamedType { name, ty: Some(box ty), }, diff --git a/comp-be/src/codegen/mangle_v1.rs b/comp-be/src/codegen/mangle_v1.rs index 4843619..fc0fa36 100644 --- a/comp-be/src/codegen/mangle_v1.rs +++ b/comp-be/src/codegen/mangle_v1.rs @@ -1,4 +1,4 @@ -use parser::ast::{AtomKind, Expression, FloatSize, FunctionType, IntSize, PrimitiveType}; +use parser::ast::{AtomKind, Expression, FloatSize, FunctionType, IntSize, Type}; use super::unit::CompilerContext; use crate::prefix; @@ -94,29 +94,29 @@ impl NameMangler for FunctionType { } } -impl NameMangler for PrimitiveType { +impl NameMangler for Type { fn mangle(&self, ctx: &CompilerContext) -> String { match self { - PrimitiveType::TypeRef(ty) => ty.clone(), - PrimitiveType::Function(ty) => ty.mangle(ctx), + Type::TypeRef(ty) => ty.clone(), + Type::Function(ty) => ty.mangle(ctx), // TODO: Handle Unit - PrimitiveType::Unit => String::new(), - PrimitiveType::NamedType { + Type::Unit => String::new(), + Type::NamedType { name: _, ty: Some(ty), } => ty.mangle(ctx), - PrimitiveType::Str => String::from("s"), - PrimitiveType::Int(size) => format!("i{}", size.mangle(ctx)), - PrimitiveType::UInt(size) => format!("u{}", size.mangle(ctx)), - PrimitiveType::Float(size) => format!("f{}", size.mangle(ctx)), - PrimitiveType::Bool => String::from("b"), - PrimitiveType::Char => String::from("c"), - PrimitiveType::Ref(r) => format!("R{}", r.mangle(ctx)), - PrimitiveType::Pointer(p) => format!("P{}", p.mangle(ctx)), - PrimitiveType::Array { ty, len: _ } => format!("A{}", ty.mangle(ctx)), - PrimitiveType::Slice { ty } => format!("S{}", ty.mangle(ctx)), - PrimitiveType::Symbol(name) => format!("N{}", name), - /*PrimitiveType::VariantType(name) => format!( + Type::Str => String::from("s"), + Type::Int(size) => format!("i{}", size.mangle(ctx)), + Type::UInt(size) => format!("u{}", size.mangle(ctx)), + Type::Float(size) => format!("f{}", size.mangle(ctx)), + Type::Bool => String::from("b"), + Type::Char => String::from("c"), + Type::Ref(r) => format!("R{}", r.mangle(ctx)), + Type::Pointer(p) => format!("P{}", p.mangle(ctx)), + Type::Array { ty, len: _ } => format!("A{}", ty.mangle(ctx)), + Type::Slice { ty } => format!("S{}", ty.mangle(ctx)), + Type::Symbol(name) => format!("N{}", name), + /*Type::VariantType(name) => format!( "{}", module .typectx_ref() @@ -124,7 +124,7 @@ impl NameMangler for PrimitiveType { .expect(format!("Cannot find variant {}", name).as_str()) .parent_name ),*/ - PrimitiveType::Variant { parent, .. } => parent.clone(), + Type::Variant { parent, .. } => parent.clone(), _ => panic!("Cannot name mangle {:?}", self), } } diff --git a/comp-be/src/codegen/mod.rs b/comp-be/src/codegen/mod.rs index 152fab2..e9666cc 100644 --- a/comp-be/src/codegen/mod.rs +++ b/comp-be/src/codegen/mod.rs @@ -93,7 +93,7 @@ pub enum CompileError { use crate::ty::TypeKind; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub struct ValueTypePair(LLVMValueRef, TypeKind); @@ -103,14 +103,14 @@ impl From<(LLVMValueRef, TypeKind)> for ValueTypePair { } } -impl From<(LLVMValueRef, PrimitiveType)> for ValueTypePair { - fn from((val, ty): (LLVMValueRef, PrimitiveType)) -> ValueTypePair { +impl From<(LLVMValueRef, Type)> for ValueTypePair { + fn from((val, ty): (LLVMValueRef, Type)) -> ValueTypePair { ValueTypePair(val, TypeKind::Primitive(ty)) } } -impl From<(LLVMValueRef, &PrimitiveType)> for ValueTypePair { - fn from((val, ty): (LLVMValueRef, &PrimitiveType)) -> ValueTypePair { +impl From<(LLVMValueRef, &Type)> for ValueTypePair { + fn from((val, ty): (LLVMValueRef, &Type)) -> ValueTypePair { ValueTypePair(val, TypeKind::Primitive(ty.clone())) } } @@ -122,11 +122,11 @@ impl From for (LLVMValueRef, TypeKind) { } impl ValueTypePair { - pub fn prim(&self) -> &PrimitiveType { + pub fn prim(&self) -> &Type { match self { ValueTypePair( _, - TypeKind::Primitive(PrimitiveType::NamedType { + TypeKind::Primitive(Type::NamedType { name: _, ty: Some(ty), }), @@ -144,13 +144,13 @@ impl ValueTypePair { todo!() /*match &self { ValueTypePair(val, TypeKind::Primitive(prim)) => match prim { - prim @ (PrimitiveType::Str | PrimitiveType::Array { .. }) => { + prim @ (Type::Str | Type::Array { .. }) => { Some((*val, prim).into()) } - PrimitiveType::Slice { .. } => { + Type::Slice { .. } => { Some((module.llvm_builder_ref().build_extract_value(*val, 0), prim).into()) } - PrimitiveType::Pointer(box ty) => Some((*val, ty).into()), + Type::Pointer(box ty) => Some((*val, ty).into()), _ => None, }, _ => None, diff --git a/comp-be/src/codegen/module.rs b/comp-be/src/codegen/module.rs index c079847..529c495 100644 --- a/comp-be/src/codegen/module.rs +++ b/comp-be/src/codegen/module.rs @@ -32,7 +32,7 @@ use super::{ }; use parser::{ ast, - ast::{AtomKind, Expression, FunctionType, PrimitiveType, AST}, + ast::{AtomKind, Expression, FunctionType, Type, AST}, }; pub type InternalFunc = dyn Fn(&mut AatbeModule, &Vec, String) -> Option; @@ -55,7 +55,7 @@ impl AatbeModule { LLVM::initialize(); let llvm_context = Context::new(); - let llvm_module = llvm_context.create_module(name.as_ref()); + let llvm_module = llvm_context.create_module(&name); let mut internal_functions: HashMap> = HashMap::new(); internal_functions.insert(String::from("len"), Rc::new(AatbeModule::internal_len)); @@ -191,7 +191,7 @@ impl AatbeModule { let smallest = variants.iter().map(|vari| vari.smallest()).min().unwrap(); let size = max_size / smallest; - let smallest_ty = PrimitiveType::UInt(smallest.into()); + let smallest_ty = Type::UInt(smallest.into()); let td_struct = self.llvm_context_ref().StructTypeNamed(name.as_ref()); td_struct.set_body( @@ -307,7 +307,7 @@ impl AatbeModule { }); } Some( - (variant, PrimitiveType::VariantType(name.clone())) + (variant, Type::VariantType(name.clone())) .into(), ) } else { @@ -355,7 +355,7 @@ impl AatbeModule { val, module.llvm_builder_ref().build_struct_gep(res, 0), ); - Some((res, PrimitiveType::Newtype(name.clone())).into()) + Some((res, Type::Newtype(name.clone())).into()) }), ); self.typectx.push_type( @@ -416,12 +416,12 @@ impl AatbeModule { .ret_ty() .clone(); - if let PrimitiveType::VariantType(ty) = val.prim() { + if let Type::VariantType(ty) = val.prim() { let parent_ty = self .typectx_ref() .get_parent_for_variant(ty) .expect("ICE: Variant without parent"); - if let PrimitiveType::TypeRef(name) = &func_ret { + if let Type::TypeRef(name) = &func_ret { if &parent_ty.type_name == name { Some(core::ret( self, @@ -493,7 +493,7 @@ impl AatbeModule { Some( ( self.llvm_builder_ref().build_load(rec), - PrimitiveType::TypeRef(record.clone()), + Type::TypeRef(record.clone()), ) .into(), ) @@ -548,12 +548,12 @@ impl AatbeModule { todo!() /*match ast { AST::Constant { - ty: PrimitiveType::NamedType { name, ty: _ }, + ty: Type::NamedType { name, ty: _ }, export, value: _, } | AST::Global { - ty: PrimitiveType::NamedType { name, ty: _ }, + ty: Type::NamedType { name, ty: _ }, export, value: _, } => { @@ -640,11 +640,11 @@ impl AatbeModule { pub fn propagate_generic_body( body: Box, - type_map: HashMap<&String, PrimitiveType>, + type_map: HashMap<&String, Type>, ) -> Box { box match body { box Expression::Atom(atom) => Expression::Atom(match atom { - AtomKind::Cast(box atom, PrimitiveType::TypeRef(ty_ref)) => { + AtomKind::Cast(box atom, Type::TypeRef(ty_ref)) => { AtomKind::Cast(box atom, type_map[&ty_ref].clone()) } AtomKind::Parenthesized(expr) => AtomKind::Parenthesized( @@ -660,8 +660,8 @@ impl AatbeModule { &mut self, template: &String, name: &String, - types: Vec, - ) -> Option> { + types: Vec, + ) -> Option> { self.get_params(name).or_else(|| { self.propagate_types_in_function(template, types.clone()) .and_then(|ty| match self.function_templates.get(template) { @@ -689,7 +689,7 @@ impl AatbeModule { params .iter() .map(|p| match p { - PrimitiveType::NamedType { + Type::NamedType { ty: Some(box ty), .. } => ty.clone(), _ => p.clone(), @@ -732,7 +732,7 @@ impl AatbeModule { /*pub fn propagate_types_in_function( &mut self, name: &String, - types: Vec, + types: Vec, ) -> Option { if types.len() == 0 { return None; @@ -769,11 +769,11 @@ impl AatbeModule { let type_map = type_names.iter().zip(types).collect::>(); let ret_ty = match ret_ty { - box PrimitiveType::TypeRef(ty) => { + box Type::TypeRef(ty) => { if type_map.contains_key(ty) { box type_map[ty].clone() } else { - box PrimitiveType::TypeRef(ty.clone()) + box Type::TypeRef(ty.clone()) } } _ => ret_ty.clone(), @@ -781,26 +781,26 @@ impl AatbeModule { let params = params .iter() .map(|param| match param { - PrimitiveType::TypeRef(ty) => { + Type::TypeRef(ty) => { if type_map.contains_key(ty) { type_map[ty].clone() } else { - PrimitiveType::TypeRef(ty.clone()) + Type::TypeRef(ty.clone()) } } - PrimitiveType::NamedType { + Type::NamedType { name, - ty: Some(box PrimitiveType::TypeRef(ty)), + ty: Some(box Type::TypeRef(ty)), } => { if type_map.contains_key(ty) { - PrimitiveType::NamedType { + Type::NamedType { name: name.clone(), ty: Some(box type_map[ty].clone()), } } else { - PrimitiveType::NamedType { + Type::NamedType { name: name.clone(), - ty: Some(box PrimitiveType::TypeRef(ty.clone())), + ty: Some(box Type::TypeRef(ty.clone())), } } } @@ -840,7 +840,7 @@ impl AatbeModule { } }*/ - pub fn propagate_types_in_record(&mut self, name: &String, types: Vec) { + pub fn propagate_types_in_record(&mut self, name: &String, types: Vec) { todo!() /*let rec = format!( "{}[{}]", @@ -865,10 +865,10 @@ impl AatbeModule { let fields = fields .iter() .map(|field| { - if let PrimitiveType::NamedType { name, ty } = field { - if let Some(box PrimitiveType::TypeRef(ty_name)) = ty { + if let Type::NamedType { name, ty } = field { + if let Some(box Type::TypeRef(ty_name)) = ty { if type_map.contains_key(ty_name) { - PrimitiveType::NamedType { + Type::NamedType { name: name.clone(), ty: Some(box type_map[ty_name].clone()), } diff --git a/comp-be/src/codegen/unit/cg/atom.rs b/comp-be/src/codegen/unit/cg/atom.rs index 48f5051..094d19d 100644 --- a/comp-be/src/codegen/unit/cg/atom.rs +++ b/comp-be/src/codegen/unit/cg/atom.rs @@ -1,4 +1,4 @@ -use parser::ast::{AtomKind, Boolean, PrimitiveType}; +use parser::ast::{AtomKind, Boolean, Type}; use guard::guard; @@ -32,7 +32,7 @@ pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { guard!(let QueryResponse::Slot(slot) = ctx.query(Query::Slot(name)) else { unreachable!(); }); let slot = slot?; match slot.var_ty().clone() { - ty @ PrimitiveType::Newtype(_) | ty @ PrimitiveType::VariantType(_) => { + ty @ Type::Newtype(_) | ty @ Type::VariantType(_) => { let val: ValueTypePair = slot.into(); Some((*val, ty).into()) } diff --git a/comp-be/src/codegen/unit/cg/binary/comp.rs b/comp-be/src/codegen/unit/cg/binary/comp.rs index 4a4e66b..01a4389 100644 --- a/comp-be/src/codegen/unit/cg/binary/comp.rs +++ b/comp-be/src/codegen/unit/cg/binary/comp.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -14,7 +14,7 @@ pub fn cg( "||" => ctx.llvm_builder.build_or(lhs, rhs), _ => panic!("ICE codegen_eq_ne unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/eqne.rs b/comp-be/src/codegen/unit/cg/binary/eqne.rs index 699cd12..51ecc98 100644 --- a/comp-be/src/codegen/unit/cg/binary/eqne.rs +++ b/comp-be/src/codegen/unit/cg/binary/eqne.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -14,7 +14,7 @@ pub fn cg( "!=" => ctx.llvm_builder.build_icmp_ne(lhs, rhs), _ => panic!("ICE codegen_eq_ne unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/float/arith.rs b/comp-be/src/codegen/unit/cg/binary/float/arith.rs index e9bf790..95be5db 100644 --- a/comp-be/src/codegen/unit/cg/binary/float/arith.rs +++ b/comp-be/src/codegen/unit/cg/binary/float/arith.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::{FloatSize, PrimitiveType}; +use parser::ast::{FloatSize, Type}; pub fn cg( lhs: LLVMValueRef, @@ -18,7 +18,7 @@ pub fn cg( "%" => ctx.llvm_builder.build_frem(lhs, rhs), _ => panic!("ICE codegen_float_ops unhandled op {}", op), }, - PrimitiveType::Float(float_size), + Type::Float(float_size), ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/float/cmp.rs b/comp-be/src/codegen/unit/cg/binary/float/cmp.rs index 5d10688..d66f726 100644 --- a/comp-be/src/codegen/unit/cg/binary/float/cmp.rs +++ b/comp-be/src/codegen/unit/cg/binary/float/cmp.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -14,7 +14,7 @@ pub fn cg( "!=" => ctx.llvm_builder.build_fcmp_une(lhs, rhs), _ => panic!("ICE codegen_eq_ne_float unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/float/eqne.rs b/comp-be/src/codegen/unit/cg/binary/float/eqne.rs index 33c4a0c..fdb3eed 100644 --- a/comp-be/src/codegen/unit/cg/binary/float/eqne.rs +++ b/comp-be/src/codegen/unit/cg/binary/float/eqne.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -16,7 +16,7 @@ pub fn cg( ">=" => ctx.llvm_builder.build_fcmp_uge(lhs, rhs), _ => panic!("ICE codegen_compare_float unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/int/arith.rs b/comp-be/src/codegen/unit/cg/binary/int/arith.rs index 413ef73..fcd1aae 100644 --- a/comp-be/src/codegen/unit/cg/binary/int/arith.rs +++ b/comp-be/src/codegen/unit/cg/binary/int/arith.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::{IntSize, PrimitiveType}; +use parser::ast::{IntSize, Type}; pub fn cg( lhs: LLVMValueRef, @@ -18,7 +18,7 @@ pub fn cg( "%" => ctx.llvm_builder.build_srem(lhs, rhs), _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), }, - PrimitiveType::Int(int_size), + Type::Int(int_size), ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/int/cmp.rs b/comp-be/src/codegen/unit/cg/binary/int/cmp.rs index eb34db2..b1d550d 100644 --- a/comp-be/src/codegen/unit/cg/binary/int/cmp.rs +++ b/comp-be/src/codegen/unit/cg/binary/int/cmp.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -16,7 +16,7 @@ pub fn cg( ">=" => ctx.llvm_builder.build_icmp_sge(lhs, rhs), _ => panic!("ICE codegen_compare_signed unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/mod.rs b/comp-be/src/codegen/unit/cg/binary/mod.rs index f303aa0..ceeef7a 100644 --- a/comp-be/src/codegen/unit/cg/binary/mod.rs +++ b/comp-be/src/codegen/unit/cg/binary/mod.rs @@ -5,7 +5,7 @@ mod float; mod int; mod uint; -use parser::ast::{Expression, IntSize, PrimitiveType}; +use parser::ast::{Expression, IntSize, Type}; use guard::guard; @@ -24,7 +24,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { let rhs = expr::cg(rh, ctx).ok_or(CompileError::Handled)?; match (lhs.prim(), rhs.prim()) { - (PrimitiveType::Bool, PrimitiveType::Bool) => { + (Type::Bool, Type::Bool) => { ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); match bool::cg(*lhs, op, *rhs, ctx) { Some(res) => Ok(res), @@ -35,7 +35,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { }), } } - (PrimitiveType::Char, PrimitiveType::Char) => { + (Type::Char, Type::Char) => { ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); match uint::cg(*lhs, op, *rhs, IntSize::Bits8, ctx) { Some(res) => Ok(res), @@ -46,7 +46,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { }), } } - (PrimitiveType::UInt(lsz), PrimitiveType::UInt(rsz)) if lsz == rsz => { + (Type::UInt(lsz), Type::UInt(rsz)) if lsz == rsz => { ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); match uint::cg(*lhs, op, *rhs, lsz.clone(), ctx) { Some(res) => Ok(res), @@ -57,7 +57,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { }), } } - (PrimitiveType::Int(lsz), PrimitiveType::Int(rsz)) if lsz == rsz => { + (Type::Int(lsz), Type::Int(rsz)) if lsz == rsz => { ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); match int::cg(*lhs, op, *rhs, lsz.clone(), ctx) { Some(res) => Ok(res), @@ -68,7 +68,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> GenRes { }), } } - (PrimitiveType::Float(lsz), PrimitiveType::Float(rsz)) if lsz == rsz => { + (Type::Float(lsz), Type::Float(rsz)) if lsz == rsz => { ctx.trace(format!("Binary {} {} {}", lh.fmt(), op, rh.fmt())); match float::cg(*lhs, op, *rhs, lsz.clone(), ctx) { Some(res) => Ok(res), diff --git a/comp-be/src/codegen/unit/cg/binary/uint/arith.rs b/comp-be/src/codegen/unit/cg/binary/uint/arith.rs index a7b9635..1873091 100644 --- a/comp-be/src/codegen/unit/cg/binary/uint/arith.rs +++ b/comp-be/src/codegen/unit/cg/binary/uint/arith.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::{IntSize, PrimitiveType}; +use parser::ast::{IntSize, Type}; pub fn cg( lhs: LLVMValueRef, @@ -18,7 +18,7 @@ pub fn cg( "%" => ctx.llvm_builder.build_urem(lhs, rhs), _ => panic!("ICE codegen_unsigned_ops unhandled op {}", op), }, - PrimitiveType::UInt(ty), + Type::UInt(ty), ) .into() } diff --git a/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs b/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs index 1bf5ff1..c03bd83 100644 --- a/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs +++ b/comp-be/src/codegen/unit/cg/binary/uint/cmp.rs @@ -1,6 +1,6 @@ use crate::{codegen::unit::CompilerContext, codegen::ValueTypePair}; use llvm_sys_wrapper::LLVMValueRef; -use parser::ast::PrimitiveType; +use parser::ast::Type; pub fn cg( lhs: LLVMValueRef, @@ -16,7 +16,7 @@ pub fn cg( ">=" => ctx.llvm_builder.build_icmp_uge(lhs, rhs), _ => panic!("ICE codegen_compare_unsigned unhandled op {}", op), }, - PrimitiveType::Bool, + Type::Bool, ) .into() } diff --git a/comp-be/src/codegen/unit/cg/call.rs b/comp-be/src/codegen/unit/cg/call.rs index cd133cb..33abc3e 100644 --- a/comp-be/src/codegen/unit/cg/call.rs +++ b/comp-be/src/codegen/unit/cg/call.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; -use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; +use parser::ast::{AtomKind, Expression, IdentPath, Type}; use llvm_sys_wrapper::LLVMValueRef; @@ -53,7 +53,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { fn compute_arguments( args: &Vec, ctx: &CompilerContext, -) -> Option<(Vec, Vec)> { +) -> Option<(Vec, Vec)> { let mut call_types = vec![]; let mut error = false; @@ -61,11 +61,11 @@ fn compute_arguments( .iter() .filter_map(|arg| match arg { Expression::Atom(AtomKind::SymbolLiteral(sym)) => { - call_types.push(PrimitiveType::Symbol(sym.clone())); + call_types.push(Type::Symbol(sym.clone())); None } Expression::Atom(AtomKind::Unit) => { - call_types.push(PrimitiveType::Unit); + call_types.push(Type::Unit); None } _ => { @@ -77,9 +77,9 @@ fn compute_arguments( None } else { expr.map_or(None, |arg| match arg.prim().clone() { - ref ty @ PrimitiveType::VariantType(ref _name) => todo!("{:?}", ty), - ref ty @ PrimitiveType::Array { .. } => todo!("{:?}", ty), - ref ty @ PrimitiveType::Ref(box PrimitiveType::Array { .. }) => { + ref ty @ Type::VariantType(ref _name) => todo!("{:?}", ty), + ref ty @ Type::Array { .. } => todo!("{:?}", ty), + ref ty @ Type::Ref(box Type::Array { .. }) => { todo!("{:?}", ty) } ref ty @ _ => { diff --git a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs index 6e6f36a..01739b1 100644 --- a/comp-be/src/codegen/unit/cg/conditional/ifelse.rs +++ b/comp-be/src/codegen/unit/cg/conditional/ifelse.rs @@ -8,7 +8,7 @@ use crate::{ ty::LLVMTyInCtx, }; use llvm_sys_wrapper::{LLVMBasicBlockRef, Phi}; -use parser::ast::{Expression, PrimitiveType}; +use parser::ast::{Expression, Type}; use guard::guard; @@ -39,10 +39,10 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { ctx.dispatch(Message::EnterIfScope(cond_expr.fmt())); let cond = expr::cg(cond_expr, ctx)?; - if *cond.prim().inner() != PrimitiveType::Bool { + if *cond.prim().inner() != Type::Bool { /* self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: cond.prim().fmt(), value: cond_expr.fmt(), }); */ @@ -72,10 +72,10 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { let cond = expr::cg(cond, ctx)?; - if *cond.prim().inner() != PrimitiveType::Bool { + if *cond.prim().inner() != Type::Bool { /* self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: cond.prim().fmt(), value: cond_expr.fmt(), }); */ @@ -154,7 +154,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { blocks.push(else_bb.unwrap()); } - if ty == PrimitiveType::Unit { + if ty == Type::Unit { return None; } diff --git a/comp-be/src/codegen/unit/cg/conditional/loops.rs b/comp-be/src/codegen/unit/cg/conditional/loops.rs index 5001cd7..1b89df0 100644 --- a/comp-be/src/codegen/unit/cg/conditional/loops.rs +++ b/comp-be/src/codegen/unit/cg/conditional/loops.rs @@ -1,4 +1,4 @@ -use parser::ast::{Expression, LoopType, PrimitiveType}; +use parser::ast::{Expression, LoopType, Type}; use guard::guard; @@ -22,10 +22,10 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { base::pos_at_end(ctx, cond_bb); let cond = expr::cg(cond_expr, ctx)?; - if *cond.prim().inner() != PrimitiveType::Bool { + if *cond.prim().inner() != Type::Bool { // TODO: Error /*self.add_error(CompileError::ExpectedType { - expected_ty: PrimitiveType::Bool.fmt(), + expected_ty: Type::Bool.fmt(), found_ty: cond.prim().fmt(), value: cond_expr.fmt(), });*/ diff --git a/comp-be/src/codegen/unit/cg/consts/numeric.rs b/comp-be/src/codegen/unit/cg/consts/numeric.rs index 29e086b..934e00a 100644 --- a/comp-be/src/codegen/unit/cg/consts/numeric.rs +++ b/comp-be/src/codegen/unit/cg/consts/numeric.rs @@ -1,24 +1,24 @@ -use parser::ast::{AtomKind, PrimitiveType}; +use parser::ast::{AtomKind, Type}; use crate::codegen::{builder::value, unit::CompilerContext, ValueTypePair}; pub fn cg(atom: &AtomKind, ctx: &CompilerContext) -> Option { match atom { - AtomKind::Integer(val, PrimitiveType::Int(size)) => { + AtomKind::Integer(val, Type::Int(size)) => { Some(value::sint(ctx, size.clone(), *val)) } - AtomKind::Integer(val, PrimitiveType::UInt(size)) => { + AtomKind::Integer(val, Type::UInt(size)) => { Some(value::uint(ctx, size.clone(), *val)) } - AtomKind::Floating(val, PrimitiveType::Float(size)) => { + AtomKind::Floating(val, Type::Float(size)) => { Some(value::floating(ctx, size.clone(), *val)) } - AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::Int(size))) + AtomKind::Unary(op, box AtomKind::Integer(val, Type::Int(size))) if op == &String::from("-") => { Some(value::sint(ctx, size.clone(), (-(*val as i64)) as u64)) } - AtomKind::Unary(op, box AtomKind::Integer(val, PrimitiveType::UInt(size))) + AtomKind::Unary(op, box AtomKind::Integer(val, Type::UInt(size))) if op == &String::from("-") => { Some(value::uint(ctx, size.clone(), (-(*val as i64)) as u64)) diff --git a/comp-be/src/codegen/unit/cg/decl.rs b/comp-be/src/codegen/unit/cg/decl.rs index ca179d0..36bba7a 100644 --- a/comp-be/src/codegen/unit/cg/decl.rs +++ b/comp-be/src/codegen/unit/cg/decl.rs @@ -1,4 +1,4 @@ -use parser::ast::{Expression, PrimitiveType}; +use parser::ast::{Expression, Type}; use guard::guard; @@ -10,7 +10,7 @@ use crate::codegen::{ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { match expr { Expression::Decl { - ty: PrimitiveType::NamedType { name, ty: Some(ty) }, + ty: Type::NamedType { name, ty: Some(ty) }, value: _, exterior_bind: _, } => { @@ -21,7 +21,7 @@ pub fn cg(expr: &Expression, ctx: &CompilerContext) -> Option { Some((slot.into(), *ty.clone()).into()) } Expression::Decl { - ty: PrimitiveType::NamedType { name, ty: None }, + ty: Type::NamedType { name, ty: None }, value, exterior_bind: _, } => { diff --git a/comp-be/src/codegen/unit/compiler.rs b/comp-be/src/codegen/unit/compiler.rs index cb430ef..c27ffba 100644 --- a/comp-be/src/codegen/unit/compiler.rs +++ b/comp-be/src/codegen/unit/compiler.rs @@ -5,6 +5,7 @@ use parser::ast::{Expression, FunctionType, AST}; use crate::{ codegen::{ + comp_unit::CompilationUnit, unit::{cg, decl, function::find_func, generic}, Scope, ValueTypePair, }, @@ -125,7 +126,7 @@ impl std::fmt::Debug for QueryResponse { .debug_tuple("FunctionGroup") .field(&format_args!( "{}", - match group.as_ref() { + match &group { None => String::from("[]"), Some(gr) => format!("{:?}", gr.borrow().iter().collect::>()), } diff --git a/comp-be/src/codegen/unit/function.rs b/comp-be/src/codegen/unit/function.rs index 4cfa499..c473256 100644 --- a/comp-be/src/codegen/unit/function.rs +++ b/comp-be/src/codegen/unit/function.rs @@ -23,7 +23,7 @@ use std::{ use guard::guard; -use parser::ast::{Expression, FunctionType, PrimitiveType}; +use parser::ast::{Expression, FunctionType, Type}; use llvm_sys_wrapper::{Builder, LLVMBasicBlockRef}; @@ -67,7 +67,7 @@ pub fn find_func<'a>(map: RefCell, ty: &FunctionType) -> Option(map: RefCell, args: &Vec) -> Option> { +pub fn find_function<'a>(map: RefCell, args: &Vec) -> Option> { for func in map.borrow().iter() { if func.accepts(args) { return Some(Rc::downgrade(func)); @@ -92,7 +92,7 @@ impl Func { &self.ty } - pub fn ret_ty(&self) -> &PrimitiveType { + pub fn ret_ty(&self) -> &Type { &self.ty.ret_ty } @@ -101,28 +101,28 @@ impl Func { } pub fn bb(&self, name: String) -> LLVMBasicBlockRef { - self.inner.append_basic_block(name.as_ref()) + self.inner.append_basic_block(&name) } - fn accepts(&self, args: &Vec) -> bool { + fn accepts(&self, args: &Vec) -> bool { let params = &self.ty.params; - if params.len() != args.len() && !(params.contains(&PrimitiveType::Varargs)) { + if params.len() != args.len() && !(params.contains(&Type::Varargs)) { return false; }; for (i, param) in params.iter().enumerate() { - if matches!(param, PrimitiveType::Varargs) { + if matches!(param, Type::Varargs) { continue; } let arg = &args[i]; match param { - PrimitiveType::Varargs => continue, - PrimitiveType::NamedType { + Type::Varargs => continue, + Type::NamedType { ty: Some(box t), .. } if t != arg => return false, - PrimitiveType::NamedType { + Type::NamedType { ty: Some(box t), .. } if t == arg => return true, t if t != arg => return false, @@ -196,7 +196,7 @@ pub fn declare_and_compile_function<'ctx>( } else { if let Some(val) = ret_val { match val.prim() { - PrimitiveType::VariantType(_variant) => todo!(), + Type::VariantType(_variant) => todo!(), _ => base::ret(&ctx, val), }; } else { @@ -262,19 +262,15 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { for (pos, ty) in params .into_iter() .filter(|ty| match ty { - PrimitiveType::Symbol(_) => false, + Type::Symbol(_) => false, _ => true, }) .enumerate() { match ty { - PrimitiveType::NamedType { + Type::NamedType { name, - ty: - Some( - box PrimitiveType::TypeRef(_) - | box PrimitiveType::Array { .. }, - ), + ty: Some(box Type::TypeRef(_) | box Type::Array { .. }), } => { /*let arg = module .get_func((fname.clone(), fty.clone())) @@ -286,9 +282,9 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { name, Slot::Variable { mutable: match ty { - PrimitiveType::Array { .. } - | PrimitiveType::NamedType { - ty: Some(box PrimitiveType::Array { .. }), + Type::Array { .. } + | Type::NamedType { + ty: Some(box Type::Array { .. }), .. } => Mutability::Mutable, _ => Mutability::Immutable, @@ -300,9 +296,9 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { );*/ todo!() } - PrimitiveType::NamedType { + Type::NamedType { name, - ty: Some(box PrimitiveType::Ref(ty) | ty), + ty: Some(box Type::Ref(ty) | ty), } => { guard!(let QueryResponse::Function(Some(func)) = ctx.query(Query::Function((prefix!(ctx).join("::"), fty))) @@ -314,7 +310,7 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { Slot::FunctionArgument(func.get_param(pos as u32), *ty.clone()), )) } - PrimitiveType::Unit | PrimitiveType::Symbol(_) => {} + Type::Unit | Type::Symbol(_) => {} _ => unimplemented!("{:?}", ty), } } @@ -328,7 +324,7 @@ pub fn inject_function_in_scope(ctx: &CompilerContext, function: &Expression) { fn has_return_type(func: &FunctionType) -> bool { match func.ret_ty { - box PrimitiveType::Unit => false, + box Type::Unit => false, _ => true, } } diff --git a/comp-be/src/codegen/unit/generic/gen.rs b/comp-be/src/codegen/unit/generic/gen.rs index 89e0b33..3368a9a 100644 --- a/comp-be/src/codegen/unit/generic/gen.rs +++ b/comp-be/src/codegen/unit/generic/gen.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use parser::ast::{Expression, FunctionType, IdentPath, PrimitiveType, AST}; +use parser::ast::{Expression, FunctionType, IdentPath, Type, AST}; use super::Processor; @@ -88,16 +88,16 @@ fn gen_expr(expr: &Expression, proc: &Processor) -> Option> { } } -fn resolve_type(ty: &PrimitiveType, map: &HashMap<&String, &PrimitiveType>) -> PrimitiveType { +fn resolve_type(ty: &Type, map: &HashMap<&String, &Type>) -> Type { match ty { - PrimitiveType::NamedType { + Type::NamedType { name, ty: Some(box ty), - } => PrimitiveType::NamedType { + } => Type::NamedType { name: name.clone(), ty: Some(box resolve_type(ty, map)), }, - PrimitiveType::TypeRef(name) => map.get(name).cloned().unwrap().clone(), + Type::TypeRef(name) => map.get(name).cloned().unwrap().clone(), _ => ty.clone(), } } diff --git a/comp-be/src/codegen/unit/generic/mod.rs b/comp-be/src/codegen/unit/generic/mod.rs index 50786f6..c1195ba 100644 --- a/comp-be/src/codegen/unit/generic/mod.rs +++ b/comp-be/src/codegen/unit/generic/mod.rs @@ -1,12 +1,12 @@ use std::collections::{HashMap, HashSet}; -use parser::ast::{Expression, IdentPath, PrimitiveType, AST}; +use parser::ast::{Expression, IdentPath, Type, AST}; mod gen; #[derive(Debug)] pub struct Processor { - pub(super) function_calls: HashMap>>, + pub(super) function_calls: HashMap>>, extracted_tree: Option, pub generated_tree: Option, } @@ -63,7 +63,7 @@ impl Processor { self } - fn insert_function_call(&mut self, name: &IdentPath, types: Vec) { + fn insert_function_call(&mut self, name: &IdentPath, types: Vec) { if !self.function_calls.contains_key(name) { self.function_calls.insert(name.clone(), HashSet::new()); } diff --git a/comp-be/src/codegen/unit/mod.rs b/comp-be/src/codegen/unit/mod.rs index 17e8726..f41e7cc 100644 --- a/comp-be/src/codegen/unit/mod.rs +++ b/comp-be/src/codegen/unit/mod.rs @@ -1,7 +1,7 @@ use llvm_sys_wrapper::{Builder, LLVMValueRef}; use crate::codegen::{AatbeModule, ValueTypePair}; -use parser::ast::{BindType, PrimitiveType}; +use parser::ast::{BindType, Type}; pub mod function; pub use function::{ @@ -44,11 +44,11 @@ impl From<&BindType> for Mutability { #[derive(Debug, Clone)] pub enum Slot { - FunctionArgument(LLVMValueRef, PrimitiveType), + FunctionArgument(LLVMValueRef, Type), Variable { mutable: Mutability, name: String, - ty: PrimitiveType, + ty: Type, value: LLVMValueRef, }, } @@ -104,24 +104,24 @@ impl Slot { match self { Slot::Variable { ty: - PrimitiveType::TypeRef(rec) - | PrimitiveType::NamedType { + Type::TypeRef(rec) + | Type::NamedType { name: _, - ty: Some(box PrimitiveType::TypeRef(rec)), + ty: Some(box Type::TypeRef(rec)), }, .. } => Some(rec.clone()), Slot::FunctionArgument( _arg, - PrimitiveType::TypeRef(rec) - | PrimitiveType::Pointer(box PrimitiveType::TypeRef(rec)), + Type::TypeRef(rec) + | Type::Pointer(box Type::TypeRef(rec)), ) => Some(rec.clone()), Slot::Variable { ty: - PrimitiveType::VariantType(name) - | PrimitiveType::NamedType { + Type::VariantType(name) + | Type::NamedType { name: _, - ty: Some(box PrimitiveType::VariantType(name)), + ty: Some(box Type::VariantType(name)), }, .. } => Some(name.clone()), @@ -129,13 +129,13 @@ impl Slot { } } - pub fn get_index(&self, module: &AatbeModule, name: &String) -> Option<(u32, PrimitiveType)> { + pub fn get_index(&self, module: &AatbeModule, name: &String) -> Option<(u32, Type)> { match self { Slot::Variable { ty: - PrimitiveType::NamedType { + Type::NamedType { name: _, - ty: Some(box PrimitiveType::TypeRef(record)), + ty: Some(box Type::TypeRef(record)), }, .. } => match module.typectx_ref().get_record(record) { @@ -149,25 +149,25 @@ impl Slot { pub fn load_var(&self, builder: &Builder) -> LLVMValueRef { match self { Slot::Variable { - ty: PrimitiveType::Array { .. }, + ty: Type::Array { .. }, .. } | Slot::Variable { ty: - PrimitiveType::NamedType { - ty: Some(box PrimitiveType::Array { .. }), + Type::NamedType { + ty: Some(box Type::Array { .. }), .. }, .. } => self.into(), Slot::Variable { - ty: PrimitiveType::Slice { .. }, + ty: Type::Slice { .. }, .. } | Slot::Variable { ty: - PrimitiveType::NamedType { - ty: Some(box PrimitiveType::Slice { .. }), + Type::NamedType { + ty: Some(box Type::Slice { .. }), .. }, .. @@ -179,17 +179,17 @@ impl Slot { Mutability::Constant => self.into(), _ => builder.build_load(self.into()), }, - Slot::FunctionArgument(_, PrimitiveType::Slice { .. }) => { + Slot::FunctionArgument(_, Type::Slice { .. }) => { builder.build_load(self.into()) } Slot::FunctionArgument(_, _) => self.into(), } } - pub fn var_ty(&self) -> &PrimitiveType { + pub fn var_ty(&self) -> &Type { match self { Slot::Variable { ty, .. } => match ty { - PrimitiveType::NamedType { + Type::NamedType { name: _, ty: Some(ty), } => ty, @@ -202,8 +202,8 @@ impl Slot { pub fn get_mutability(&self) -> &Mutability { match self { Slot::Variable { mutable, .. } => mutable, - Slot::FunctionArgument(_, PrimitiveType::Array { .. }) => &Mutability::Mutable, - Slot::FunctionArgument(_, PrimitiveType::Slice { .. }) => &Mutability::Mutable, + Slot::FunctionArgument(_, Type::Array { .. }) => &Mutability::Mutable, + Slot::FunctionArgument(_, Type::Slice { .. }) => &Mutability::Mutable, _ => panic!("ICE get_mutability: Not a variable {:?}", self), } } diff --git a/comp-be/src/codegen/unit/variable.rs b/comp-be/src/codegen/unit/variable.rs index 0a1556f..00c5702 100644 --- a/comp-be/src/codegen/unit/variable.rs +++ b/comp-be/src/codegen/unit/variable.rs @@ -10,7 +10,7 @@ use crate::{ }; use guard::guard; -use parser::ast::{AtomKind, Expression, LValue, PrimitiveType}; +use parser::ast::{AtomKind, Expression, LValue, Type}; macro_rules! rec_name { ($name:expr, $types:expr) => {{ @@ -33,25 +33,25 @@ macro_rules! rec_name { }}; } -pub fn alloc_variable(variable: &Expression, ctx: &CompilerContext) -> Option { +pub fn alloc_variable(variable: &Expression, ctx: &CompilerContext) -> Option { match variable { Expression::Decl { - ty: PrimitiveType::NamedType { name, ty }, + ty: Type::NamedType { name, ty }, value, exterior_bind, } => { let mut vtp = None; let ty = match ty { Some(ty) => match ty { - box PrimitiveType::GenericTypeRef(name, types) => { + box Type::GenericTypeRef(name, types) => { /*let rec = rec_name!(name.clone(), types); if !module.typectx_ref().get_record(&rec).is_ok() { module.propagate_types_in_record(name, types.clone()); } - PrimitiveType::TypeRef(rec.clone())*/ + Type::TypeRef(rec.clone())*/ todo!() } - box PrimitiveType::VariantType(_) => { + box Type::VariantType(_) => { /*if let Some(e) = value { let pair = module.codegen_expr(e)?; @@ -75,13 +75,13 @@ pub fn alloc_variable(variable: &Expression, ctx: &CompilerContext) -> Option Option Option Option Option Option { + Type::Array { ref ty, len } if !constant => { /*if let box Expression::Atom(AtomKind::Array(exprs)) = e { let vals = exprs .iter() @@ -252,7 +252,7 @@ pub fn init_record( if let Some(val) = val { match val.ty() { - TypeKind::Primitive(PrimitiveType::Str) => { + TypeKind::Primitive(Type::Str) => { let gep = module .llvm_builder_ref() .build_inbounds_gep(*val, &mut [*index]); @@ -260,7 +260,7 @@ pub fn init_record( Some( ( module.llvm_builder_ref().build_load(gep), - PrimitiveType::Char, + Type::Char, ) .into(), ) @@ -353,14 +353,14 @@ pub fn store_value( if let Some(val) = val { match val.ty() { - TypeKind::Primitive(PrimitiveType::Str) => Some( + TypeKind::Primitive(Type::Str) => Some( ( base::inbounds_gep(ctx, base::load(ctx, *val), &mut vec![*index]), - PrimitiveType::Char, + Type::Char, ) .into(), ), - TypeKind::Primitive(PrimitiveType::Array { ty: box ty, .. }) => Some( + TypeKind::Primitive(Type::Array { ty: box ty, .. }) => Some( ( base::inbounds_gep( ctx, @@ -371,7 +371,7 @@ pub fn store_value( ) .into(), ), - TypeKind::Primitive(PrimitiveType::Slice { ty: box ty }) => Some( + TypeKind::Primitive(Type::Slice { ty: box ty }) => Some( ( base::inbounds_gep( ctx, diff --git a/comp-be/src/fmt.rs b/comp-be/src/fmt.rs index 3ff8cc2..279bf5c 100644 --- a/comp-be/src/fmt.rs +++ b/comp-be/src/fmt.rs @@ -1,6 +1,6 @@ use parser::ast::{ AtomKind, Boolean, Expression, FloatSize, FunctionType, IdentPath, IntSize, LValue, - PrimitiveType, + Type, }; pub trait AatbeFmt { @@ -17,7 +17,7 @@ impl AatbeFmt for &IdentPath { } } -impl AatbeFmt for PrimitiveType { +impl AatbeFmt for Type { fn fmt(self) -> String { (&self).fmt() } @@ -31,7 +31,7 @@ impl AatbeFmt for FunctionType { impl AatbeFmt for &FunctionType { fn fmt(self) -> String { - let params = if self.params.len() == 1 && self.params[0] == PrimitiveType::Unit { + let params = if self.params.len() == 1 && self.params[0] == Type::Unit { String::from("()") } else { format!( @@ -50,43 +50,43 @@ impl AatbeFmt for &FunctionType { } } -impl AatbeFmt for &PrimitiveType { +impl AatbeFmt for &Type { fn fmt(self) -> String { match self { - PrimitiveType::Str => String::from("str"), - PrimitiveType::Bool => String::from("bool"), - PrimitiveType::Int(bits) => match bits { + Type::Str => String::from("str"), + Type::Bool => String::from("bool"), + Type::Int(bits) => match bits { IntSize::Bits8 => String::from("i8"), IntSize::Bits16 => String::from("i16"), IntSize::Bits32 => String::from("i32"), IntSize::Bits64 => String::from("i64"), }, - PrimitiveType::UInt(bits) => match bits { + Type::UInt(bits) => match bits { IntSize::Bits8 => String::from("u8"), IntSize::Bits16 => String::from("u16"), IntSize::Bits32 => String::from("u32"), IntSize::Bits64 => String::from("u64"), }, - PrimitiveType::Float(bits) => match bits { + Type::Float(bits) => match bits { FloatSize::Bits32 => String::from("f32"), FloatSize::Bits64 => String::from("f64"), }, - PrimitiveType::Varargs => String::from("..."), - PrimitiveType::NamedType { + Type::Varargs => String::from("..."), + Type::NamedType { name: _, ty: Some(ty), } => ty.clone().fmt(), - PrimitiveType::Pointer(ty) => format!("{}*", ty.clone().fmt()), - PrimitiveType::Char => String::from("char"), - PrimitiveType::TypeRef(ty) => ty.clone(), - PrimitiveType::Array { ty, len } => { + Type::Pointer(ty) => format!("{}*", ty.clone().fmt()), + Type::Char => String::from("char"), + Type::TypeRef(ty) => ty.clone(), + Type::Array { ty, len } => { format!("{}[{}]", ty.clone().fmt(), len.to_string()) } - PrimitiveType::Unit => String::from("()"), - PrimitiveType::Ref(ty) => format!("&{}", ty.clone().fmt()), - PrimitiveType::Function(func) => func.fmt(), - PrimitiveType::Slice { ty } => format!("{}[]", ty.clone().fmt()), - PrimitiveType::GenericTypeRef(name, types) => format!( + Type::Unit => String::from("()"), + Type::Ref(ty) => format!("&{}", ty.clone().fmt()), + Type::Function(func) => func.fmt(), + Type::Slice { ty } => format!("{}[]", ty.clone().fmt()), + Type::GenericTypeRef(name, types) => format!( "{}[{}]", name, types @@ -95,8 +95,8 @@ impl AatbeFmt for &PrimitiveType { .collect::>() .join(", ") ), - PrimitiveType::Newtype(name) => name.clone(), - PrimitiveType::VariantType(name) => name.clone(), + Type::Newtype(name) => name.clone(), + Type::VariantType(name) => name.clone(), _ => panic!("ICE fmt {:?}", self), } } diff --git a/comp-be/src/ty/infer.rs b/comp-be/src/ty/infer.rs index 987ab2c..bf0e95c 100644 --- a/comp-be/src/ty/infer.rs +++ b/comp-be/src/ty/infer.rs @@ -1,4 +1,4 @@ -use parser::ast::{AtomKind, Expression, IdentPath, PrimitiveType}; +use parser::ast::{AtomKind, Expression, IdentPath, Type}; use guard::guard; @@ -7,7 +7,7 @@ use crate::{ prefix, }; -pub fn infer_type(ctx: &CompilerContext, expr: &Expression) -> Option<(PrimitiveType, bool)> { +pub fn infer_type(ctx: &CompilerContext, expr: &Expression) -> Option<(Type, bool)> { match expr { Expression::Atom(atom) => infer_atom(ctx, &atom), Expression::Call { @@ -45,31 +45,31 @@ pub fn infer_type(ctx: &CompilerContext, expr: &Expression) -> Option<(Primitive .flatten() } Expression::RecordInit { record, types, .. } if types.len() == 0 => { - Some((PrimitiveType::TypeRef(record.clone()), true)) + Some((Type::TypeRef(record.clone()), true)) } Expression::RecordInit { record, types, .. } => Some(( - PrimitiveType::GenericTypeRef(record.clone(), types.clone()), + Type::GenericTypeRef(record.clone(), types.clone()), true, )), _ => unimplemented!("{:?}", expr), } } -pub fn infer_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option<(PrimitiveType, bool)> { +pub fn infer_atom(ctx: &CompilerContext, atom: &AtomKind) -> Option<(Type, bool)> { match atom { AtomKind::Integer(_, sz) => Some((sz.clone(), true)), - AtomKind::Unit => Some((PrimitiveType::Unit, true)), - AtomKind::StringLiteral(_) => Some((PrimitiveType::Str, true)), - AtomKind::CharLiteral(_) => Some((PrimitiveType::Char, true)), - AtomKind::Bool(_) => Some((PrimitiveType::Bool, true)), - AtomKind::SymbolLiteral(s) => Some((PrimitiveType::Symbol(s.clone()), true)), + AtomKind::Unit => Some((Type::Unit, true)), + AtomKind::StringLiteral(_) => Some((Type::Str, true)), + AtomKind::CharLiteral(_) => Some((Type::Char, true)), + AtomKind::Bool(_) => Some((Type::Bool, true)), + AtomKind::SymbolLiteral(s) => Some((Type::Symbol(s.clone()), true)), AtomKind::Array(vals) => { let fst = vals.first().and_then(|v| infer_type(ctx, v)); if !vals.iter().all(|v| infer_type(ctx, v) == fst) { None } else if let Some((ty, constant)) = fst { Some(( - PrimitiveType::Array { + Type::Array { ty: box ty, len: vals.len() as u32, }, diff --git a/comp-be/src/ty/mod.rs b/comp-be/src/ty/mod.rs index 3ceb09d..b817ead 100644 --- a/comp-be/src/ty/mod.rs +++ b/comp-be/src/ty/mod.rs @@ -3,7 +3,7 @@ use crate::{ fmt::AatbeFmt, ty::variant::{Variant, VariantType}, }; -use parser::ast::{FloatSize, FunctionType, IntSize, PrimitiveType}; +use parser::ast::{FloatSize, FunctionType, IntSize, Type}; use llvm_sys_wrapper::{LLVMFunctionType, LLVMTypeRef, LLVMValueRef}; @@ -21,7 +21,7 @@ pub use record::Record; #[derive(Debug)] pub enum TypeError { NotFound(String), - NotFoundPrim(PrimitiveType), + NotFoundPrim(Type), VariantOOB(String, u32), RecordIndexOOB(String, u32), NamedOnVariant(String, String), @@ -32,13 +32,13 @@ pub type TypeResult = Result; pub enum TypeKind { RecordType(Record), - Primitive(PrimitiveType), + Primitive(Type), Typedef(TypedefKind), } pub enum TypedefKind { Opaque(LLVMTypeRef), - Newtype(LLVMTypeRef, PrimitiveType), + Newtype(LLVMTypeRef, Type), VariantType(VariantType), } @@ -136,17 +136,17 @@ impl TypeContext { } } - pub fn get_aggregate_from_prim(&self, prim: &PrimitiveType) -> Option<&dyn Aggregate> { + pub fn get_aggregate_from_prim(&self, prim: &Type) -> Option<&dyn Aggregate> { match prim { - PrimitiveType::TypeRef(name) => match self.types.get(name) { + Type::TypeRef(name) => match self.types.get(name) { Some(TypeKind::RecordType(record)) => Some(record as &dyn Aggregate), _ => None, }, - PrimitiveType::VariantType(name) => match self.get_variant(name) { + Type::VariantType(name) => match self.get_variant(name) { Some(variant) => Some(variant as &dyn Aggregate), _ => None, }, - PrimitiveType::Variant { variant, .. } => match self.get_variant(variant) { + Type::Variant { variant, .. } => match self.get_variant(variant) { Some(variant) => Some(variant as &dyn Aggregate), _ => None, }, @@ -242,20 +242,20 @@ impl LLVMTyInCtx for FunctionType { .params .iter() .filter_map(|t| match t { - /*PrimitiveType::TypeRef(name) => { + /*Type::TypeRef(name) => { Some(module.typectx_ref().get_type(name)?.llvm_ty_in_ctx(module)) }*/ - PrimitiveType::Symbol(_) => None, - PrimitiveType::Unit => None, - PrimitiveType::Varargs => { + Type::Symbol(_) => None, + Type::Unit => None, + Type::Varargs => { varargs = true; None } - /*PrimitiveType::NamedType { - ty: Some(box PrimitiveType::Slice { ty: box ty }), + /*Type::NamedType { + ty: Some(box Type::Slice { ty: box ty }), .. } - | PrimitiveType::Slice { ty: box ty } + | Type::Slice { ty: box ty } if ext => { Some( @@ -279,12 +279,12 @@ impl LLVMTyInCtx for FunctionType { } } -impl LLVMTyInCtx for PrimitiveType { +impl LLVMTyInCtx for Type { fn llvm_ty_in_ctx(&self, mctx: &CompilerContext) -> LLVMTypeRef { let ctx = mctx.llvm_context; match self { - PrimitiveType::Slice { ty } => ctx + Type::Slice { ty } => ctx .StructType( &mut vec![ ctx.PointerType(ctx.ArrayType(ty.llvm_ty_in_ctx(mctx), 0)), @@ -293,36 +293,36 @@ impl LLVMTyInCtx for PrimitiveType { false, ) .as_ref(), - PrimitiveType::Array { ty, len } => ctx.ArrayType(ty.llvm_ty_in_ctx(mctx), *len), - PrimitiveType::Ref(r) => ctx.PointerType(r.llvm_ty_in_ctx(mctx)), - PrimitiveType::Unit => ctx.VoidType(), - PrimitiveType::Bool => ctx.Int1Type(), - PrimitiveType::Int(IntSize::Bits8) | PrimitiveType::UInt(IntSize::Bits8) => { + Type::Array { ty, len } => ctx.ArrayType(ty.llvm_ty_in_ctx(mctx), *len), + Type::Ref(r) => ctx.PointerType(r.llvm_ty_in_ctx(mctx)), + Type::Unit => ctx.VoidType(), + Type::Bool => ctx.Int1Type(), + Type::Int(IntSize::Bits8) | Type::UInt(IntSize::Bits8) => { ctx.Int8Type() } - PrimitiveType::Int(IntSize::Bits16) | PrimitiveType::UInt(IntSize::Bits16) => { + Type::Int(IntSize::Bits16) | Type::UInt(IntSize::Bits16) => { ctx.Int16Type() } - PrimitiveType::Int(IntSize::Bits32) | PrimitiveType::UInt(IntSize::Bits32) => { + Type::Int(IntSize::Bits32) | Type::UInt(IntSize::Bits32) => { ctx.Int32Type() } - PrimitiveType::Int(IntSize::Bits64) | PrimitiveType::UInt(IntSize::Bits64) => { + Type::Int(IntSize::Bits64) | Type::UInt(IntSize::Bits64) => { ctx.Int64Type() } - PrimitiveType::Float(FloatSize::Bits32) => ctx.FloatType(), - PrimitiveType::Float(FloatSize::Bits64) => ctx.DoubleType(), - PrimitiveType::Str => ctx.CharPointerType(), - PrimitiveType::Char => ctx.Int8Type(), - PrimitiveType::NamedType { + Type::Float(FloatSize::Bits32) => ctx.FloatType(), + Type::Float(FloatSize::Bits64) => ctx.DoubleType(), + Type::Str => ctx.CharPointerType(), + Type::Char => ctx.Int8Type(), + Type::NamedType { name: _, ty: Some(ty), } => ty.llvm_ty_in_ctx(mctx), - /*PrimitiveType::TypeRef(name) => module + /*Type::TypeRef(name) => module .typectx_ref() .llvm_ty_in_ctx(name) .expect(format!("Type {} is not declared", name).as_str()) .llvm_ty_in_ctx(module), - PrimitiveType::GenericTypeRef(name, types) => { + Type::GenericTypeRef(name, types) => { let rec = format!( "{}[{}]", name, @@ -339,17 +339,17 @@ impl LLVMTyInCtx for PrimitiveType { .expect(format!("Type {} is not declared", rec).as_str()) .llvm_ty_in_ctx(module) } - PrimitiveType::Pointer(ty) => match ty { - box PrimitiveType::Char => ctx.CharPointerType(), - tr @ box PrimitiveType::TypeRef(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), - tr @ box PrimitiveType::UInt(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), - tr @ box PrimitiveType::Int(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), - box PrimitiveType::Str => ctx.PointerType(ctx.Int8PointerType()), - box PrimitiveType::Pointer(box ty) => ctx.PointerType(ty.llvm_ty_in_ctx(module)), + Type::Pointer(ty) => match ty { + box Type::Char => ctx.CharPointerType(), + tr @ box Type::TypeRef(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), + tr @ box Type::UInt(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), + tr @ box Type::Int(_) => ctx.PointerType(tr.llvm_ty_in_ctx(module)), + box Type::Str => ctx.PointerType(ctx.Int8PointerType()), + box Type::Pointer(box ty) => ctx.PointerType(ty.llvm_ty_in_ctx(module)), _ => panic!("llvm_ty_in_ctx {:?}", ty), }, - PrimitiveType::Function(ty) => ty.llvm_ty_in_ctx(module), - PrimitiveType::Newtype(name) => module + Type::Function(ty) => ty.llvm_ty_in_ctx(module), + Type::Newtype(name) => module .typectx_ref() .get_type(&name) .map(|ty| match ty { @@ -357,17 +357,17 @@ impl LLVMTyInCtx for PrimitiveType { _ => unreachable!(), }) .expect(format!("Cannot find type for {:?}", self).as_ref()), - PrimitiveType::Variant { variant, .. } => { + Type::Variant { variant, .. } => { module.typectx_ref().get_variant(variant).expect("ICE").ty } - PrimitiveType::VariantType(variant) => { + Type::VariantType(variant) => { module .typectx_ref() .get_parent_for_variant(variant) .expect("ICE") .ty }*/ - PrimitiveType::Box(box val) => ctx.PointerType(val.llvm_ty_in_ctx(mctx)), + Type::Box(box val) => ctx.PointerType(val.llvm_ty_in_ctx(mctx)), _ => panic!("ICE: llvm_ty_in_ctx {:?}", self), } } diff --git a/comp-be/src/ty/record.rs b/comp-be/src/ty/record.rs index 516712b..298ec76 100644 --- a/comp-be/src/ty/record.rs +++ b/comp-be/src/ty/record.rs @@ -2,7 +2,7 @@ use crate::{ codegen::{builder::base, unit::CompilerContext, AatbeModule, ValueTypePair}, ty::{Aggregate, LLVMTyInCtx, TypeError, TypeResult}, }; -use parser::ast::PrimitiveType; +use parser::ast::Type; use llvm_sys_wrapper::{LLVMTypeRef, LLVMValueRef, Struct}; use std::collections::HashMap; @@ -12,15 +12,15 @@ pub struct Record { name: String, inner: Struct, body: HashMap, - types: HashMap, + types: HashMap, } impl Record { - pub fn new(module: &AatbeModule, name: &String, types: &Vec) -> Self { + pub fn new(module: &AatbeModule, name: &String, types: &Vec) -> Self { let mut body = HashMap::new(); let mut types_map = HashMap::new(); types.iter().enumerate().for_each(|(index, ty)| match ty { - PrimitiveType::NamedType { name, ty: Some(ty) } => { + Type::NamedType { name, ty: Some(ty) } => { body.insert(name.clone(), index as u32); types_map.insert(index as u32, *ty.clone()); } @@ -29,13 +29,13 @@ impl Record { Self { name: name.clone(), - inner: Struct::new_with_name(module.llvm_context_ref().as_ref(), name.as_ref()), + inner: Struct::new_with_name(module.llvm_context_ref().as_ref(), &name), body, types: types_map, } } - pub fn set_body(&self, ctx: &CompilerContext, types: &Vec) { + pub fn set_body(&self, ctx: &CompilerContext, types: &Vec) { let mut types = types .iter() .map(|ty| ty.llvm_ty_in_ctx(ctx)) @@ -44,7 +44,7 @@ impl Record { self.inner.set_body(&mut types, false); } - pub fn get_field_index_ty(&self, name: &String) -> Option<(u32, PrimitiveType)> { + pub fn get_field_index_ty(&self, name: &String) -> Option<(u32, Type)> { let idx = self.body.get(name).map(|i| *i); (idx, self.types.get(&idx?).map(|i| i.clone())).transpose() } @@ -98,7 +98,7 @@ pub fn store_named_field( rec: &Record, name: &String, value: ValueTypePair, -) -> Result<(), PrimitiveType> { +) -> Result<(), Type> { let index = rec .get_field_index_ty(name) .expect(format!("Cannot find field {:?} in {:?}\0", name, rec.name).as_str()); diff --git a/comp-be/src/ty/size.rs b/comp-be/src/ty/size.rs index c32d663..69e861e 100644 --- a/comp-be/src/ty/size.rs +++ b/comp-be/src/ty/size.rs @@ -1,26 +1,26 @@ -use parser::ast::{IntSize, PrimitiveType, TypeKind}; +use parser::ast::{IntSize, Type, TypeKind}; pub trait AatbeSizeOf { fn size_of(&self) -> usize; fn smallest(&self) -> usize; } -impl AatbeSizeOf for PrimitiveType { +impl AatbeSizeOf for Type { fn size_of(&self) -> usize { match self { - PrimitiveType::UInt(IntSize::Bits8) => 1, - PrimitiveType::UInt(IntSize::Bits16) => 2, - PrimitiveType::UInt(IntSize::Bits32) => 4, - PrimitiveType::UInt(IntSize::Bits64) => 8, - PrimitiveType::Int(IntSize::Bits8) => 1, - PrimitiveType::Int(IntSize::Bits16) => 2, - PrimitiveType::Int(IntSize::Bits32) => 4, - PrimitiveType::Int(IntSize::Bits64) => 8, - PrimitiveType::Str => 8, // TODO: Platform specific pointer size - PrimitiveType::Pointer(_) => 8, // FIXME: Platform specific pointer size - PrimitiveType::Box(_) => 8, // FIXME: Platform specific pointer size - PrimitiveType::Bool => 1, - PrimitiveType::Char => 1, + Type::UInt(IntSize::Bits8) => 1, + Type::UInt(IntSize::Bits16) => 2, + Type::UInt(IntSize::Bits32) => 4, + Type::UInt(IntSize::Bits64) => 8, + Type::Int(IntSize::Bits8) => 1, + Type::Int(IntSize::Bits16) => 2, + Type::Int(IntSize::Bits32) => 4, + Type::Int(IntSize::Bits64) => 8, + Type::Str => 8, // TODO: Platform specific pointer size + Type::Pointer(_) => 8, // FIXME: Platform specific pointer size + Type::Box(_) => 8, // FIXME: Platform specific pointer size + Type::Bool => 1, + Type::Char => 1, _ => unimplemented!("{:?}", self), } } diff --git a/comp-be/src/ty/variant.rs b/comp-be/src/ty/variant.rs index b008bad..dbb1df4 100644 --- a/comp-be/src/ty/variant.rs +++ b/comp-be/src/ty/variant.rs @@ -4,13 +4,13 @@ use crate::{ }; use llvm_sys_wrapper::{LLVMTypeRef, LLVMValueRef}; -use parser::ast::PrimitiveType; +use parser::ast::Type; use std::{collections::HashMap, fmt}; pub struct VariantType { pub type_name: String, pub variants: HashMap, - pub discriminant_type: PrimitiveType, + pub discriminant_type: Type, pub ty: LLVMTypeRef, } @@ -30,7 +30,7 @@ impl LLVMTyInCtx for VariantType { pub struct Variant { pub parent_name: String, pub name: String, - pub types: Option>, + pub types: Option>, pub ty: LLVMTypeRef, pub discriminant: u32, } diff --git a/libc.aat b/libc.aat new file mode 100644 index 0000000..b20473c --- /dev/null +++ b/libc.aat @@ -0,0 +1 @@ +public extern fn printf str, ... -> i32 \ No newline at end of file diff --git a/main.aat b/main.aat index f35f6f7..14715fd 100644 --- a/main.aat +++ b/main.aat @@ -1,6 +1,4 @@ -module libc { - public extern fn printf str, ... -> i32 -} +use libc module std { public fn println s: str = ::libc::printf "%s\n", s diff --git a/parser/src/ast.rs b/parser/src/ast.rs index d752d56..aae7a4a 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -14,20 +14,20 @@ pub enum AST { File(Vec), Error, Expr(Expression), - Import(String), - Record(String, Option>, Vec), + Import(IdentPath), + Record(String, Option>, Vec), Typedef { name: String, type_names: Option>, variants: Option>, }, Constant { - ty: PrimitiveType, + ty: Type, export: bool, value: Box, }, Global { - ty: PrimitiveType, + ty: Type, export: bool, value: Box, }, @@ -36,8 +36,8 @@ pub enum AST { #[derive(Debug, PartialEq, Clone)] pub enum TypeKind { - Newtype(PrimitiveType), - Variant(String, Option>), + Newtype(Type), + Variant(String, Option>), } #[derive(Debug, PartialEq, Clone)] @@ -47,7 +47,7 @@ pub enum Expression { Block(Vec), Ret(Box), Decl { - ty: PrimitiveType, + ty: Type, value: Option>, exterior_bind: BindType, }, @@ -57,7 +57,7 @@ pub enum Expression { }, Call { name: IdentPath, - types: Vec, + types: Vec, args: Vec, }, Function { @@ -76,7 +76,7 @@ pub enum Expression { }, RecordInit { record: String, - types: Vec, + types: Vec, values: Vec, }, Loop { @@ -110,18 +110,18 @@ pub enum LoopType { #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub struct FunctionType { pub ext: bool, - pub ret_ty: Box, - pub params: Vec, + pub ret_ty: Box, + pub params: Vec, } -impl From for PrimitiveType { +impl From for Type { fn from(func: FunctionType) -> Self { - PrimitiveType::Function(func) + Type::Function(func) } } #[derive(Debug, PartialEq, Eq, Clone, Hash)] -pub enum PrimitiveType { +pub enum Type { Unit, Str, Varargs, @@ -131,52 +131,41 @@ pub enum PrimitiveType { UInt(IntSize), Float(FloatSize), TypeRef(String), - GenericTypeRef(String, Vec), + GenericTypeRef(String, Vec), Newtype(String), VariantType(String), - Variant { - parent: String, - variant: String, - }, + Variant { parent: String, variant: String }, Function(FunctionType), - NamedType { - name: String, - ty: Option>, - }, - Ref(Box), - Pointer(Box), - Array { - ty: Box, - len: u32, - }, - Slice { - ty: Box, - }, + NamedType { name: String, ty: Option> }, + Ref(Box), + Pointer(Box), + Array { ty: Box, len: u32 }, + Slice { ty: Box }, Symbol(String), - Box(Box), + Box(Box), Path(ModPath), } -impl PrimitiveType { - pub fn inner(&self) -> &PrimitiveType { +impl Type { + pub fn inner(&self) -> &Type { match self { - PrimitiveType::NamedType { + Type::NamedType { name: _, ty: Some(box ty), } => ty, - PrimitiveType::Function(..) => panic!("ICE primty inner {:?}", self), + Type::Function(..) => panic!("ICE primty inner {:?}", self), other => other, } } pub fn ext(&self) -> bool { match self { - PrimitiveType::Function(FunctionType { + Type::Function(FunctionType { ext, ret_ty: _, params: _, }) => ext.clone(), - _ => panic!("ICE PrimitiveType ext {:?}", self), + _ => panic!("ICE Type ext {:?}", self), } } } @@ -186,8 +175,8 @@ pub enum AtomKind { Unit, SymbolLiteral(String), Bool(Boolean), - Integer(u64, PrimitiveType), - Floating(f64, PrimitiveType), + Integer(u64, Type), + Floating(f64, Type), StringLiteral(String), CharLiteral(char), Expr(Box), @@ -198,7 +187,7 @@ pub enum AtomKind { Deref(Box), Ref(Box), Index(Box, Box), - Cast(Box, PrimitiveType), + Cast(Box, Type), Array(Vec), Is(Box, String), NamedValue { name: String, val: Box }, diff --git a/parser/src/lexer/mod.rs b/parser/src/lexer/mod.rs index 946830d..ecea1da 100644 --- a/parser/src/lexer/mod.rs +++ b/parser/src/lexer/mod.rs @@ -320,9 +320,9 @@ impl<'c> Lexer<'c> { token!( tokens, - Token::keyword(buf.as_ref()).unwrap_or( - Token::boolean(buf.as_ref()).unwrap_or( - Token::r#type(buf.as_ref()).unwrap_or(TokenKind::Identifier(buf)), + Token::keyword(&buf).unwrap_or( + Token::boolean(&buf).unwrap_or( + Token::r#type(&buf).unwrap_or(TokenKind::Identifier(buf)), ), ), pos @@ -355,9 +355,10 @@ impl<'c> Lexer<'c> { }; } if buf.contains(".") { - TokenKind::FloatLiteral(f64::from_str(&buf).expect( - format!("{} is not a floating point literal", buf).as_ref(), - )) + TokenKind::FloatLiteral( + f64::from_str(&buf) + .expect(&format!("{} is not a floating point literal", buf)), + ) } else { TokenKind::IntLiteral( u64::from_str_radix(&buf, 10).expect("Lexer died @digits -> u64"), @@ -381,9 +382,10 @@ impl<'c> Lexer<'c> { token!( tokens, if buf.contains(".") { - TokenKind::FloatLiteral(f64::from_str(&buf).expect( - format!("{} is not a floating point literal", buf).as_ref(), - )) + TokenKind::FloatLiteral( + f64::from_str(&buf) + .expect(&format!("{} is not a floating point literal", buf)), + ) } else { TokenKind::IntLiteral( u64::from_str_radix(&buf, 10).expect("Lexer died @digits -> u64"), diff --git a/parser/src/lexer/tests.rs b/parser/src/lexer/tests.rs index 0b132ed..230cd1f 100644 --- a/parser/src/lexer/tests.rs +++ b/parser/src/lexer/tests.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod lexer_tests { use crate::lexer::{ - token::{Boolean, Keyword, Type}, + token::{Boolean, Keyword, TokenType}, Lexer, Symbol, TokenKind, }; #[test] @@ -194,7 +194,7 @@ mod lexer_tests { sep!(tokens); assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Until)); sep!(tokens); - assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Type)); + assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::TokenType)); sep!(tokens); assert_eq!(tokens.next().unwrap().kw(), Some(Keyword::Is)); sep!(tokens); @@ -208,26 +208,26 @@ mod lexer_tests { let mut lexer = Lexer::new("str i8 i16 i32 i64 u8 u16 u32 u64 f32 f64"); let mut tokens = lexer.lex().into_iter(); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::Str)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::Str)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::I8)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::I8)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::I16)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::I16)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::I32)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::I32)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::I64)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::I64)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::U8)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::U8)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::U16)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::U16)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::U32)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::U32)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::U64)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::U64)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::F32)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::F32)); sep!(tokens); - assert_eq!(tokens.next().unwrap().ty(), Some(Type::F64)); + assert_eq!(tokens.next().unwrap().ty(), Some(TokenType::F64)); } } diff --git a/parser/src/lexer/token.rs b/parser/src/lexer/token.rs index 82fd1f4..f563987 100644 --- a/parser/src/lexer/token.rs +++ b/parser/src/lexer/token.rs @@ -18,7 +18,7 @@ pub enum TokenKind { BooleanLiteral(Boolean), Identifier(String), Keyword(Keyword), - Type(Type), + TokenType(TokenType), StringLiteral(String), CharLiteral(char), EOL, @@ -113,14 +113,14 @@ pub enum Keyword { Ret, While, Until, - Type, + TokenType, Is, Public, Module, } #[derive(Debug, Eq, PartialEq, Clone, Copy)] -pub enum Type { +pub enum TokenType { Char, Str, I8, @@ -163,7 +163,7 @@ impl Token { } to_tok!(keyword, Keyword, Keyword); to_tok!(boolean, BooleanLiteral, Boolean); - to_tok!(r#type, Type, Type); + to_tok!(r#type, TokenType, TokenType); pub fn op(&self) -> Option { if let TokenKind::Symbol(sym) = self.kind { return match sym { @@ -205,13 +205,13 @@ impl Token { from_tok!(int, IntLiteral, u64); from_tok!(float, FloatLiteral, f64); from_tok!(ident, Identifier, String); - from_tok!(ty, Type, Type); + from_tok!(ty, TokenType, TokenType); from_tok!(st, StringLiteral, String); from_tok!(comm, Comment, String); from_tok!(ch, CharLiteral, char); } -impl FromStr for Type { +impl FromStr for TokenType { type Err = (); fn from_str(s: &str) -> Result { match s { @@ -252,7 +252,7 @@ impl FromStr for Keyword { "ret" => Ok(Self::Ret), "while" => Ok(Self::While), "until" => Ok(Self::Until), - "type" => Ok(Self::Type), + "type" => Ok(Self::TokenType), "is" => Ok(Self::Is), "public" => Ok(Self::Public), "module" => Ok(Self::Module), diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 66d7b97..2486629 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -8,10 +8,10 @@ pub mod parser; mod tests; use crate::{ - ast::{Expression, FloatSize, IntSize, PrimitiveType, TypeKind, AST}, + ast::{Expression, FloatSize, IntSize, Type, TypeKind, AST}, lexer::{ token, - token::{Keyword, Symbol, Type}, + token::{Keyword, Symbol, TokenType}, }, parser::{ParseError, ParseResult, Parser}, }; @@ -20,19 +20,19 @@ use ast::FunctionType; use std::path::PathBuf; impl Parser { - fn parse_type(&mut self) -> ParseResult { + fn parse_type(&mut self) -> ParseResult { let token = self.next(); if let Some(tok) = token { match tok.sym() { - Some(Symbol::Colon) => Some(PrimitiveType::Symbol(ident!(res self)?)), - Some(Symbol::Unit) => Some(PrimitiveType::Unit), - Some(Symbol::GoDot) => Some(PrimitiveType::Varargs), + Some(Symbol::Colon) => Some(Type::Symbol(ident!(res self)?)), + Some(Symbol::Unit) => Some(Type::Unit), + Some(Symbol::GoDot) => Some(Type::Varargs), Some(Symbol::Ampersand) => capture!(res parse_type, self) .ok() - .and_then(|ty| Some(PrimitiveType::Ref(box ty))), + .and_then(|ty| Some(Type::Ref(box ty))), Some(Symbol::At) => capture!(res parse_type, self) .ok() - .and_then(|ty| Some(PrimitiveType::Box(box ty))), + .and_then(|ty| Some(Type::Box(box ty))), Some(Symbol::LBracket) => capture!(res parse_type, self).ok().and_then(|ty| { let len = if sym!(bool Comma, self) { self.peek().and_then(|tok| tok.int()).map(|len| len as u32) @@ -44,14 +44,14 @@ impl Parser { } sym!(RBracket, self); Some(match len { - None => PrimitiveType::Slice { ty: box ty }, - Some(len) => PrimitiveType::Array { ty: box ty, len }, + None => Type::Slice { ty: box ty }, + Some(len) => Type::Array { ty: box ty, len }, }) }), _ => None, } .or_else(|| match tok.kw() { - Some(Keyword::Bool) => Some(PrimitiveType::Bool), + Some(Keyword::Bool) => Some(Type::Bool), _ => None, }) .or_else(|| match tok.ident() { @@ -62,7 +62,7 @@ impl Parser { .parse_type_list() .expect(format!("Expected type list at {}", tyref).as_str()); sym!(RBracket, self); - Some(PrimitiveType::GenericTypeRef(tyref, types)) + Some(Type::GenericTypeRef(tyref, types)) } else { if matches!(self.peek_symbol(Symbol::Doubly), Some(true)) { let mut res = vec![tyref]; @@ -79,27 +79,27 @@ impl Parser { } } } - Some(PrimitiveType::Path(res)) + Some(Type::Path(res)) } else { - Some(PrimitiveType::TypeRef(tyref)) + Some(Type::TypeRef(tyref)) } } } None => None, }) .or_else(|| match tok.ty() { - Some(Type::Str) => Some(PrimitiveType::Str), - Some(Type::Char) => Some(PrimitiveType::Char), - Some(Type::I8) => Some(PrimitiveType::Int(IntSize::Bits8)), - Some(Type::I16) => Some(PrimitiveType::Int(IntSize::Bits16)), - Some(Type::I32) => Some(PrimitiveType::Int(IntSize::Bits32)), - Some(Type::I64) => Some(PrimitiveType::Int(IntSize::Bits64)), - Some(Type::U8) => Some(PrimitiveType::UInt(IntSize::Bits8)), - Some(Type::U16) => Some(PrimitiveType::UInt(IntSize::Bits16)), - Some(Type::U32) => Some(PrimitiveType::UInt(IntSize::Bits32)), - Some(Type::U64) => Some(PrimitiveType::UInt(IntSize::Bits64)), - Some(Type::F32) => Some(PrimitiveType::Float(FloatSize::Bits32)), - Some(Type::F64) => Some(PrimitiveType::Float(FloatSize::Bits64)), + Some(TokenType::Str) => Some(Type::Str), + Some(TokenType::Char) => Some(Type::Char), + Some(TokenType::I8) => Some(Type::Int(IntSize::Bits8)), + Some(TokenType::I16) => Some(Type::Int(IntSize::Bits16)), + Some(TokenType::I32) => Some(Type::Int(IntSize::Bits32)), + Some(TokenType::I64) => Some(Type::Int(IntSize::Bits64)), + Some(TokenType::U8) => Some(Type::UInt(IntSize::Bits8)), + Some(TokenType::U16) => Some(Type::UInt(IntSize::Bits16)), + Some(TokenType::U32) => Some(Type::UInt(IntSize::Bits32)), + Some(TokenType::U64) => Some(Type::UInt(IntSize::Bits64)), + Some(TokenType::F32) => Some(Type::Float(FloatSize::Bits32)), + Some(TokenType::F64) => Some(Type::Float(FloatSize::Bits64)), _ => None, }) } else { @@ -108,14 +108,14 @@ impl Parser { .and_then(|ty| { let mut ty = ty; while sym!(bool Star, self) { - ty = PrimitiveType::Pointer(box ty); + ty = Type::Pointer(box ty); } Some(ty) }) .ok_or(ParseError::ExpectedType) } - fn parse_named_type(&mut self) -> ParseResult { + fn parse_named_type(&mut self) -> ParseResult { let name = ident!(required self); if sym!(bool Comma, self) | sym!(bool Arrow, self) @@ -129,7 +129,7 @@ impl Parser { } else { None }; - Ok(PrimitiveType::NamedType { name, ty }) + Ok(Type::NamedType { name, ty }) } fn parse_attribute(&mut self) -> Option { @@ -139,20 +139,13 @@ impl Parser { fn parse_use(&mut self) -> ParseResult { kw!(Use, self); - if let Some(path) = self.peek_str() { - self.next(); - let pb = PathBuf::from(path); + let path = path!(module self); - Ok(AST::Import( - pb.to_str().expect("ICE parse_use pb.to_str").to_string(), - )) - } else { - Err(ParseError::ExpectedPath) - } + Ok(AST::Import(path)) } - fn parse_type_list(&mut self) -> ParseResult> { + fn parse_type_list(&mut self) -> ParseResult> { let mut params = vec![]; loop { @@ -169,7 +162,7 @@ impl Parser { Ok(params) } - fn parse_free_type_list(&mut self) -> ParseResult> { + fn parse_free_type_list(&mut self) -> ParseResult> { let mut params = vec![]; loop { @@ -208,7 +201,7 @@ impl Parser { }; let fields = if sym!(bool Unit, self) { - vec![PrimitiveType::Unit] + vec![Type::Unit] } else { sym!(required LParen, self); let fields = self @@ -243,7 +236,7 @@ impl Parser { } fn parse_typedef(&mut self) -> ParseResult { - kw!(Type, self); + kw!(TokenType, self); let name = ident!(res self)?; let type_names = if sym!(bool LBracket, self) { @@ -260,7 +253,7 @@ impl Parser { Some(if sym!(bool Pipe, self) { let mut variants = vec![]; - if let PrimitiveType::TypeRef(name) = ty { + if let Type::TypeRef(name) = ty { self.variants.push(name.clone()); variants.push(TypeKind::Variant(name, vars)); } else { @@ -282,7 +275,7 @@ impl Parser { variants } else { if vars.is_some() { - if let PrimitiveType::TypeRef(name) = ty { + if let Type::TypeRef(name) = ty { vec![TypeKind::Variant(name, vars)] } else { return Err(ParseError::ExpectedIdent); @@ -332,7 +325,7 @@ impl Parser { let ret_ty = box if sym!(bool Arrow, self) { capture!(res parse_type, self)? } else { - PrimitiveType::Unit + Type::Unit }; let mut body = None; diff --git a/parser/src/parser/atom.rs b/parser/src/parser/atom.rs index 4d65fb7..22e898f 100644 --- a/parser/src/parser/atom.rs +++ b/parser/src/parser/atom.rs @@ -1,8 +1,8 @@ use crate::{ - ast::{AtomKind, Boolean, FloatSize, IntSize, PrimitiveType}, + ast::{AtomKind, Boolean, FloatSize, IntSize, Type}, parser::{ParseError, ParseResult, Parser}, token, - token::{Keyword, Symbol, Type}, + token::{Keyword, Symbol, TokenType}, }; impl Parser { @@ -21,22 +21,22 @@ impl Parser { } fn parse_number(&mut self) -> Option { - fn parse_number_type(parser: &mut Parser) -> Option { + fn parse_number_type(parser: &mut Parser) -> Option { let prev_ind = parser.index; let tok = parser.next(); if let Some(tok) = tok { match tok.ty() { - Some(Type::I8) => Some(PrimitiveType::Int(IntSize::Bits8)), - Some(Type::I16) => Some(PrimitiveType::Int(IntSize::Bits16)), - Some(Type::I32) => Some(PrimitiveType::Int(IntSize::Bits32)), - Some(Type::I64) => Some(PrimitiveType::Int(IntSize::Bits64)), - Some(Type::U8) => Some(PrimitiveType::UInt(IntSize::Bits8)), - Some(Type::U16) => Some(PrimitiveType::UInt(IntSize::Bits16)), - Some(Type::U32) => Some(PrimitiveType::UInt(IntSize::Bits32)), - Some(Type::U64) => Some(PrimitiveType::UInt(IntSize::Bits64)), - Some(Type::F32) => Some(PrimitiveType::Float(FloatSize::Bits32)), - Some(Type::F64) => Some(PrimitiveType::Float(FloatSize::Bits64)), + Some(TokenType::I8) => Some(Type::Int(IntSize::Bits8)), + Some(TokenType::I16) => Some(Type::Int(IntSize::Bits16)), + Some(TokenType::I32) => Some(Type::Int(IntSize::Bits32)), + Some(TokenType::I64) => Some(Type::Int(IntSize::Bits64)), + Some(TokenType::U8) => Some(Type::UInt(IntSize::Bits8)), + Some(TokenType::U16) => Some(Type::UInt(IntSize::Bits16)), + Some(TokenType::U32) => Some(Type::UInt(IntSize::Bits32)), + Some(TokenType::U64) => Some(Type::UInt(IntSize::Bits64)), + Some(TokenType::F32) => Some(Type::Float(FloatSize::Bits32)), + Some(TokenType::F64) => Some(Type::Float(FloatSize::Bits64)), _ => { parser.index = prev_ind; None @@ -52,11 +52,9 @@ impl Parser { if let Some(tok) = token { if let Some(val) = tok.int() { return Some(match parse_number_type(self) { - Some(ty @ (PrimitiveType::Int(_) | PrimitiveType::UInt(_))) => { - AtomKind::Integer(val, ty) - } - Some(ty @ PrimitiveType::Float(_)) => AtomKind::Floating(val as f64, ty), - None => AtomKind::Integer(val, PrimitiveType::Int(IntSize::Bits32)), + Some(ty @ (Type::Int(_) | Type::UInt(_))) => AtomKind::Integer(val, ty), + Some(ty @ Type::Float(_)) => AtomKind::Floating(val as f64, ty), + None => AtomKind::Integer(val, Type::Int(IntSize::Bits32)), _ => unreachable!(), }); } @@ -66,14 +64,14 @@ impl Parser { } fn parse_float(&mut self) -> Option { - fn parse_float_type(parser: &mut Parser) -> Option { + fn parse_float_type(parser: &mut Parser) -> Option { let prev_ind = parser.index; let tok = parser.next(); if let Some(tok) = tok { match tok.ty() { - Some(Type::F32) => Some(PrimitiveType::Float(FloatSize::Bits32)), - Some(Type::F64) => Some(PrimitiveType::Float(FloatSize::Bits64)), + Some(TokenType::F32) => Some(Type::Float(FloatSize::Bits32)), + Some(TokenType::F64) => Some(Type::Float(FloatSize::Bits64)), _ => { parser.index = prev_ind; None @@ -91,7 +89,7 @@ impl Parser { let ty = parse_float_type(self); return Some(AtomKind::Floating( val, - ty.unwrap_or(PrimitiveType::Float(FloatSize::Bits32)), + ty.unwrap_or(Type::Float(FloatSize::Bits32)), )); } } diff --git a/parser/src/parser/macros.rs b/parser/src/parser/macros.rs index 8912656..7c00e1c 100644 --- a/parser/src/parser/macros.rs +++ b/parser/src/parser/macros.rs @@ -112,6 +112,51 @@ macro_rules! kw { #[macro_export] macro_rules! path { + (module $self:ident) => {{ + use crate::{ast::IdentPath, lexer::token::TokenKind}; + let prev_ind = $self.index; + let token = $self.next(); + if let Some(tok) = token { + match tok.kind { + TokenKind::Identifier(id) => { + let mut res = vec![id.clone()]; + + while matches!($self.peek_symbol(Symbol::Doubly), Some(true)) { + $self.next(); + if $self.peek_ident().is_some() { + $self.next().unwrap().ident().map(|id| res.push(id.clone())); + } + } + + if res.len() == 1 { + IdentPath::Local(id) + } else { + IdentPath::Module(res) + } + } + TokenKind::Symbol(Symbol::Doubly) => { + $self.index = prev_ind; + let mut res = vec![]; + + while matches!($self.peek_symbol(Symbol::Doubly), Some(true)) { + $self.next(); + if $self.peek_ident().is_some() { + $self.next().unwrap().ident().map(|id| res.push(id.clone())); + } + } + + IdentPath::Root(res) + } + _ => { + $self.index = prev_ind; + return Err(ParseError::ExpectedIdent); + } + } + } else { + $self.index = prev_ind; + return Err(ParseError::ExpectedIdent); + } + }}; (required $self:ident) => {{ use crate::{ ast::IdentPath, diff --git a/parser/src/parser/pass/type_resolution.rs b/parser/src/parser/pass/type_resolution.rs index 77502c3..5508b3e 100644 --- a/parser/src/parser/pass/type_resolution.rs +++ b/parser/src/parser/pass/type_resolution.rs @@ -1,4 +1,4 @@ -use crate::ast::{AtomKind, Expression, FunctionType, LValue, PrimitiveType, TypeKind, AST}; +use crate::ast::{AtomKind, Expression, FunctionType, LValue, Type, TypeKind, AST}; pub fn type_resolution(variants: &Vec, ast: &AST) -> AST { match ast { @@ -192,16 +192,16 @@ fn resolve_function_ty(variants: &Vec, ty: &FunctionType) -> FunctionTyp } } -fn resolve_prim(variants: &Vec, ty: &PrimitiveType) -> PrimitiveType { +fn resolve_prim(variants: &Vec, ty: &Type) -> Type { match ty { - PrimitiveType::TypeRef(ty) => { + Type::TypeRef(ty) => { if variants.contains(ty) { - PrimitiveType::VariantType(ty.clone()) + Type::VariantType(ty.clone()) } else { - PrimitiveType::TypeRef(ty.clone()) + Type::TypeRef(ty.clone()) } } - PrimitiveType::NamedType { name, ty } => PrimitiveType::NamedType { + Type::NamedType { name, ty } => Type::NamedType { name: name.clone(), ty: ty.as_ref().map(|ty| box resolve_prim(variants, &ty)), }, diff --git a/parser/src/tests.rs b/parser/src/tests.rs index bd3664b..ba35247 100644 --- a/parser/src/tests.rs +++ b/parser/src/tests.rs @@ -3,7 +3,7 @@ mod parser_tests { use crate::{ ast::{AtomKind, BindType, Boolean, FunctionType, IdentPath, IntSize, LValue, TypeKind}, lexer::{token::Token, Lexer}, - Expression, ParseError, Parser, PrimitiveType, AST, + Expression, ParseError, Parser, Type, AST, }; fn tt(code: &'static str) -> Vec { @@ -58,8 +58,8 @@ mod parser_tests { public: true, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -79,8 +79,8 @@ mod parser_tests { public: false, ty: FunctionType { ext: true, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -106,8 +106,8 @@ fn main () -> () type_names: vec![], ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -133,8 +133,8 @@ fn main () -> () = () body: Some(box Expression::Atom(AtomKind::Unit)), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -160,41 +160,29 @@ fn main () -> () = 1 + 2 * 3 + 4 || 1 == 2 & -foo body: Some(box Expression::Binary( box Expression::Binary( box Expression::Binary( - box Expression::Atom(AtomKind::Integer( - 1, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(1, Type::Int(IntSize::Bits32))), "+".to_string(), box Expression::Binary( box Expression::Atom(AtomKind::Integer( 2, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) )), "*".to_string(), box Expression::Atom(AtomKind::Integer( 3, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) )), ), ), "+".to_string(), - box Expression::Atom(AtomKind::Integer( - 4, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(4, Type::Int(IntSize::Bits32))), ), "||".to_string(), box Expression::Binary( box Expression::Binary( - box Expression::Atom(AtomKind::Integer( - 1, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(1, Type::Int(IntSize::Bits32))), "==".to_string(), - box Expression::Atom(AtomKind::Integer( - 2, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(2, Type::Int(IntSize::Bits32))), ), "&".to_string(), box Expression::Atom(AtomKind::Unary( @@ -205,8 +193,8 @@ fn main () -> () = 1 + 2 * 3 + 4 || 1 == 2 & -foo ),), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -232,8 +220,8 @@ fn main () -> () = {} public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -261,8 +249,8 @@ fn main () -> () = { () } )])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -297,8 +285,8 @@ fn main () -> () = { public: false, ty: FunctionType { ext: true, - ret_ty: box PrimitiveType::Int(IntSize::Bits32), - params: vec![PrimitiveType::Str], + ret_ty: box Type::Int(IntSize::Bits32), + params: vec![Type::Str], } }), AST::Expr(Expression::Function { @@ -309,14 +297,14 @@ fn main () -> () = { public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, + ret_ty: box Type::Unit, params: vec![ - PrimitiveType::NamedType { + Type::NamedType { name: "s".to_string(), - ty: Some(box PrimitiveType::Str) + ty: Some(box Type::Str) }, - PrimitiveType::Int(IntSize::Bits32), - PrimitiveType::Varargs, + Type::Int(IntSize::Bits32), + Type::Varargs, ], } }), @@ -348,12 +336,12 @@ fn main () -> () = { Expression::Binary( box Expression::Atom(AtomKind::Integer( 1, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) )), "+".to_string(), box Expression::Atom(AtomKind::Integer( 2, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) )), ) ] @@ -361,8 +349,8 @@ fn main () -> () = { ])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }), ]) @@ -393,9 +381,9 @@ fn main () -> () = { public: false, body: Some(box Expression::Block(vec![ Expression::Decl { - ty: PrimitiveType::NamedType { + ty: Type::NamedType { name: "var_t".to_string(), - ty: Some(box PrimitiveType::Str), + ty: Some(box Type::Str), }, value: Some(box Expression::Atom(AtomKind::StringLiteral( "Hello World".to_string() @@ -403,15 +391,15 @@ fn main () -> () = { exterior_bind: BindType::Mutable, }, Expression::Decl { - ty: PrimitiveType::NamedType { + ty: Type::NamedType { name: "val_t".to_string(), - ty: Some(box PrimitiveType::Str), + ty: Some(box Type::Str), }, value: None, exterior_bind: BindType::Immutable, }, Expression::Decl { - ty: PrimitiveType::NamedType { + ty: Type::NamedType { name: "infer".to_string(), ty: None, }, @@ -427,8 +415,8 @@ fn main () -> () = { ])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -476,8 +464,8 @@ fn main () = { }])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -512,15 +500,9 @@ fn main () -> () = { body: Some(box Expression::Block(vec![ Expression::If { cond_expr: box Expression::Binary( - box Expression::Atom(AtomKind::Integer( - 1, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(1, Type::Int(IntSize::Bits32))), "==".to_string(), - box Expression::Atom(AtomKind::Integer( - 2, - PrimitiveType::Int(IntSize::Bits32) - )), + box Expression::Atom(AtomKind::Integer(2, Type::Int(IntSize::Bits32))), ), then_expr: box Expression::Block(vec![Expression::Call { name: IdentPath::Local("foo".to_string()), @@ -567,8 +549,8 @@ fn main () -> () = { ])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }),]) ); @@ -579,7 +561,9 @@ fn main () -> () = { let pt = parse_test!( " // test comment -use \"lib.aat\" +use lib +use mod::lib +use ::lib @entry fn main () -> () @@ -590,7 +574,12 @@ fn main () -> () assert_eq!( pt, AST::File(vec![ - AST::Import("lib.aat".to_string()), + AST::Import(IdentPath::Local("lib".to_string())), + AST::Import(IdentPath::Module(vec![ + "mod".to_string(), + "lib".to_string() + ])), + AST::Import(IdentPath::Root(vec!["lib".to_string()])), AST::Expr(Expression::Function { name: "main".to_string(), attributes: attr(vec!["entry"]), @@ -599,8 +588,8 @@ fn main () -> () public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }), ]) @@ -625,25 +614,25 @@ rec Unit() "Record".to_string(), None, vec![ - PrimitiveType::NamedType { + Type::NamedType { name: "msg".to_string(), - ty: Some(box PrimitiveType::Str), + ty: Some(box Type::Str), }, - PrimitiveType::NamedType { + Type::NamedType { name: "time".to_string(), - ty: Some(box PrimitiveType::Int(IntSize::Bits64)), + ty: Some(box Type::Int(IntSize::Bits64)), } ] ), AST::Record( "Generic".to_string(), Some(vec!["T".to_string()]), - vec![PrimitiveType::NamedType { + vec![Type::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef("T".to_string())), + ty: Some(box Type::TypeRef("T".to_string())), },] ), - AST::Record("Unit".to_string(), None, vec![PrimitiveType::Unit],) + AST::Record("Unit".to_string(), None, vec![Type::Unit],) ]) ); } @@ -668,22 +657,22 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } "Record".to_string(), None, vec![ - PrimitiveType::NamedType { + Type::NamedType { name: "msg".to_string(), - ty: Some(box PrimitiveType::Str), + ty: Some(box Type::Str), }, - PrimitiveType::NamedType { + Type::NamedType { name: "time".to_string(), - ty: Some(box PrimitiveType::Int(IntSize::Bits32)), + ty: Some(box Type::Int(IntSize::Bits32)), } ] ), AST::Record( "Generic".to_string(), Some(vec!["T".to_string()]), - vec![PrimitiveType::NamedType { + vec![Type::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef("T".to_string())), + ty: Some(box Type::TypeRef("T".to_string())), },] ), AST::Expr(Expression::Function { @@ -705,7 +694,7 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } name: "time".to_string(), val: box Expression::Atom(AtomKind::Integer( 42, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) )) }, AtomKind::NamedValue { @@ -719,8 +708,8 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } }), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }), AST::Expr(Expression::Function { @@ -730,7 +719,7 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } public: false, body: Some(box Expression::RecordInit { record: "Generic".to_string(), - types: vec![PrimitiveType::Str], + types: vec![Type::Str], values: vec![AtomKind::NamedValue { name: "value".to_string(), val: box Expression::Atom(AtomKind::StringLiteral("Aloha".to_string())) @@ -738,8 +727,8 @@ fn generic_test () = Generic[str] { value: \"Aloha\" } }), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }), ]) @@ -764,9 +753,9 @@ fn generic_test[T] value: T AST::Record( "Generic".to_string(), Some(vec!["T".to_string()]), - vec![PrimitiveType::NamedType { + vec![Type::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef("T".to_string())), + ty: Some(box Type::TypeRef("T".to_string())), },] ), AST::Expr(Expression::Function { @@ -777,10 +766,10 @@ fn generic_test[T] value: T public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::GenericTypeRef( + ret_ty: box Type::Unit, + params: vec![Type::GenericTypeRef( "Generic".to_string(), - vec![PrimitiveType::TypeRef("T".to_string())] + vec![Type::TypeRef("T".to_string())] )], } }), @@ -792,10 +781,10 @@ fn generic_test[T] value: T public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::NamedType { + ret_ty: box Type::Unit, + params: vec![Type::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef("T".to_string())) + ty: Some(box Type::TypeRef("T".to_string())) }], } }), @@ -824,10 +813,10 @@ fn test () = generic_test[i32] 64 public: false, ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::NamedType { + ret_ty: box Type::Unit, + params: vec![Type::NamedType { name: "value".to_string(), - ty: Some(box PrimitiveType::TypeRef("T".to_string())) + ty: Some(box Type::TypeRef("T".to_string())) }], } }), @@ -838,16 +827,16 @@ fn test () = generic_test[i32] 64 public: false, body: Some(box Expression::Call { name: IdentPath::Local("generic_test".to_string()), - types: vec![PrimitiveType::Int(IntSize::Bits32)], + types: vec![Type::Int(IntSize::Bits32)], args: vec![Expression::Atom(AtomKind::Integer( 64, - PrimitiveType::Int(IntSize::Bits32) + Type::Int(IntSize::Bits32) ))] }), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } }), ]) @@ -884,9 +873,7 @@ type Complex = u8 | u16 | Comp @str AST::Typedef { name: "Newtype".to_string(), type_names: None, - variants: Some(vec![TypeKind::Newtype(PrimitiveType::UInt( - IntSize::Bits32 - ))]), + variants: Some(vec![TypeKind::Newtype(Type::UInt(IntSize::Bits32))]), }, AST::Typedef { name: "Option".to_string(), @@ -895,7 +882,7 @@ type Complex = u8 | u16 | Comp @str TypeKind::Variant("None".to_string(), None), TypeKind::Variant( "Some".to_string(), - Some(vec![PrimitiveType::TypeRef("T".to_string())]) + Some(vec![Type::TypeRef("T".to_string())]) ) ]), }, @@ -903,20 +890,17 @@ type Complex = u8 | u16 | Comp @str name: "Number".to_string(), type_names: None, variants: Some(vec![ - TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits8)), - TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits16)), + TypeKind::Newtype(Type::UInt(IntSize::Bits8)), + TypeKind::Newtype(Type::UInt(IntSize::Bits16)), ]), }, AST::Typedef { name: "Complex".to_string(), type_names: None, variants: Some(vec![ - TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits8)), - TypeKind::Newtype(PrimitiveType::UInt(IntSize::Bits16)), - TypeKind::Variant( - "Comp".to_string(), - Some(vec![PrimitiveType::Box(box PrimitiveType::Str)]) - ) + TypeKind::Newtype(Type::UInt(IntSize::Bits8)), + TypeKind::Newtype(Type::UInt(IntSize::Bits16)), + TypeKind::Variant("Comp".to_string(), Some(vec![Type::Box(box Type::Str)])) ]), }, ]) @@ -978,7 +962,7 @@ type Newtype = mod::test::next AST::File(vec![AST::Typedef { name: "Newtype".to_string(), type_names: None, - variants: Some(vec![TypeKind::Newtype(PrimitiveType::Path(vec![ + variants: Some(vec![TypeKind::Newtype(Type::Path(vec![ "mod".to_string(), "test".to_string(), "next".to_string(), @@ -1027,8 +1011,8 @@ fn main () = { ])), ty: FunctionType { ext: false, - ret_ty: box PrimitiveType::Unit, - params: vec![PrimitiveType::Unit], + ret_ty: box Type::Unit, + params: vec![Type::Unit], } })]) );