Translate function (no args yet)
This commit is contained in:
parent
c884287d33
commit
716ad3e4e9
|
@ -27,8 +27,8 @@ impl Engine {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn compile(&mut self, expr: &ast::Expr) -> Result<*const u8, String> {
|
||||
self.translate(expr)?;
|
||||
pub fn compile(&mut self, fn_impl: &ast::FnImpl) -> Result<*const u8, String> {
|
||||
self.translate(fn_impl)?;
|
||||
|
||||
let name = "dummy_function";
|
||||
let id = self
|
||||
|
@ -49,26 +49,11 @@ impl Engine {
|
|||
Ok(code)
|
||||
}
|
||||
|
||||
pub fn translate(&mut self, expr: &ast::Expr) -> Result<(), String> {
|
||||
pub fn translate(&mut self, fn_impl: &ast::FnImpl) -> Result<(), String> {
|
||||
let int = self.module.target_config().pointer_type();
|
||||
|
||||
self.ctx.func.signature.returns.push(AbiParam::new(int));
|
||||
|
||||
let mut builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_context);
|
||||
|
||||
let entry_block = builder.create_block();
|
||||
builder.append_block_params_for_function_params(entry_block);
|
||||
builder.switch_to_block(entry_block);
|
||||
builder.seal_block(entry_block);
|
||||
|
||||
let builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_context);
|
||||
let mut trans = super::translate::FunctionTranslator { int, builder };
|
||||
|
||||
let return_value = trans.translate_expr(expr);
|
||||
trans.builder.ins().return_(&[return_value]);
|
||||
|
||||
println!("{}", trans.builder.func.display());
|
||||
trans.builder.finalize();
|
||||
|
||||
trans.translate(fn_impl);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -79,17 +64,17 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn simple_math() {
|
||||
use crate::parse::{
|
||||
lexer::{Lexer, Token},
|
||||
rd::RecursiveDescent,
|
||||
};
|
||||
|
||||
let source = "(1 + 2) * (3 / (4 + 5));";
|
||||
use crate::parse::lexer::Lexer;
|
||||
use crate::parse::rd::RecursiveDescent;
|
||||
let source = "simple_math() i64 { (1 + 2) * (3 / (4 + 5)) }";
|
||||
println!("JIT-compiling source: {}", source);
|
||||
let lexer = Lexer::new(source);
|
||||
let mut rd = RecursiveDescent::new(lexer);
|
||||
let (expr, tail) = rd.build_expr();
|
||||
let expr = expr.expect("Failed to parse expression");
|
||||
assert_eq!(tail, Token::Semicolon);
|
||||
Engine::new().compile(&expr).unwrap();
|
||||
let def = rd.build_fn(false, None);
|
||||
if let ast::Definition::Function { implementation, .. } = def {
|
||||
Engine::new().compile(&implementation).unwrap();
|
||||
} else {
|
||||
panic!("Failed to parse function from test source");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2022 Marceline Cramer
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
use cranelift::prelude::*;
|
||||
use crate::parse::ast;
|
||||
use cranelift::prelude::*;
|
||||
|
||||
pub struct FunctionTranslator<'a> {
|
||||
pub int: types::Type,
|
||||
|
@ -10,6 +10,55 @@ pub struct FunctionTranslator<'a> {
|
|||
}
|
||||
|
||||
impl<'a> FunctionTranslator<'a> {
|
||||
pub fn translate(mut self, fn_impl: &ast::FnImpl) {
|
||||
let signature = &fn_impl.def.signature;
|
||||
|
||||
let return_info = if let Some(tail_expr) = &fn_impl.body.tail_expr {
|
||||
match signature.return_type {
|
||||
Some(t) => Some((tail_expr, t)),
|
||||
None => panic!("Function has tail expression but no return type"),
|
||||
}
|
||||
} else if let Some(_) = signature.return_type {
|
||||
panic!("Function has return type but no tail expression");
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for _ in signature.args.iter() {
|
||||
self.builder
|
||||
.func
|
||||
.signature
|
||||
.params
|
||||
.push(AbiParam::new(self.int));
|
||||
}
|
||||
|
||||
if let Some((_, _return_type)) = return_info {
|
||||
self.builder
|
||||
.func
|
||||
.signature
|
||||
.returns
|
||||
.push(AbiParam::new(self.int));
|
||||
}
|
||||
|
||||
let entry_block = self.builder.create_block();
|
||||
self.builder
|
||||
.append_block_params_for_function_params(entry_block);
|
||||
self.builder.switch_to_block(entry_block);
|
||||
self.builder.seal_block(entry_block);
|
||||
|
||||
if fn_impl.body.statements.len() > 0 {
|
||||
unimplemented!("Function body statements are unimplemented");
|
||||
}
|
||||
|
||||
if let Some((tail_expr, _)) = return_info {
|
||||
let return_value = self.translate_expr(tail_expr);
|
||||
self.builder.ins().return_(&[return_value]);
|
||||
}
|
||||
|
||||
println!("{}", self.builder.func.display());
|
||||
self.builder.finalize();
|
||||
}
|
||||
|
||||
pub fn translate_expr(&mut self, expr: &ast::Expr) -> Value {
|
||||
use ast::Expr::*;
|
||||
match expr {
|
||||
|
|
Loading…
Reference in New Issue