From 0370e7c22a193eca2a2aa71bf5a46db5749a9d0d Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sat, 3 Dec 2022 03:37:43 -0500 Subject: Add initial struct offset calculation --- libtnsl/math/basic.tnsl | 36 +++++++-------- tnslc/compile/compile.tnsl | 109 ++++++++++++++++++++++++++++++++++++++++++++- tnslc/dummy.tnsl | 4 ++ 3 files changed, 129 insertions(+), 20 deletions(-) diff --git a/libtnsl/math/basic.tnsl b/libtnsl/math/basic.tnsl index 354abe8..5671c25 100644 --- a/libtnsl/math/basic.tnsl +++ b/libtnsl/math/basic.tnsl @@ -28,14 +28,14 @@ ;return a ;/ -/; absf (float a) [float] +/; abs_f (float a) [float] /; if (a < 0) ;return -a ;/ ;return a ;/ -/; abst (type T, T a) [T] +/; abs_t (type T, T a) [T] /; if ( a < (0)[T] ) ;return -a ;/ @@ -49,12 +49,12 @@ ;return o1, o2 ;/ -/; divf (float a, b) [float, float] +/; div_f (float a, b) [float, float] ;float o1 = a / b, o2 = a % b ;return o1, o2 ;/ -/; divt (type T, T a, b) [T, T] +/; div_t (type T, T a, b) [T, T] ;T o1 = a / b, o2 = a % b ;return o1, o2 ;/ @@ -68,14 +68,14 @@ ;return b ;/ -/; maxf (float a, b) [float] +/; max_f (float a, b) [float] /; if (a > b) ;return a ;/ ;return b ;/ -/; maxt (type T, T a, b) [T] +/; max_t (type T, T a, b) [T] /; if (a > b) ;return a ;/ @@ -89,14 +89,14 @@ ;return b ;/ -/; minf (float a, b) [float] +/; min_f (float a, b) [float] /; if (a > b) ;return a ;/ ;return b ;/ -/; mint (type T, T a, b) [T] +/; min_t (type T, T a, b) [T] /; if (a < b) ;return a ;/ @@ -109,7 +109,7 @@ ;return a - (a % 1.0) ;/ -/; trunct (type T, T a) [T] +/; trunc_t (type T, T a) [T] ;return a - (a % (1.0)[T]) ;/ @@ -120,9 +120,9 @@ ;return a ;/ -/; ceilt (type T, T a) [T] - /; if (trunct(T, a) !== a) - ;return trunct(T, a + (1.0)[T]) +/; ceil_t (type T, T a) [T] + /; if (trunc_t(T, a) !== a) + ;return trunc_t(T, a + (1.0)[T]) ;/ ;return a ;/ @@ -134,9 +134,9 @@ ;return a ;/ -/; floort (type T, T a) [T] - /; if (trunct(T, a) !== a) - ;return trunct(T, a - (1.0)[T]) +/; floor_t (type T, T a) [T] + /; if (trunc_t(T, a) !== a) + ;return trunc_t(T, a - (1.0)[T]) ;/ ;return a ;/ @@ -148,10 +148,10 @@ ;return ceil(a) ;/ -/; roundt (type T, T a) [T] +/; round_t (type T, T a) [T] /; if (a % (1.0)[T] < (0.5)[T]) - ;return floort(T, a) + ;return floor_t(T, a) ;/ - ;return ceilt(T, a) + ;return ceil_t(T, a) ;/ diff --git a/tnslc/compile/compile.tnsl b/tnslc/compile/compile.tnsl index 9472313..4862342 100644 --- a/tnslc/compile/compile.tnsl +++ b/tnslc/compile/compile.tnsl @@ -74,6 +74,26 @@ ;return -1 ;/ +/; reg_by_num(int r) [{}charp] + /; if (r == 0) + ;return "ax" + ;; if (r == 1) + ;return "bx" + ;; if (r == 2) + ;return "cx" + ;; if (r == 3) + ;return "dx" + ;; if (r == 4) + ;return "sp" + ;; if (r == 5) + ;return "bp" + ;; if (r == 6) + ;return "si" + ;; if (r == 7) + ;/ + ;return string_from_int(r) +;/ + # Given an index in the vtrack, returns a string representation of the # register or memory where that variable is /; index_to_loc (int index, ~VTrack tab) [{}charp] @@ -89,6 +109,12 @@ ;stack_bytes = stack_bytes + tab`.sym_types{i}._size ;/ ;/ + + /; if (is_struct(tab`.sym_types{index})) + ;out = "(todo: structs)" + ;; else + ;out = reg_by_num(reg) + ;/ ;return out ;/ @@ -108,6 +134,82 @@ ;return true ;/ +# Using the type name and member name, create a label of form "_type.member" +/; construct_offset_label ({}charp t, {}charp n) [{}charp] + ;{}charp out = "_" + ;add_strings(~out, ~t) + ;out.append('.') + ;add_strings(~out, ~n) + ;return out +;/ + +/; construct_offset_value (int offset) [{}charp] + ;{}charp out = ".qword " + ;{}charp tmp = string_from_int(offset) + ;add_strings(~out, ~tmp) + ;return out +;/ + +# Parse a struct and add it to the table +/; def_struct (~int cur, ~{}Token data, ~{}charp dsec) [VType] + ;VType out = {0, 0, ""} + ;cur`++ + + ;{}charp a = "_" + ;add_strings(~a, data`{cur`}.data) + ;out.name = data`{cur`}.data` + + ;cur`++ + ;cur`++ + # Should be indexed at first type in the type list + + /; if (token_is(cur, data, "}")) + ;return NT + ;/ + + ;VType ctype = get_vtype(cur, data) + ;cur`++ + + /; loop (cur` < len data`) [cur`++] + /; if (token_is(cur, data, "}")) + ;break + ;; else if (token_is(cur, data, ",")) + ;cur`++ + ;/ + + ;cur`++ + /; if (token_is(cur, data, ",") || token_is(cur, data, "}")) + # Use ctype + ;cur`-- + ;{}charp l = construct_offset_label(out.name, data`{cur`}.data`) + ;l.append(':') + ;l.append(' ') + ;{}charp p = construct_offset_value(out._size) + + /; if (ctype.ptr > 0) + ;p = construct_offset_value(8) + ;out._size = out._size + 8 + ;; else + ;out._size = out._size + ctype._size + ;/ + + ;p.append('\n') + ;add_strings(~l, ~p) + # add "_type.member: .qword #offset_value" to data section + + ;add_strings(dsec, ~l) + + ;; else + # Get type + ;cur`-- + ;ctype = get_vtype(cur, data) + ;/ + ;/ + + ;type_table.append(out) + ;return out +;/ + # Checks if the current token's data is equal to a string /; token_is(~int cur, ~{}Token data, {}charp str) [bool] ;return string_equate(data`{cur`}.data`, str) @@ -184,8 +286,11 @@ ;/ # Mostly deals with structs and enums -/; compile_global - +/; compile_global (~int cur, ~{}Token data, ~VTrack gsc, ~{}charp hsec, csec, dsec) + ;cur`++ + /; if (token_is(cur, data, "struct")) + ;def_struct(cur, data, dsec) + ;/ ;/ # Sets up a call and reports back where the return value is stored diff --git a/tnslc/dummy.tnsl b/tnslc/dummy.tnsl index bd28c70..c806022 100644 --- a/tnslc/dummy.tnsl +++ b/tnslc/dummy.tnsl @@ -1,3 +1,7 @@ +;struct test { + int i, j, k, l +} + /; _alloc (uint bytes) [~void] ;asm "mov %rax, %rdi" ;asm "mov $0, %r10" -- cgit v1.2.3