ran into another type inference problem
This commit is contained in:
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user