Skip to content

Commit

Permalink
vset, vget & vlen
Browse files Browse the repository at this point in the history
  • Loading branch information
cody-quinn committed Jun 26, 2023
1 parent 00e423d commit daecd33
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 11 deletions.
18 changes: 18 additions & 0 deletions examples/hello.sloth
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,21 @@ fn testtwo(list: [Int]) Int {
return x;
}

fn testthree(list: [Int]) Int {
var x: Int = vlen(list);
return x;
}

foreign fn testback(x: Int) Void;

fn testfour(list: [Int]) Int {
vseti(list, 0, 888);
var i: Int = 0;
while i < vlen(list) {
var value: Int = vgeti(list, i);
testback(value);
i = i + 1;
}
return 0;
}

123 changes: 121 additions & 2 deletions sloth/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,18 @@ impl<'ctx> Codegen<'ctx> {
references: Default::default(),
};

// Compiler intrinsic functions
this.INTRINSIC_vlen();

for (c, t) in [
("i", Type::Integer),
("f", Type::Float),
("b", Type::Boolean),
] {
this.INTRINSIC_vpush(c, t.clone());
this.INTRINSIC_vpop(c, t);
this.INTRINSIC_vpop(c, t.clone());
this.INTRINSIC_vget(c, t.clone());
this.INTRINSIC_vset(c, t);
}

