44 lines
1.5 KiB
Rust
44 lines
1.5 KiB
Rust
// Copyright (c) 2022 Marceline Cramer
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
use cranelift::prelude::*;
|
|
use crate::parse::ast;
|
|
|
|
pub struct FunctionTranslator<'a> {
|
|
pub int: types::Type,
|
|
pub builder: FunctionBuilder<'a>,
|
|
}
|
|
|
|
impl<'a> FunctionTranslator<'a> {
|
|
pub fn translate_expr(&mut self, expr: &ast::Expr) -> Value {
|
|
use ast::Expr::*;
|
|
match expr {
|
|
Literal(ast::Literal::DecimalInteger(literal)) => {
|
|
// TODO parse integers while building ast so that codegen doesn't have to
|
|
let val: i64 = literal.parse().unwrap();
|
|
self.builder.ins().iconst(self.int, val)
|
|
}
|
|
BinaryOp(op, terms) => {
|
|
let lhs = self.translate_expr(&terms.0);
|
|
let rhs = self.translate_expr(&terms.1);
|
|
self.translate_binary_op(op, lhs, rhs)
|
|
}
|
|
// TODO the AST doesn't need this either
|
|
Group(expr) => self.translate_expr(expr),
|
|
_ => unimplemented!("Expression: {:#?}", expr),
|
|
}
|
|
}
|
|
|
|
pub fn translate_binary_op(&mut self, op: &ast::BinaryOp, lhs: Value, rhs: Value) -> Value {
|
|
use ast::BinaryOp::*;
|
|
let ins = self.builder.ins();
|
|
match op {
|
|
Add => ins.iadd(lhs, rhs),
|
|
Sub => ins.isub(lhs, rhs),
|
|
Mul => ins.imul(lhs, rhs),
|
|
Div => ins.udiv(lhs, rhs),
|
|
_ => unimplemented!("Binary operation: {:#?}", op),
|
|
}
|
|
}
|
|
}
|