diff options
| -rw-r--r-- | examples/hello.sloth | 18 | ||||
| -rw-r--r-- | sloth/src/codegen/mod.rs | 123 | ||||
| -rw-r--r-- | sloth/src/main.rs | 43 | ||||
| -rw-r--r-- | test.c | 13 |
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(); @@ -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(""); } |
