diff --git a/src/ast/llvm.rs b/src/ast/llvm.rs index cb43ed4..ad9adc9 100644 --- a/src/ast/llvm.rs +++ b/src/ast/llvm.rs @@ -6,7 +6,7 @@ use inkwell::{ context::Context, module::Module, types::{BasicMetadataTypeEnum, BasicTypeEnum, FunctionType}, - values::{BasicValueEnum, FunctionValue, IntValue, PointerValue}, + values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, BasicMetadataValueEnum}, IntPredicate, }; @@ -24,12 +24,15 @@ impl Expr { match &self.kind { ExprKind::Var(name) => { - let (_, value) = match env.lookup(&name) { - Some(v) => v, + let value = match env.lookup(&name) { + Some(v) => match v.kind { + EnvValueKind::Local(l) => l, + EnvValueKind::Func(f) => f.as_global_value().as_pointer_value(), + }, None => bail!("Unbound name {name:?}"), }; - Ok(builder.build_load(*value, "")) + Ok(builder.build_load(value, "")) } ExprKind::Int(n) => { @@ -73,12 +76,38 @@ impl Expr { } } - ExprKind::Call(func, args) => { - let func_llvm = func.into_llvm(); - builder.build_call(func_llvm); + ExprKind::Call(func, args) => match env.lookup(func) { + Some(EnvValue { + ty: func_ty, + kind: EnvValueKind::Func(func_ptr), + }) => { - todo!() - } + fn DUMB_CONVERT(a: BasicValueEnum) -> BasicMetadataValueEnum { + use BasicValueEnum as A; + use BasicMetadataValueEnum as B; + match a { + A::ArrayValue(a) => B::ArrayValue(a), + A::IntValue(a) => B::IntValue(a), + A::FloatValue(a) => B::FloatValue(a), + A::PointerValue(a) => B::PointerValue(a), + A::StructValue(a) => B::StructValue(a), + A::VectorValue(a) => B::VectorValue(a), + } + } + + let args_llvm = args + .iter() + .map(|arg| { + arg.into_llvm(context, builder, env).map(DUMB_CONVERT) + }) + .collect::>>()?; + + builder.build_call(*func_ptr, args_llvm.as_slice(), ""); + + todo!() + } + _ => bail!("No function with name {func:?}"), + }, } } } @@ -111,7 +140,15 @@ fn fn_type_basic<'ctx>( } } -type EnvValue<'a, 'ctx> = (&'a Type, PointerValue<'ctx>); +enum EnvValueKind<'ctx> { + Func(FunctionValue<'ctx>), + Local(PointerValue<'ctx>), +} + +struct EnvValue<'a, 'ctx> { + ty: &'a Type, + kind: EnvValueKind<'ctx>, +} #[derive(Default)] struct Env<'a, 'ctx> { @@ -202,7 +239,13 @@ fn convert_stmts( let expr_val = expr.into_llvm(context, builder, &scope_env)?; builder.build_store(alloca, expr_val); - scope_env.local_type_map.insert(name.clone(), (ty, alloca)); + scope_env.local_type_map.insert( + name.clone(), + EnvValue { + ty, + kind: EnvValueKind::Local(alloca), + }, + ); } Stmt::Return(ret_val) => { diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 6e3d69b..218de19 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -44,7 +44,7 @@ pub enum ExprKind { Int(i64), Var(String), BinOp(Box>, Op, Box>), - Call(Box>, Vec>), + Call(String, Vec>), } #[derive(Copy, Clone, Debug)] diff --git a/src/ast/typed.rs b/src/ast/typed.rs index 9dce3e9..b76b3ab 100644 --- a/src/ast/typed.rs +++ b/src/ast/typed.rs @@ -212,7 +212,6 @@ fn annotate_expr(ctx: &mut AnnotationContext, expr: &Expr<()>) -> Expr { } ExprKind::Call(func, args) => { - let func = annotate_expr(ctx, func); let mut args_annot = Vec::new(); let ret_ty = ctx.type_var(); @@ -221,11 +220,8 @@ fn annotate_expr(ctx: &mut AnnotationContext, expr: &Expr<()>) -> Expr { args_annot.push(arg_annot); } - // ctx.constrain(); - // TODO: - Expr { - kind: ExprKind::Call(Box::new(func), args_annot), + kind: ExprKind::Call(func.to_string(), args_annot), ty: ret_ty, } } @@ -348,12 +344,11 @@ fn substitute_in_expr_kind( ExprKind::BinOp(Box::new(left), op, Box::new(right)) } ExprKind::Call(func, args) => { - let func = substitute_in_expr(assignments, *func)?; let args = args .into_iter() .map(|arg| substitute_in_expr(assignments, arg)) .collect::>()?; - ExprKind::Call(Box::new(func), args) + ExprKind::Call(func, args) } }) } diff --git a/src/parser.lalrpop b/src/parser.lalrpop index 74c1877..3e9e6e0 100644 --- a/src/parser.lalrpop +++ b/src/parser.lalrpop @@ -43,8 +43,8 @@ Expr: Expr<()> = { Ident => Expr { kind: ExprKind::Var(<>), ty: () }, #[precedence(level = "2")] - "(" > ")" => - Expr { kind: ExprKind::Call(Box::new(expr), args), ty: () }, + "(" ?> ")" => + Expr { kind: ExprKind::Call(func, args.unwrap_or_else(|| vec![])), ty: () }, #[precedence(level = "13")] #[assoc(side = "none")]