aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/hello.sloth18
-rw-r--r--sloth/src/codegen/mod.rs123
-rw-r--r--sloth/src/main.rs43
-rw-r--r--test.c13
4 files changed, 186 insertions, 11 deletions
diff --git a/examples/hello.sloth b/examples/hello.sloth
index f4e6692..db71b01 100644
--- a/examples/hello.sloth
+++ b/examples/hello.sloth
@@ -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;
+}
+
diff --git a/sloth/src/codegen/mod.rs b/sloth/src/codegen/mod.rs
index 0035802..07cfde9 100644
--- a/sloth/src/codegen/mod.rs
+++ b/sloth/src/codegen/mod.rs
@@ -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
@@ -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),
@@ -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
@@ -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));
+ }
}
diff --git a/sloth/src/main.rs b/sloth/src/main.rs
index 5522082..ff3df31 100644
--- a/sloth/src/main.rs
+++ b/sloth/src/main.rs
@@ -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();
diff --git a/test.c b/test.c
index 988b352..cac1aef 100644
--- a/test.c
+++ b/test.c
@@ -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();
@@ -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("");
}