From 050c862c1a07048dbccaead310c12a8c9ca5cdd9 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sat, 12 Feb 2022 21:00:12 +0800 Subject: [PATCH] nac3core: function codegen callback changes Added code generator argument to the callback, so it would be easier to write complicated codegen with that callback. To prepare for RPC codegen. --- nac3core/src/codegen/expr.rs | 10 +---- nac3core/src/toplevel/builtins.rs | 64 +++++++++++++++---------------- nac3core/src/toplevel/mod.rs | 25 ++++++------ 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index a1fdba21f..c20be479f 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -371,13 +371,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( .. } => { if let Some(callback) = codegen_callback { - // TODO: Change signature - let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx, generator))); - let params = params - .into_iter() - .map(|(name, val)| (name, val.to_basic_value_enum(ctx, generator))) - .collect(); - return callback.run(ctx, obj, fun, params); + return callback.run(ctx, obj, fun, params, generator); } let old_key = ctx.get_subst_key(obj.as_ref().map(|a| a.0), fun.0, None); let mut keys = fun.0.args.clone(); @@ -431,7 +425,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( }; param_vals = real_params .into_iter() - .map(|p| p.to_basic_value_enum(ctx, generator).into()) + .map(|p| p.to_basic_value_enum(ctx, generator)) .collect_vec(); instance_to_symbol.get(&key).cloned() } diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index 1693dfa80..7a331fd45 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -62,13 +62,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { + |ctx, _, fun, args, generator| { let int32 = ctx.primitives.int32; let int64 = ctx.primitives.int64; let float = ctx.primitives.float; let boolean = ctx.primitives.bool; let arg_ty = fun.0.args[0].ty; - let arg = args[0].1; + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(arg_ty, boolean) { Some( ctx.builder @@ -120,13 +120,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { + |ctx, _, fun, args, generator| { let int32 = ctx.primitives.int32; let int64 = ctx.primitives.int64; let float = ctx.primitives.float; let boolean = ctx.primitives.bool; let arg_ty = fun.0.args[0].ty; - let arg = args[0].1; + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(arg_ty, boolean) || ctx.unifier.unioned(arg_ty, int32) { @@ -170,18 +170,18 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { + |ctx, _, fun, args, generator| { let int32 = ctx.primitives.int32; let int64 = ctx.primitives.int64; let boolean = ctx.primitives.bool; let float = ctx.primitives.float; let arg_ty = fun.0.args[0].ty; - let arg = args[0].1; + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(arg_ty, boolean) || ctx.unifier.unioned(arg_ty, int32) || ctx.unifier.unioned(arg_ty, int64) { - let arg = args[0].1.into_int_value(); + let arg = arg.into_int_value(); let val = ctx .builder .build_signed_int_to_float(arg, ctx.ctx.f64_type(), "sitofp") @@ -207,8 +207,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let round_intrinsic = ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -244,8 +244,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let round_intrinsic = ctx.module.get_function("llvm.round.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -294,7 +294,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { let mut start = None; let mut stop = None; let mut step = None; @@ -302,17 +302,17 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { let zero = int32.const_zero(); for (i, arg) in args.iter().enumerate() { if arg.0 == Some("start".into()) { - start = Some(arg.1); + start = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } else if arg.0 == Some("stop".into()) { - stop = Some(arg.1); + stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } else if arg.0 == Some("step".into()) { - step = Some(arg.1); + step = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } else if i == 0 { - start = Some(arg.1); + start = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } else if i == 1 { - stop = Some(arg.1); + stop = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } else if i == 2 { - step = Some(arg.1); + step = Some(arg.1.clone().to_basic_value_enum(ctx, generator)); } } // TODO: error when step == 0 @@ -356,8 +356,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|_, _, _, args| { - Some(args[0].1) + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + Some(args[0].1.clone().to_basic_value_enum(ctx, generator)) })))), })), Arc::new(RwLock::new(TopLevelDef::Function { @@ -373,13 +373,13 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { + |ctx, _, fun, args, generator| { let int32 = ctx.primitives.int32; let int64 = ctx.primitives.int64; let float = ctx.primitives.float; let boolean = ctx.primitives.bool; let arg_ty = fun.0.args[0].ty; - let arg = args[0].1; + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(arg_ty, boolean) { Some(arg) } else if ctx.unifier.unioned(arg_ty, int32) { @@ -424,8 +424,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let floor_intrinsic = ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -461,8 +461,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let floor_intrinsic = ctx.module.get_function("llvm.floor.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -498,8 +498,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let ceil_intrinsic = ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -535,8 +535,8 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_symbol: Default::default(), instance_to_stmt: Default::default(), resolver: None, - codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args| { - let arg = args[0].1; + codegen_callback: Some(Arc::new(GenCall::new(Box::new(|ctx, _, _, args, generator| { + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); let ceil_intrinsic = ctx.module.get_function("llvm.ceil.f64").unwrap_or_else(|| { let float = ctx.ctx.f64_type(); @@ -581,10 +581,10 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { instance_to_stmt: Default::default(), resolver: None, codegen_callback: Some(Arc::new(GenCall::new(Box::new( - |ctx, _, fun, args| { + |ctx, _, fun, args, generator| { let range_ty = ctx.primitives.range; let arg_ty = fun.0.args[0].ty; - let arg = args[0].1; + let arg = args[0].1.clone().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(arg_ty, range_ty) { let arg = arg.into_pointer_value(); let (start, end, step) = destructure_range(ctx, arg); diff --git a/nac3core/src/toplevel/mod.rs b/nac3core/src/toplevel/mod.rs index 4a8cbb074..b14ba4eaa 100644 --- a/nac3core/src/toplevel/mod.rs +++ b/nac3core/src/toplevel/mod.rs @@ -11,20 +11,21 @@ use super::codegen::CodeGenContext; use super::typecheck::type_inferencer::PrimitiveStore; use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier}; use crate::{ - symbol_resolver::SymbolResolver, + codegen::CodeGenerator, + symbol_resolver::{SymbolResolver, ValueEnum}, typecheck::{type_inferencer::CodeLocation, typedef::CallId}, }; -use itertools::{izip, Itertools}; -use parking_lot::RwLock; -use nac3parser::ast::{self, Stmt, StrRef}; use inkwell::values::BasicValueEnum; +use itertools::{izip, Itertools}; +use nac3parser::ast::{self, Stmt, StrRef}; +use parking_lot::RwLock; #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)] pub struct DefinitionId(pub usize); +pub mod builtins; pub mod composer; pub mod helper; -pub mod builtins; pub mod type_annotation; use composer::*; use type_annotation::*; @@ -34,9 +35,10 @@ mod test; type GenCallCallback = Box< dyn for<'ctx, 'a> Fn( &mut CodeGenContext<'ctx, 'a>, - Option<(Type, BasicValueEnum)>, + Option<(Type, ValueEnum<'ctx>)>, (&FunSignature, DefinitionId), - Vec<(Option, BasicValueEnum<'ctx>)>, + Vec<(Option, ValueEnum<'ctx>)>, + &mut dyn CodeGenerator, ) -> Option> + Send + Sync, @@ -54,11 +56,12 @@ impl GenCall { pub fn run<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, - obj: Option<(Type, BasicValueEnum<'ctx>)>, + obj: Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), - args: Vec<(Option, BasicValueEnum<'ctx>)>, + args: Vec<(Option, ValueEnum<'ctx>)>, + generator: &mut dyn CodeGenerator, ) -> Option> { - (self.fp)(ctx, obj, fun, args) + (self.fp)(ctx, obj, fun, args, generator) } } @@ -120,7 +123,7 @@ pub enum TopLevelDef { // symbol resolver of the module defined the class resolver: Option>, // custom codegen callback - codegen_callback: Option> + codegen_callback: Option>, }, }