Translate function (no args yet)

This commit is contained in:
mars 2022-03-26 09:42:59 -06:00
parent c884287d33
commit 716ad3e4e9
2 changed files with 65 additions and 31 deletions

View File

@ -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");
}
}
}

View File

@ -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 {