forked from M-Labs/nac3
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.
This commit is contained in:
parent
ffe89eec86
commit
050c862c1a
@ -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()
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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<StrRef>, BasicValueEnum<'ctx>)>,
|
||||
Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||
&mut dyn CodeGenerator,
|
||||
) -> Option<BasicValueEnum<'ctx>>
|
||||
+ 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<StrRef>, BasicValueEnum<'ctx>)>,
|
||||
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
|
||||
generator: &mut dyn CodeGenerator,
|
||||
) -> Option<BasicValueEnum<'ctx>> {
|
||||
(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<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||
// custom codegen callback
|
||||
codegen_callback: Option<Arc<GenCall>>
|
||||
codegen_callback: Option<Arc<GenCall>>,
|
||||
},
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user