ran into another type inference problem

This commit is contained in:
2024-02-05 17:30:16 -06:00
parent 7def938781
commit 9d41cf0da7
17 changed files with 267 additions and 24 deletions

View File

@@ -53,10 +53,9 @@ pub enum BackendError {
impl From<BackendError> for Diagnostic<usize> {
fn from(value: BackendError) -> Self {
match value {
BackendError::Cranelift(me) => {
Diagnostic::error().with_message(format!("Internal cranelift error: {}", me))
.with_notes(vec![format!("{:?}", me)])
}
BackendError::Cranelift(me) => Diagnostic::error()
.with_message(format!("Internal cranelift error: {}", me))
.with_notes(vec![format!("{:?}", me)]),
BackendError::BuiltinError(me) => {
Diagnostic::error().with_message(format!("Internal runtime function error: {}", me))
}

View File

@@ -4,7 +4,8 @@ use crate::eval::PrimitiveType;
use crate::ir::{Expression, Primitive, Program, TopLevel, Type, Value, ValueOrRef, Variable};
use crate::syntax::{ConstantType, Location};
use cranelift_codegen::ir::{
self, entities, types, AbiParam, Function, GlobalValue, InstBuilder, MemFlags, Signature, UserFuncName
self, entities, types, AbiParam, Function, GlobalValue, InstBuilder, MemFlags, Signature,
UserFuncName,
};
use cranelift_codegen::isa::CallConv;
use cranelift_codegen::Context;
@@ -29,7 +30,9 @@ impl ReferenceBuilder {
ReferenceBuilder::Global(ty, gv) => {
let cranelift_type = ir::Type::from(*ty);
let ptr_value = builder.ins().symbol_value(types::I64, *gv);
let value = builder.ins().load(cranelift_type, MemFlags::new(), ptr_value, 0);
let value = builder
.ins()
.load(cranelift_type, MemFlags::new(), ptr_value, 0);
(value, *ty)
}
@@ -435,7 +438,8 @@ impl<M: Module> Backend<M> {
// Look up the value for the variable. Because this might be a
// global variable (and that requires special logic), we just turn
// this into an `Expression` and re-use the logic in that implementation.
let fake_ref = ValueOrRef::Ref(ann, Type::Primitive(PrimitiveType::U8), var.clone());
let fake_ref =
ValueOrRef::Ref(ann, Type::Primitive(PrimitiveType::U8), var.clone());
let (val, vtype) = self.compile_value_or_ref(fake_ref, variables, builder)?;
let vtype_repr = builder.ins().iconst(types::I64, vtype as i64);
@@ -473,6 +477,39 @@ impl<M: Module> Backend<M> {
variables.insert(name, ReferenceBuilder::Local(value_type, variable));
Ok((builder.ins().iconst(types::I64, 0), ConstantType::Void))
}
Expression::Call(_, _, function, args) => {
let (arguments, _argument_types): (Vec<_>, Vec<_>) = args
.into_iter()
.map(|x| self.compile_value_or_ref(x, variables, builder))
.collect::<Result<Vec<(_,_)>,BackendError>>()?
.into_iter()
.unzip();
match *function {
ValueOrRef::Value(_, _, _) => {
panic!("Can't use a value for a function")
}
ValueOrRef::Ref(_, result_type, name) => match self.defined_functions.get(&name) {
None => panic!("Couldn't find function {} to call", name),
Some(function) => {
let func_ref = self.module.declare_func_in_func(*function, builder.func);
let call = builder.ins().call(func_ref, &arguments);
let results = builder.inst_results(call);
match results {
[] => Ok((builder.ins().iconst(types::I64, 0), ConstantType::Void)),
[result] => match result_type {
Type::Primitive(ct) => Ok((*result, ct.into())),
Type::Function(_, _) => panic!("return value is a function?"),
}
_ => panic!("don't support multi-value returns yet"),
}
}
}
}
}
}
}