something worked
This commit is contained in:
@@ -25,6 +25,7 @@ lalrpop-util = "^0.19.7"
|
|||||||
lazy_static = "^1.4.0"
|
lazy_static = "^1.4.0"
|
||||||
logos = "^0.12.0"
|
logos = "^0.12.0"
|
||||||
pretty = { version = "^0.11.2", features = ["termcolor"] }
|
pretty = { version = "^0.11.2", features = ["termcolor"] }
|
||||||
|
target-lexicon = "^0.12.5"
|
||||||
thiserror = "^1.0.30"
|
thiserror = "^1.0.30"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
|
|||||||
35
src/bin.rs
35
src/bin.rs
@@ -3,15 +3,17 @@ use codespan_reporting::diagnostic::Diagnostic;
|
|||||||
use codespan_reporting::files::SimpleFiles;
|
use codespan_reporting::files::SimpleFiles;
|
||||||
use codespan_reporting::term;
|
use codespan_reporting::term;
|
||||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
use cranelift_codegen::ir::{AbiParam, types, Signature};
|
use cranelift_codegen::ir::{types, AbiParam, Signature};
|
||||||
use cranelift_codegen::isa::CallConv;
|
use cranelift_codegen::isa::CallConv;
|
||||||
use cranelift_codegen::{isa, settings, CodegenError};
|
use cranelift_codegen::{isa, settings, CodegenError};
|
||||||
use cranelift_module::{default_libcall_names, ModuleError, Linkage, Module};
|
use cranelift_module::{default_libcall_names, Linkage, Module, ModuleError};
|
||||||
use cranelift_object::{ObjectBuilder, ObjectModule, object};
|
use cranelift_object::{object, ObjectBuilder, ObjectModule};
|
||||||
use ngr::asts::lil;
|
use ngr::asts::lil;
|
||||||
use ngr::passes::run_front_end;
|
use ngr::passes::{run_front_end, BackendError};
|
||||||
|
use ngr::runtime::RuntimeFunctions;
|
||||||
use pretty::Arena;
|
use pretty::Arena;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use target_lexicon::Triple;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@@ -41,6 +43,9 @@ enum MainError {
|
|||||||
|
|
||||||
#[error("Object write error: {0}")]
|
#[error("Object write error: {0}")]
|
||||||
Object(#[from] object::write::Error),
|
Object(#[from] object::write::Error),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
Backend(#[from] BackendError),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), MainError> {
|
fn main() -> Result<(), MainError> {
|
||||||
@@ -75,18 +80,12 @@ fn main() -> Result<(), MainError> {
|
|||||||
//let arena = Arena::new();
|
//let arena = Arena::new();
|
||||||
let lil_tree = lil::Program::convert(hil_tree, variable_map.clone());
|
let lil_tree = lil::Program::convert(hil_tree, variable_map.clone());
|
||||||
|
|
||||||
let isa = isa::lookup_by_name("aarch64-apple-darwin")?.finish(settings::Flags::new(settings::builder()))?;
|
let isa = isa::lookup(Triple::host())?.finish(settings::Flags::new(settings::builder()))?;
|
||||||
let object_builder = ObjectBuilder::new(isa, "example", default_libcall_names())?;
|
let object_builder = ObjectBuilder::new(isa, "example", default_libcall_names())?;
|
||||||
let mut object_module = ObjectModule::new(object_builder);
|
let mut object_module = ObjectModule::new(object_builder);
|
||||||
|
let rtfuns = RuntimeFunctions::new(&mut object_module)?;
|
||||||
|
|
||||||
let print_signature = Signature {
|
let _compiled = lil_tree.into_cranelift(&mut object_module, &rtfuns)?;
|
||||||
params: vec![AbiParam::new(types::I64)],
|
|
||||||
returns: vec![],
|
|
||||||
call_conv: CallConv::SystemV,
|
|
||||||
};
|
|
||||||
let print_func_id = object_module.declare_function("print", Linkage::Import, &print_signature)?;
|
|
||||||
|
|
||||||
let _compiled = lil_tree.into_cranelift(&mut object_module, print_func_id)?;
|
|
||||||
|
|
||||||
// something?
|
// something?
|
||||||
|
|
||||||
@@ -94,11 +93,11 @@ fn main() -> Result<(), MainError> {
|
|||||||
|
|
||||||
std::fs::write("output.o", bytes)?;
|
std::fs::write("output.o", bytes)?;
|
||||||
|
|
||||||
// lil_tree
|
// lil_tree
|
||||||
// .pretty(&variable_map, &arena)
|
// .pretty(&variable_map, &arena)
|
||||||
// .into_doc()
|
// .into_doc()
|
||||||
// .render_colored(72, StandardStream::stdout(ColorChoice::Auto))
|
// .render_colored(72, StandardStream::stdout(ColorChoice::Auto))
|
||||||
// .unwrap()
|
// .unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ impl From<Error> for Diagnostic<usize> {
|
|||||||
Label::primary(*file_id, *offset..*offset).with_message("this is related")
|
Label::primary(*file_id, *offset..*offset).with_message("this is related")
|
||||||
])
|
])
|
||||||
.with_message(format!("Internal error: {}", string)),
|
.with_message(format!("Internal error: {}", string)),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ use crate::warnings::Warning;
|
|||||||
use codespan_reporting::files::SimpleFiles;
|
use codespan_reporting::files::SimpleFiles;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
pub use crate::passes::into_crane::BackendError;
|
||||||
|
|
||||||
mod hil_to_lil;
|
mod hil_to_lil;
|
||||||
mod syntax_to_hil;
|
|
||||||
mod into_crane;
|
mod into_crane;
|
||||||
|
mod syntax_to_hil;
|
||||||
|
|
||||||
pub struct PassResult<T> {
|
pub struct PassResult<T> {
|
||||||
pub result: T,
|
pub result: T,
|
||||||
|
|||||||
@@ -1,13 +1,31 @@
|
|||||||
use crate::asts::lil::{Program, Statement, Primitive, SimpleExpression, Value};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::asts::lil::{Primitive, Program, SimpleExpression, Statement, Value};
|
||||||
|
use crate::runtime::{RuntimeFunctionError, RuntimeFunctions};
|
||||||
use cranelift_codegen::entity::EntityRef;
|
use cranelift_codegen::entity::EntityRef;
|
||||||
use cranelift_codegen::ir::{Function, UserFuncName, Signature, types, InstBuilder, entities};
|
use cranelift_codegen::ir::{entities, types, Function, InstBuilder, Signature, UserFuncName};
|
||||||
use cranelift_codegen::isa::CallConv;
|
use cranelift_codegen::isa::CallConv;
|
||||||
use cranelift_codegen::{Context};
|
use cranelift_codegen::Context;
|
||||||
use cranelift_frontend::{FunctionBuilderContext, FunctionBuilder, Variable};
|
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
|
||||||
use cranelift_module::{FuncId, Module, Linkage, ModuleError, ModuleCompiledFunction};
|
use cranelift_module::{FuncId, Linkage, Module, ModuleCompiledFunction, ModuleError, DataContext};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum BackendError {
|
||||||
|
#[error("Cranelift module error: {0}")]
|
||||||
|
Cranelift(#[from] ModuleError),
|
||||||
|
#[error("Builtin function error: {0}")]
|
||||||
|
BuiltinError(#[from] RuntimeFunctionError),
|
||||||
|
#[error("Internal variable lookup error")]
|
||||||
|
VariableLookupFailure,
|
||||||
|
}
|
||||||
|
|
||||||
impl<Annotation> Program<Annotation> {
|
impl<Annotation> Program<Annotation> {
|
||||||
pub fn into_cranelift<M: Module>(&self, module: &mut M, print_func_id: FuncId) -> Result<ModuleCompiledFunction, ModuleError> {
|
pub fn into_cranelift<M: Module>(
|
||||||
|
&self,
|
||||||
|
module: &mut M,
|
||||||
|
rtfuns: &RuntimeFunctions,
|
||||||
|
) -> Result<ModuleCompiledFunction, BackendError> {
|
||||||
let basic_signature = Signature {
|
let basic_signature = Signature {
|
||||||
params: vec![],
|
params: vec![],
|
||||||
returns: vec![],
|
returns: vec![],
|
||||||
@@ -16,9 +34,33 @@ impl<Annotation> Program<Annotation> {
|
|||||||
|
|
||||||
let func_id = module.declare_function("gogogo", Linkage::Export, &basic_signature)?;
|
let func_id = module.declare_function("gogogo", Linkage::Export, &basic_signature)?;
|
||||||
let mut ctx = Context::new();
|
let mut ctx = Context::new();
|
||||||
ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature);
|
ctx.func =
|
||||||
|
Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature);
|
||||||
|
let mut variable_name_global_values = HashMap::new();
|
||||||
|
|
||||||
let print_func_ref = module.declare_func_in_func(print_func_id, &mut ctx.func);
|
for stmt in self.statements.iter() {
|
||||||
|
if let Statement::Print(_ann, var) = stmt {
|
||||||
|
let name = self
|
||||||
|
.variable_info
|
||||||
|
.get_name(*var)
|
||||||
|
.ok_or(BackendError::VariableLookupFailure)?;
|
||||||
|
let global_id = module.declare_data(
|
||||||
|
&format!("local-{}", name),
|
||||||
|
Linkage::Local,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
let mut data_context = DataContext::new();
|
||||||
|
data_context.set_align(8);
|
||||||
|
let zero_termed = format!("{}\0", name);
|
||||||
|
data_context.define(zero_termed.into_boxed_str().into_boxed_bytes());
|
||||||
|
module.define_data(global_id, &data_context)?;
|
||||||
|
let local_data = module.declare_data_in_func(global_id, &mut ctx.func);
|
||||||
|
variable_name_global_values.insert(*var, local_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let print_func_ref = rtfuns.include_runtime_function("print", module, &mut ctx.func)?;
|
||||||
|
|
||||||
let mut fctx = FunctionBuilderContext::new();
|
let mut fctx = FunctionBuilderContext::new();
|
||||||
let mut builder = FunctionBuilder::new(&mut ctx.func, &mut fctx);
|
let mut builder = FunctionBuilder::new(&mut ctx.func, &mut fctx);
|
||||||
@@ -28,8 +70,10 @@ impl<Annotation> Program<Annotation> {
|
|||||||
for stmt in self.statements.iter() {
|
for stmt in self.statements.iter() {
|
||||||
match stmt {
|
match stmt {
|
||||||
Statement::Print(_ann, var) => {
|
Statement::Print(_ann, var) => {
|
||||||
let var = builder.use_var(Variable::new(*var));
|
let local_data = *variable_name_global_values.get(var).unwrap();
|
||||||
builder.ins().call(print_func_ref, &[var]);
|
let var_name = builder.ins().symbol_value(types::I64, local_data);
|
||||||
|
let val = builder.use_var(Variable::new(*var));
|
||||||
|
builder.ins().call(print_func_ref, &[var_name, val]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement::ResultBinding(_, varnum, value) => {
|
Statement::ResultBinding(_, varnum, value) => {
|
||||||
@@ -77,7 +121,7 @@ impl<Annotation> Program<Annotation> {
|
|||||||
builder.seal_block(main_block);
|
builder.seal_block(main_block);
|
||||||
builder.finalize();
|
builder.finalize();
|
||||||
|
|
||||||
module.define_function(func_id, &mut ctx)
|
Ok(module.define_function(func_id, &mut ctx)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +130,7 @@ impl<Annotation> SimpleExpression<Annotation> {
|
|||||||
match self {
|
match self {
|
||||||
SimpleExpression::Constant(_, value) => match value {
|
SimpleExpression::Constant(_, value) => match value {
|
||||||
Value::Number(_base, numval) => builder.ins().iconst(types::I64, *numval as i64),
|
Value::Number(_base, numval) => builder.ins().iconst(types::I64, *numval as i64),
|
||||||
}
|
},
|
||||||
|
|
||||||
SimpleExpression::Reference(_, num) => builder.use_var(Variable::new(*num)),
|
SimpleExpression::Reference(_, num) => builder.use_var(Variable::new(*num)),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use cranelift_codegen::ir::{Signature, AbiParam, types, ArgumentPurpose, ArgumentExtension, Function, FuncRef};
|
use cranelift_codegen::ir::{
|
||||||
|
types, AbiParam, ArgumentExtension, ArgumentPurpose, FuncRef, Function, Signature,
|
||||||
|
};
|
||||||
use cranelift_codegen::isa::CallConv;
|
use cranelift_codegen::isa::CallConv;
|
||||||
use cranelift_module::{Module, ModuleResult, Linkage, FuncId};
|
use cranelift_module::{FuncId, Linkage, Module, ModuleResult};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@@ -20,22 +22,36 @@ impl RuntimeFunctions {
|
|||||||
let mut builtin_functions = HashMap::new();
|
let mut builtin_functions = HashMap::new();
|
||||||
let _referenced_functions = Vec::new();
|
let _referenced_functions = Vec::new();
|
||||||
|
|
||||||
let string_param = AbiParam::new(types::R64);
|
let string_param = AbiParam::new(types::I64);
|
||||||
let int64_param = AbiParam::new(types::I64);
|
let int64_param = AbiParam::new(types::I64);
|
||||||
|
|
||||||
let print_id = module.declare_function("print", Linkage::Import, &Signature {
|
let print_id = module.declare_function(
|
||||||
params: vec![string_param, int64_param],
|
"print",
|
||||||
returns: vec![],
|
Linkage::Import,
|
||||||
call_conv: CallConv::AppleAarch64
|
&Signature {
|
||||||
})?;
|
params: vec![string_param, int64_param],
|
||||||
|
returns: vec![],
|
||||||
|
call_conv: CallConv::AppleAarch64,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
builtin_functions.insert("print".to_string(), print_id);
|
builtin_functions.insert("print".to_string(), print_id);
|
||||||
|
|
||||||
Ok(RuntimeFunctions { builtin_functions, _referenced_functions })
|
Ok(RuntimeFunctions {
|
||||||
|
builtin_functions,
|
||||||
|
_referenced_functions,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn include_runtime_function<M: Module>(&self, name: &str, module: &mut M, func: &mut Function) -> Result<FuncRef, RuntimeFunctionError> {
|
pub fn include_runtime_function<M: Module>(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
module: &mut M,
|
||||||
|
func: &mut Function,
|
||||||
|
) -> Result<FuncRef, RuntimeFunctionError> {
|
||||||
match self.builtin_functions.get(name) {
|
match self.builtin_functions.get(name) {
|
||||||
None => Err(RuntimeFunctionError::CannotFindRuntimeFunction(name.to_string())),
|
None => Err(RuntimeFunctionError::CannotFindRuntimeFunction(
|
||||||
|
name.to_string(),
|
||||||
|
)),
|
||||||
Some(func_id) => Ok(module.declare_func_in_func(*func_id, func)),
|
Some(func_id) => Ok(module.declare_func_in_func(*func_id, func)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user