Skip to content

Commit

Permalink
Add codegen for dynamically sized arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
skius committed Nov 10, 2021
1 parent 659dc5b commit 525ff45
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 10 deletions.
15 changes: 13 additions & 2 deletions codegen-examples/array.progge
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@ fn program(_argc: int) -> int {
if arr_v[0][0] == 1 {
let _ = print_int(_argc);
}
let _ = print_int(-1);
let _ = print_int(111111111111111);
// prints 100 because Progge's arrays are by-reference
let _ = print_int(arr_v[1][1]);

let _ = print_int(111111111111111);

let dyn_arr = [42; _argc];
let i = 0;
while i < _argc {
let _ = print_int(dyn_arr[i]);
i = i + 1;
}

return 0;
}

fn double_index(barr: [[int]]) -> [int] {
barr[0] = [1];
let size = 1;
barr[0] = [1; size];
return barr[1];
}
13 changes: 13 additions & 0 deletions runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ int64_t* alloc_array(int64_t size) {
return array;
}

int64_t* alloc_array_default(int64_t size, int64_t value) {
int64_t* array = malloc((size + 1) * sizeof(int64_t));
if (array == NULL) {
printf("Array allocation failed!\n");
exit(1);
}
array[0] = size;
for (int i = 1; i <= size; i++) {
array[i] = value;
}
return array;
}

int64_t int_arg(int64_t i) {
char* arg = argv[i];
int64_t result = 0;
Expand Down
34 changes: 26 additions & 8 deletions src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::arch::x86_64::_mm256_undefined_pd;
use std::collections::HashMap;
use std::process::Command;
use inkwell::builder::Builder;
Expand Down Expand Up @@ -70,15 +71,20 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
self.context.i64_type().into()
}

fn compile_array_alloc(&mut self, size: u64) -> PointerValue<'ctx> {
let size = self.context.i64_type().const_int(size as u64, false);

fn compile_array_alloc(&mut self, size: IntValue<'ctx>) -> PointerValue<'ctx> {
let alloc_array_fn = self.functions.get("alloc_array").unwrap();
let alloc_array_res = self.builder.build_call(*alloc_array_fn, &[size.into()], "alloc_array");

alloc_array_res.try_as_basic_value().left().unwrap().into_pointer_value()
}

fn compile_array_alloc_default(&mut self, size: IntValue<'ctx>, default: IntValue<'ctx>) -> PointerValue<'ctx> {
let alloc_array_default_fn = self.functions.get("alloc_array_default").unwrap();
let alloc_array_default_res = self.builder.build_call(*alloc_array_default_fn, &[size.into(), default.into()], "alloc_array_default");

alloc_array_default_res.try_as_basic_value().left().unwrap().into_pointer_value()
}

fn compile_loc_exp(&mut self, lexp: &WithLoc<LocExpr>) -> PointerValue<'ctx> {
match &lexp.elem {
LocExpr::Var(v) => {
Expand Down Expand Up @@ -193,13 +199,14 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
// Progge array representation: pointer to array of size+1 elements, element 0 is size
// also, arrays are reference types
Expr::Array(els) => {
let ty = match &exp.typ {
Type::Array(t) => t.clone(),
_ => panic!("Expected array type")
};
// let ty = match &exp.typ {
// Type::Array(t) => t.clone(),
// _ => panic!("Expected array type")
// };

let size = els.len();
let arr_ptr = self.compile_array_alloc(size as u64);
let size = self.context.i64_type().const_int(size as u64, false);
let arr_ptr = self.compile_array_alloc(size);

unsafe {
for (i, el) in els.iter().enumerate() {
Expand All @@ -223,6 +230,13 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {

self.builder.build_ptr_to_int(arr_ptr, self.context.i64_type(), "arr_ptr_int").into()
}
Expr::DefaultArray { default_value, size } => {
let size = self.compile_exp(size);
let default_value = self.compile_exp(default_value);
let arr_ptr = self.compile_array_alloc_default(size.into_int_value(), default_value.into_int_value());

self.builder.build_ptr_to_int(arr_ptr, self.context.i64_type(), "arr_ptr_int").into()
}
Expr::Index(arr, idx) => {
let ptr = self.compile_loc_exp(&WithLoc::new(LocExpr::Index((**arr).clone(), (**idx).clone()), exp.loc));
self.builder.build_load(ptr, "arr_idx_load").into()
Expand Down Expand Up @@ -417,6 +431,10 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
let alloc_array_fn = self.module.add_function("alloc_array", alloc_array, None);
self.functions.insert("alloc_array".to_string(), alloc_array_fn);

let alloc_array_default = self.context.i64_type().ptr_type(AddressSpace::Generic).fn_type(&[self.context.i64_type().into(), self.context.i64_type().into()], false);
let alloc_array_default_fn = self.module.add_function("alloc_array_default", alloc_array_default, None);
self.functions.insert("alloc_array_default".to_string(), alloc_array_default_fn);

let funcdefs = self.program.0.clone();
// Build decl map
for f in funcdefs.iter() {
Expand Down

0 comments on commit 525ff45

Please sign in to comment.