this
Expand Down Expand Up @@ -621,7 +626,7 @@ impl<'ctx> Codegen<'ctx> {
let array_input = self.type_as_basic_type(Type::Array {
typ: Box::new(typ.clone()),
});
let inputs = &[array_input.into(), self.type_as_metadata_type(typ.clone())];
let inputs = &[array_input.into()];
let func_type = match typ {
Type::Integer => self.context.i32_type().fn_type(inputs, false),
Type::Float => self.context.f32_type().fn_type(inputs, false),
Expand All @@ -640,6 +645,8 @@ impl<'ctx> Codegen<'ctx> {
let (size_ptr, cap_ptr, inner_ptr) = self._get_ptrs(element_type, vector_ptr);
let (size, _cap, inner) = self._get_values(element_type, size_ptr, cap_ptr, inner_ptr);

// FIXME: Array cant shrink as of now

// Get the last element in the array
let element_idx = self
.builder
Expand All @@ -658,4 +665,116 @@ impl<'ctx> Codegen<'ctx> {
// Return element
self.builder.build_return(Some(&element));
}

fn INTRINSIC_vget(&mut self, name: &str, typ: Type) {
// Setup function
let array_input = self.type_as_basic_type(Type::Array {
typ: Box::new(typ.clone()),
});
// [Array, Index]
let inputs = &[array_input.into(), self.context.i32_type().into()];
let func_type = match typ {
Type::Integer => self.context.i32_type().fn_type(inputs, false),
Type::Float => self.context.f32_type().fn_type(inputs, false),
Type::Boolean => self.context.bool_type().fn_type(inputs, false),
_ => panic!(),
};
self._setup(&format!("vget{name}"), func_type);
let func = self.current_func.unwrap();

// Types
let element_type = self.type_as_basic_type(typ);

// Getting the pointers and values needed
let vector_ptr = func.get_nth_param(0).unwrap().into_pointer_value();
let (size_ptr, cap_ptr, inner_ptr) = self._get_ptrs(element_type, vector_ptr);
let (_, _, inner) = self._get_values(element_type, size_ptr, cap_ptr, inner_ptr);

// Get the selected element in the array
let element_idx = func.get_nth_param(1).unwrap().into_int_value();
let element_ptr = unsafe {
self.builder
.build_gep(element_type, inner, &[element_idx], "elementptr")
};
let element = self
.builder
.build_load(element_type, element_ptr, "element");

// Return element
self.builder.build_return(Some(&element));
}

fn INTRINSIC_vset(&mut self, name: &str, typ: Type) {
// Setup function
let array_input = self.type_as_basic_type(Type::Array {
typ: Box::new(typ.clone()),
});
// [Array, Index, Value]
let inputs = &[
array_input.into(),
self.context.i32_type().into(),
self.type_as_metadata_type(typ.clone()),
];
let func_type = self.context.void_type().fn_type(inputs, false);
self._setup(&format!("vset{name}"), func_type);
let func = self.current_func.unwrap();

// Types
let element_type = self.type_as_basic_type(typ);

// Getting the pointers and values needed
let vector_ptr = func.get_nth_param(0).unwrap().into_pointer_value();
let (size_ptr, cap_ptr, inner_ptr) = self._get_ptrs(element_type, vector_ptr);
let (_, _, inner) = self._get_values(element_type, size_ptr, cap_ptr, inner_ptr);

// Get the selected element in the array
let element_idx = func.get_nth_param(1).unwrap().into_int_value();
let element_ptr = unsafe {
self.builder
.build_gep(element_type, inner, &[element_idx], "elementptr")
};
let element = func.get_nth_param(2).unwrap();
self.builder.build_store(element_ptr, element);

self.builder.build_return(None);
}

fn INTRINSIC_vremove(&mut self, name: &str, typ: Type) {
// Setup function
let array_input = self.type_as_basic_type(Type::Array {
typ: Box::new(typ.clone()),
});
// [Array, Index]
let inputs = &[array_input.into(), self.context.i32_type().into()];
let func_type = self.context.void_type().fn_type(inputs, false);
self._setup(&format!("vremove{name}"), func_type);
let func = self.current_func.unwrap();

// Types
let element_type = self.type_as_basic_type(typ);

// FIXME: Array cant shrink as of now
// TODO: vremove
}

fn INTRINSIC_vlen(&mut self) {
// Setup function
let array_input = self.type_as_basic_type(Type::Array {
typ: Box::new(Type::Integer),
});
// [Array, Index]
let inputs = &[array_input.into(), self.context.i32_type().into()];
let func_type = self.context.i32_type().fn_type(inputs, false);
self._setup("vlen", func_type);
let func = self.current_func.unwrap();

// Getting the pointers and values needed
let element_type = self.type_as_basic_type(Type::Integer); // Dummy - Not actually used
let vector_ptr = func.get_nth_param(0).unwrap().into_pointer_value();
let (size_ptr, cap_ptr, inner_ptr) = self._get_ptrs(element_type, vector_ptr);
let (size, _, _) = self._get_values(element_type, size_ptr, cap_ptr, inner_ptr);

// Return element
self.builder.build_return(Some(&size));
}
}
43 changes: 35 additions & 8 deletions sloth/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,48 @@ fn main() {
global_symtable.insert("Float".into(), Symbol::Type(Type::Float));
global_symtable.insert("Bool".into(), Symbol::Type(Type::Boolean));

let dummy = Symbol::Value(ValueSymbol {
// Inputs aren't type checked but outputs are
let dummyi = Symbol::Value(ValueSymbol {
typ: Type::Function {
inputs: vec![],
output: Box::new(Type::Void),
output: Box::new(Type::Integer),
},
id: 0,
});

global_symtable.insert("vpushi".into(), dummy.clone());
global_symtable.insert("vpushf".into(), dummy.clone());
global_symtable.insert("vpushb".into(), dummy.clone());
let dummyf = Symbol::Value(ValueSymbol {
typ: Type::Function {
inputs: vec![],
output: Box::new(Type::Float),
},
id: 0,
});

let dummyb = Symbol::Value(ValueSymbol {
typ: Type::Function {
inputs: vec![],
output: Box::new(Type::Boolean),
},
id: 0,
});

global_symtable.insert("vlen".into(), dummyi.clone());

global_symtable.insert("vpushi".into(), dummyi.clone());
global_symtable.insert("vpushf".into(), dummyf.clone());
global_symtable.insert("vpushb".into(), dummyb.clone());

global_symtable.insert("vpopi".into(), dummyi.clone());
global_symtable.insert("vpopf".into(), dummyf.clone());
global_symtable.insert("vpopb".into(), dummyb.clone());

global_symtable.insert("vgeti".into(), dummyi.clone());
global_symtable.insert("vgetf".into(), dummyf.clone());
global_symtable.insert("vgetb".into(), dummyb.clone());

global_symtable.insert("vpopi".into(), dummy.clone());
global_symtable.insert("vpopf".into(), dummy.clone());
global_symtable.insert("vpopb".into(), dummy);
global_symtable.insert("vseti".into(), dummyi);
global_symtable.insert("vsetf".into(), dummyf);
global_symtable.insert("vsetb".into(), dummyb);

// Parsing
let tokens = Lexer::new(&source).collect_vec();
Expand Down
13 changes: 12 additions & 1 deletion test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ typedef struct {

IntVec* test();
int testtwo(IntVec*);
int testthree(IntVec*);
int testfour(IntVec*);

void testback(int x) {
printf("%d, ", x);
}

int main() {
IntVec* v = test();
Expand Down Expand Up @@ -38,5 +44,10 @@ int main() {
int value = inner[i];
printf("%d ", value);
}
puts("\n");
puts("\n\n");
int i = testthree(v);
printf("%d ", i);
puts("\n\n");
testfour(v);
puts("");
}

0 comments on commit daecd33

Please sign in to comment.