Change func names to string instead of expr

This commit is contained in:
Michael Zhang 2022-04-19 18:23:13 -05:00
parent 1e954399c6
commit 15d1d627fd
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 59 additions and 21 deletions

View file

@ -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<Type> {
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<Type> {
}
}
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),
}) => {
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::<Result<Vec<_>>>()?;
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) => {

View file

@ -44,7 +44,7 @@ pub enum ExprKind<T> {
Int(i64),
Var(String),
BinOp(Box<Expr<T>>, Op, Box<Expr<T>>),
Call(Box<Expr<T>>, Vec<Expr<T>>),
Call(String, Vec<Expr<T>>),
}
#[derive(Copy, Clone, Debug)]

View file

@ -212,7 +212,6 @@ fn annotate_expr(ctx: &mut AnnotationContext, expr: &Expr<()>) -> Expr<Type_> {
}
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<Type_> {
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::<Result<_>>()?;
ExprKind::Call(Box::new(func), args)
ExprKind::Call(func, args)
}
})
}

View file

@ -43,8 +43,8 @@ Expr: Expr<()> = {
Ident => Expr { kind: ExprKind::Var(<>), ty: () },
#[precedence(level = "2")]
<expr:Expr> "(" <args:Punct<",", Expr>> ")" =>
Expr { kind: ExprKind::Call(Box::new(expr), args), ty: () },
<func:Ident> "(" <args:Punct<",", Expr>?> ")" =>
Expr { kind: ExprKind::Call(func, args.unwrap_or_else(|| vec![])), ty: () },
#[precedence(level = "13")]
#[assoc(side = "none")]