todo: arbitrary ir
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::eval::PrimitiveType;
|
||||
use crate::ir::{Expression, Primitive, Program, TopLevel, Type, Value, ValueOrRef, Variable};
|
||||
use crate::syntax::{ConstantType, Location};
|
||||
@@ -16,14 +14,6 @@ use internment::ArcIntern;
|
||||
use crate::backend::error::BackendError;
|
||||
use crate::backend::Backend;
|
||||
|
||||
/// When we're compiling, we might need to reference some of the strings built into
|
||||
/// the source code; to do so, we need a `GlobalValue`. Perhaps unexpectedly, given
|
||||
/// the name, `GlobalValue`s are specific to a single function we're compiling, so
|
||||
/// we end up computing this table for every function.
|
||||
///
|
||||
/// This just a handy type alias to avoid a lot of confusion in the functions.
|
||||
type StringTable = HashMap<ArcIntern<String>, GlobalValue>;
|
||||
|
||||
/// When we're talking about variables, it's handy to just have a table that points
|
||||
/// from a variable to "what to do if you want to reference this variable", which is
|
||||
/// agnostic about whether the variable is local, global, an argument, etc. Since
|
||||
@@ -36,7 +26,9 @@ struct ReferenceBuilder {
|
||||
|
||||
impl ReferenceBuilder {
|
||||
fn refer_to(&self, builder: &mut FunctionBuilder) -> (entities::Value, ConstantType) {
|
||||
let value = builder.ins().symbol_value(self.cranelift_type, self.local_data);
|
||||
let value = builder
|
||||
.ins()
|
||||
.symbol_value(self.cranelift_type, self.local_data);
|
||||
(value, self.ir_type)
|
||||
}
|
||||
}
|
||||
@@ -83,7 +75,7 @@ impl<M: Module> Backend<M> {
|
||||
for item in program.items {
|
||||
match item {
|
||||
TopLevel::Function(name, args, rettype, body) => {
|
||||
self.compile_function(name.as_str(), &args, rettype, body);
|
||||
self.compile_function(name.as_str(), &args, rettype, body)?;
|
||||
}
|
||||
|
||||
TopLevel::Statement(stmt) => {
|
||||
@@ -139,18 +131,6 @@ impl<M: Module> Backend<M> {
|
||||
let user_func_name = UserFuncName::user(0, func_id.as_u32());
|
||||
ctx.func = Function::with_name_signature(user_func_name, basic_signature);
|
||||
|
||||
// In the future, we might want to see what runtime functions the function
|
||||
// we were given uses, and then only include those functions that we care
|
||||
// about. Presumably, we'd use some sort of lookup table like we do for
|
||||
// strings. But for now, we only have one runtime function, and we're pretty
|
||||
// sure we're always going to use it, so we just declare it (and reference
|
||||
// it) directly.
|
||||
let print_func_ref = self.runtime_functions.include_runtime_function(
|
||||
"print",
|
||||
&mut self.module,
|
||||
&mut ctx.func,
|
||||
)?;
|
||||
|
||||
// Let's start creating the variable table we'll use when we're dereferencing
|
||||
// them later. This table is a little interesting because instead of pointing
|
||||
// from data to data, we're going to point from data (the variable) to an
|
||||
@@ -166,7 +146,11 @@ impl<M: Module> Backend<M> {
|
||||
let cranelift_type = ir::Type::from(*ty);
|
||||
variables.insert(
|
||||
name.clone(),
|
||||
ReferenceBuilder { cranelift_type, local_data, ir_type: *ty },
|
||||
ReferenceBuilder {
|
||||
cranelift_type,
|
||||
local_data,
|
||||
ir_type: *ty,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -176,9 +160,6 @@ impl<M: Module> Backend<M> {
|
||||
// to win.
|
||||
variables.new_scope();
|
||||
|
||||
// FIXME: Add arguments
|
||||
let mut next_var_num = 1;
|
||||
|
||||
// Finally (!), we generate the function builder that we're going to use to
|
||||
// make this function!
|
||||
let mut fctx = FunctionBuilderContext::new();
|
||||
@@ -326,7 +307,7 @@ impl<M: Module> Backend<M> {
|
||||
for inner in exprs {
|
||||
// we can ignore all of these return values and such, because we
|
||||
// don't actually use them anywhere
|
||||
self.compile_expression(inner, variables, builder);
|
||||
self.compile_expression(inner, variables, builder)?;
|
||||
}
|
||||
// instead, we just return the last one
|
||||
self.compile_expression(last, variables, builder)
|
||||
|
||||
Reference in New Issue
Block a user