Skip to content

Commit

Permalink
Add parameter dereferencing
Browse files Browse the repository at this point in the history
No type or semantic checking done yet on parameters, will need to
implement scoping
  • Loading branch information
IGI-111 committed Nov 5, 2019
1 parent 7b7eb5c commit 1c7fa2b
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 79 deletions.
6 changes: 3 additions & 3 deletions a.jack
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
fn fun(a: int): bool
true
fn not(a: bool): bool
!a
end

fn main(): int
if true then
if fun(1) then
if not(not(true)) then
1
else
9999
Expand Down
10 changes: 5 additions & 5 deletions src/gen/expr/array.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::super::{GenerationContext, Realizable};
use super::gen_expr;
use crate::ir::typed::*;
use crate::ir::sem::*;
use crate::ir::*;
use inkwell::types::BasicTypeEnum;
use inkwell::values::{ArrayValue, BasicValueEnum, IntValue};

pub(super) fn gen_array(
vals: &Vec<Box<TypedNode>>,
vals: &Vec<Box<SemNode>>,
ty: &Type,
ctx: &GenerationContext,
) -> BasicValueEnum {
Expand Down Expand Up @@ -43,15 +43,15 @@ pub(super) fn gen_array(
}

pub(super) fn gen_array_deref(
array: &TypedNode,
index: &TypedNode,
array: &SemNode,
index: &SemNode,
ctx: &GenerationContext,
) -> BasicValueEnum {
ctx.builder
.build_extract_value(
gen_expr(array, ctx).into_array_value(),
match index.expr() {
TypedExpression::Int(val) => *val as u32,
SemExpression::Int(val) => *val as u32,
_ => unreachable!(),
},
"",
Expand Down
8 changes: 4 additions & 4 deletions src/gen/expr/conditional.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use super::super::GenerationContext;
use super::gen_expr;
use crate::ir::typed::*;
use crate::ir::sem::*;
use inkwell::values::{BasicValue, BasicValueEnum};

pub(super) fn gen_conditional(
cond: &TypedNode,
then: &TypedNode,
alt: &TypedNode,
cond: &SemNode,
then: &SemNode,
alt: &SemNode,
ctx: &GenerationContext,
) -> BasicValueEnum {
let cond_block = ctx
Expand Down
25 changes: 15 additions & 10 deletions src/gen/expr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
use super::GenerationContext;
use crate::ir::typed::*;
use crate::ir::sem::*;
use crate::ir::*;
use array::{gen_array, gen_array_deref};
use conditional::gen_conditional;
use inkwell::values::BasicValueEnum;
use inkwell::values::{BasicValue, BasicValueEnum};
use inkwell::IntPredicate;

mod array;
mod conditional;

pub(super) fn gen_expr(root: &TypedNode, ctx: &GenerationContext) -> BasicValueEnum {
pub(super) fn gen_expr(root: &SemNode, ctx: &GenerationContext) -> BasicValueEnum {
match root.expr() {
TypedExpression::FunCall(name, args) => ctx
SemExpression::Id(name) => ctx
.value_store
.get(name)
.expect(&format!("Unknown identifier {}", name))
.as_basic_value_enum(),
SemExpression::FunCall(name, args) => ctx
.builder
.build_call(
ctx.functions.get(name).unwrap().0,
Expand All @@ -21,16 +26,16 @@ pub(super) fn gen_expr(root: &TypedNode, ctx: &GenerationContext) -> BasicValueE
.try_as_basic_value()
.left()
.expect("Callsite is not convertible to a BasicValue"),
TypedExpression::Array(vals) => gen_array(vals, root.ty(), ctx),
TypedExpression::Bool(val) => BasicValueEnum::IntValue(
SemExpression::Array(vals) => gen_array(vals, root.ty(), ctx),
SemExpression::Bool(val) => BasicValueEnum::IntValue(
ctx.context
.bool_type()
.const_int(if *val { 1 } else { 0 }, false),
),
TypedExpression::Int(val) => {
SemExpression::Int(val) => {
BasicValueEnum::IntValue(ctx.context.i64_type().const_int(*val, false))
}
TypedExpression::UnaryOp(op, a) => match op {
SemExpression::UnaryOp(op, a) => match op {
UnaryOp::Minus => BasicValueEnum::IntValue(ctx.builder.build_int_sub(
ctx.context.i64_type().const_zero(),
gen_expr(a, ctx).into_int_value(),
Expand All @@ -42,7 +47,7 @@ pub(super) fn gen_expr(root: &TypedNode, ctx: &GenerationContext) -> BasicValueE
"",
)),
},
TypedExpression::BinaryOp(op, a, b) => match op {
SemExpression::BinaryOp(op, a, b) => match op {
BinaryOp::ArrayDeref => gen_array_deref(a, b, ctx),
BinaryOp::Add => BasicValueEnum::IntValue(ctx.builder.build_int_add(
gen_expr(a, ctx).into_int_value(),
Expand Down Expand Up @@ -115,6 +120,6 @@ pub(super) fn gen_expr(root: &TypedNode, ctx: &GenerationContext) -> BasicValueE
"",
)),
},
TypedExpression::Conditional(cond, then, alt) => gen_conditional(cond, then, alt, ctx),
SemExpression::Conditional(cond, then, alt) => gen_conditional(cond, then, alt, ctx),
}
}
16 changes: 13 additions & 3 deletions src/gen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::ir::typed::*;
use crate::ir::sem::*;
use crate::ir::*;
use expr::gen_expr;
use inkwell::builder::Builder;
Expand All @@ -14,8 +14,9 @@ mod expr;
struct GenerationContext<'a> {
pub builder: &'a Builder,
pub context: &'a Context,
pub value_store: &'a HashMap<String, BasicValueEnum>,
pub current_function: &'a FunctionValue,
pub functions: &'a HashMap<String, (FunctionValue, &'a TypedFunction)>,
pub functions: &'a HashMap<String, (FunctionValue, &'a SemFunction)>,
}

trait Realizable {
Expand All @@ -40,7 +41,7 @@ impl Realizable for Type {
}
}

pub fn gen(funcs: &[TypedFunction]) -> Module {
pub fn gen(funcs: &[SemFunction]) -> Module {
let context = Context::create();
let module = context.create_module("main");
let builder = context.create_builder();
Expand Down Expand Up @@ -75,7 +76,16 @@ pub fn gen(funcs: &[TypedFunction]) -> Module {
.collect::<HashMap<_, _>>();

for (function, fun) in functions.values() {
let mut value_store = HashMap::new();
for (param_val, param_name) in function
.get_param_iter()
.zip(fun.args().iter().map(|(name, _)| name))
{
value_store.insert(param_name.to_string(), param_val);
}

let ctx = GenerationContext {
value_store: &value_store,
context: &context,
builder: &builder,
current_function: &function,
Expand Down
8 changes: 7 additions & 1 deletion src/ir/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod raw;
pub mod typed;
pub mod sem;

#[derive(Debug, PartialEq, Clone)]
pub enum UnaryOp {
Expand Down Expand Up @@ -39,4 +39,10 @@ impl Type {
_ => panic!("Not a Function type"),
}
}
pub fn into_function(self) -> (Box<Type>, Vec<Box<Type>>) {
match self {
Type::Function(ret, args) => (ret, args),
_ => panic!("Not a Function type"),
}
}
}
7 changes: 4 additions & 3 deletions src/ir/raw.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use super::*;

#[derive(Debug, Clone)]
pub struct RawFunction {
pub name: String,
pub root: RawNode,
pub args: Vec<(String, Type)>,
pub ty: Type,
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub enum RawExpression {
Int(u64),
Bool(bool),
Array(Vec<Box<RawNode>>),
FunCall(String, Vec<Box<RawNode>>),
// Id(String),
Id(String), // TODO: semantic checking step
BinaryOp(BinaryOp, Box<RawNode>, Box<RawNode>),
UnaryOp(UnaryOp, Box<RawNode>),
Conditional(Box<RawNode>, Box<RawNode>, Box<RawNode>),
Expand All @@ -23,7 +24,7 @@ pub trait Node: PartialEq + Sized {
fn into_expr(self) -> RawExpression;
}

#[derive(PartialEq, Debug)]
#[derive(PartialEq, Debug, Clone)]
pub struct RawNode {
expr: RawExpression,
}
Expand Down
Loading

0 comments on commit 1c7fa2b

Please sign in to comment.