From 89f2b3b4a40749eba388ea998b99381a37bbeb53 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sun, 14 May 2023 11:43:43 -0400 Subject: Indexing and proper string decomp --- tnslc/c_wrap.tnsl | 89 +++++++----------------------------- tnslc/proper_calling.tnsl | 21 --------- tnslc/simple.tnsl | 33 +------------- tnslc/syntax-playground.tnsl | 92 -------------------------------------- tnslc/tests/proper_calling.tnsl | 21 +++++++++ tnslc/tests/syntax-playground.tnsl | 92 ++++++++++++++++++++++++++++++++++++++ tnslc/tnslc.tnsl | 65 +++++++++++++++++---------- tnslc/tnslc_wrapped.tnsl | 10 +++-- tnslc/vector.tnsl | 69 ++++++++++++++++++++++++++++ 9 files changed, 247 insertions(+), 245 deletions(-) delete mode 100644 tnslc/proper_calling.tnsl delete mode 100644 tnslc/syntax-playground.tnsl create mode 100644 tnslc/tests/proper_calling.tnsl create mode 100644 tnslc/tests/syntax-playground.tnsl create mode 100644 tnslc/vector.tnsl diff --git a/tnslc/c_wrap.tnsl b/tnslc/c_wrap.tnsl index eead086..ee39cdc 100644 --- a/tnslc/c_wrap.tnsl +++ b/tnslc/c_wrap.tnsl @@ -3,8 +3,8 @@ asm "extern realloc" asm "extern free" asm "extern printf" -{}uint8 _alert = "Alert!" -uint _stop = 0 +{}uint8 _alert = "Alert!\n\0" +{}uint8 _dec = "%d\n\0" /; _alloc (uint size) [~void] ~void out @@ -72,79 +72,24 @@ uint _stop = 0 asm "mov r10, 0" # do call asm "call printf" - # there's no more to do 'cause free returns nothing + # there's no more to do 'cause printf returns nothing +;/ + +/; _print_num (~void str, int num) + # setup call by clearing most values + asm "mov rcx, rax" + asm "mov rdx, rbx" + asm "mov rdi, 0" + asm "mov rsi, 0" + asm "mov r8, 0" + asm "mov r9, 0" + asm "mov r10, 0" + # do call + asm "call printf" + # there's no more to do 'cause printf returns nothing ;/ /; print_alert _printf(~_alert{0}) ;/ -struct Vector { - uint - el_size, - num_el, - dat_size, - ~uint8 dat -} - -/; method Vector - - /; resize (uint num_el) - self.dat_size = num_el - self.dat = _realloc(self.dat, num_el * self.el_size) - ;/ - - /; get (uint i) [~uint8] - /; if (i !< self.num_el) - return self.dat - ;/ - return self.dat + (i * self.el_size) - ;/ - - /; set (uint i, ~uint8 data) - ~uint8 index = self.get(i) - /; loop (i = 0; i < self.el_size) [i++] - index` = data` - index++ - data++ - ;/ - ;/ - - /; push (~uint8 data) - self.set(self.num_el, data) - self.num_el = self.num_el + 1 - /; if (self.num_el !< self.dat_size) - self.resize(2 * self.dat_size) - ;/ - ;/ - - /; pop - self.num_el = self.num_el - 1 - /; if (self.num_el !== 0 && self.num_el < self.dat_size / 4) - self.resize(self.dat_size / 2) - ;/ - ;/ - - /; remove (int index) - index++ - /; loop (index < self.num_el) [index++] - self.set(index - 1, self.get(index)) - ;/ - self.pop() - ;/ - - /; start (int el_size) - self.num_el = 0 - self.el_size = el_size - self.dat_size = 1 - self.dat = _alloc(self.el_size) - ;/ - - /; clean - self.num_el = 0 - self.el_size = 0 - self.dat_size = 0 - _delete(self.dat) - self.dat = 0 - ;/ -;/ diff --git a/tnslc/proper_calling.tnsl b/tnslc/proper_calling.tnsl deleted file mode 100644 index 6fd5e69..0000000 --- a/tnslc/proper_calling.tnsl +++ /dev/null @@ -1,21 +0,0 @@ -struct CallMe { - int a, b -} - -/; method CallMe - /; call_two (int a, b) [int] - return a + b + self.a + self.b - ;/ - - /; call_four (int a, b, c, d) [int] - return self.call_two(a + b, b * c + d) + self.call_two(a * b + c, c + d) - ;/ - -;/ - -/; main [int] - CallMe cm - cm.a = 0 - cm.b = 0 - return cm.call_four(0, 2, 2, 0) -;/ \ No newline at end of file diff --git a/tnslc/simple.tnsl b/tnslc/simple.tnsl index 49b6db1..29113b7 100644 --- a/tnslc/simple.tnsl +++ b/tnslc/simple.tnsl @@ -1,44 +1,13 @@ {}uint8 str1 = "abcd" -{}uint8 str2 = "abcd" - -/; method Test - /; mamba [int] - return 1 - ;/ - - /; wamba [int] - return self.i + self.j + self.mamba() - ;/ -;/ - -struct Test { - int i, j, k -} /; main (int argc, ~~uint argv) [int] # On windows, the first two arguments are passed in RCX and RDX, so we need to # update their positions here or else tnsl will have garbage values in r8 and r9 asm "mov r8, rcx" asm "mov r9, rdx" - - # If on linux, you would use rdi and rsi instead of rcx and rdx, respectively - # simply comment out the bove asm, and uncomment the below lines - # asm "mov r8, rdi" - # asm "mov r9, rsi" - - Test m - ~int j = ~m.i - ~~int i = ~j - i{0}{1} = 3 - - /; if (argc > 8) - argc = 90 - ;/ - - m.i = argc # return 3 - return m.wamba() + return argc + len str1 ;/ diff --git a/tnslc/syntax-playground.tnsl b/tnslc/syntax-playground.tnsl deleted file mode 100644 index 651be62..0000000 --- a/tnslc/syntax-playground.tnsl +++ /dev/null @@ -1,92 +0,0 @@ -# This file is for playing with syntax and seeing what works and what does not. - - -## TEST 1 - newlines seperate statements, not ; -## newlines can be escaped with \ - -/; test1 - int main = 0 - - /; loop (int i = 0, i < 5) [i++] - tnsl.io.println("Hi!") - ;/ - - String str = {} - - /; loop (char j = ' ', j != 'k') \ - [j++] - - str.append(j) - ;/ - - tnsl.io.println(str) - - return main -;/ - -## END TEST 1 -## -## Thoughts: this is much better. - -## TEST 2 - get '.' augment auto de-references pointers - -struct a { - int i, j -} - -struct b { - String str, - ~a ints -} - -/; ptr_test1 - b str_b = {"Hello", {0, 1}} - - ~b ptr_b = ~str_b - - tnsl.io.println(ptr_b.str) - # vs - tnsl.io.println(ptr_b`.str) - # both work - - ptr_b.ints.i = 12 - ptr_b.ints.j = ptr_b.ints.i / 4 - # vs - ptr_b`.ints`.i = 12 - ptr_b`.ints`.j = ptr_b`.ints`.i / 4 - # Again, the second one is more descriptive, but is it better? - - ptr_call(ptr_b) - ref_call(ptr_b) -;/ - -/; ptr_call (~b ptr) - ptr.ints.i = 8 -;/ - -/; ref_call (b` ref) - ref.ints.j = 9 -;/ - -## END TEST 2 -## -## Thoughts: not sure, the . operator could become a little too ambiguous if this is added - -## Test 3: using [] for array indexing instead of {} - -:include "tnsl" -:using "tnsl" - -/; main ({}String args) [int] - int i = len args - String first = args[0] - - {}int list = {0, 1, 2, 3} - i = list[2] - - return i -;/ - -## End test 3 -## -## Thoughts: I'm not sure weather I like it better or not. diff --git a/tnslc/tests/proper_calling.tnsl b/tnslc/tests/proper_calling.tnsl new file mode 100644 index 0000000..6fd5e69 --- /dev/null +++ b/tnslc/tests/proper_calling.tnsl @@ -0,0 +1,21 @@ +struct CallMe { + int a, b +} + +/; method CallMe + /; call_two (int a, b) [int] + return a + b + self.a + self.b + ;/ + + /; call_four (int a, b, c, d) [int] + return self.call_two(a + b, b * c + d) + self.call_two(a * b + c, c + d) + ;/ + +;/ + +/; main [int] + CallMe cm + cm.a = 0 + cm.b = 0 + return cm.call_four(0, 2, 2, 0) +;/ \ No newline at end of file diff --git a/tnslc/tests/syntax-playground.tnsl b/tnslc/tests/syntax-playground.tnsl new file mode 100644 index 0000000..651be62 --- /dev/null +++ b/tnslc/tests/syntax-playground.tnsl @@ -0,0 +1,92 @@ +# This file is for playing with syntax and seeing what works and what does not. + + +## TEST 1 - newlines seperate statements, not ; +## newlines can be escaped with \ + +/; test1 + int main = 0 + + /; loop (int i = 0, i < 5) [i++] + tnsl.io.println("Hi!") + ;/ + + String str = {} + + /; loop (char j = ' ', j != 'k') \ + [j++] + + str.append(j) + ;/ + + tnsl.io.println(str) + + return main +;/ + +## END TEST 1 +## +## Thoughts: this is much better. + +## TEST 2 - get '.' augment auto de-references pointers + +struct a { + int i, j +} + +struct b { + String str, + ~a ints +} + +/; ptr_test1 + b str_b = {"Hello", {0, 1}} + + ~b ptr_b = ~str_b + + tnsl.io.println(ptr_b.str) + # vs + tnsl.io.println(ptr_b`.str) + # both work + + ptr_b.ints.i = 12 + ptr_b.ints.j = ptr_b.ints.i / 4 + # vs + ptr_b`.ints`.i = 12 + ptr_b`.ints`.j = ptr_b`.ints`.i / 4 + # Again, the second one is more descriptive, but is it better? + + ptr_call(ptr_b) + ref_call(ptr_b) +;/ + +/; ptr_call (~b ptr) + ptr.ints.i = 8 +;/ + +/; ref_call (b` ref) + ref.ints.j = 9 +;/ + +## END TEST 2 +## +## Thoughts: not sure, the . operator could become a little too ambiguous if this is added + +## Test 3: using [] for array indexing instead of {} + +:include "tnsl" +:using "tnsl" + +/; main ({}String args) [int] + int i = len args + String first = args[0] + + {}int list = {0, 1, 2, 3} + i = list[2] + + return i +;/ + +## End test 3 +## +## Thoughts: I'm not sure weather I like it better or not. diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl index 485113d..2695706 100644 --- a/tnslc/tnslc.tnsl +++ b/tnslc/tnslc.tnsl @@ -148,7 +148,7 @@ ;; else if (cmp == 't') ;return '\t' ;; else if (cmp == '0') - ;return '\0' + ;return 0 ;; else if (cmp == '\'') ;return '\'' ;/ @@ -260,6 +260,20 @@ ;return out ;/ +/; string_to_csb ({}uint8 str) [{}uint8] + ;{}uint8 out = "" + + /; loop (int i = 0; i < len str) [i++] + ;out = string_add(out, int_to_string(str{i})) + /; if (i < len str - 1) + ;out.append(',') + ;out.append(' ') + ;/ + ;/ + + ;return out +;/ + ## ## Structs ## @@ -388,13 +402,13 @@ "~=", "`=", "%=", "^=", "&=", "*=", "!=", "|=", "/=", - "<<", ">>", "!&", "!|", "!^" + "<<", ">>", "!&", "!|", "!^", + + "len", "is" } ;{}{}uint8 KEYWORDS = { - "len", - "is", "if", "else", @@ -535,19 +549,15 @@ /; gen_type (Token t) [int] /; if (is_separator(t.data)) ;return TOKEN.SEPARATOR - ;/ - - /; if (is_literal(t.data)) + ;; else if (is_literal(t.data)) ;return TOKEN.LITERAL + ;; else if (is_delimiter(t.data)) + ;return TOKEN.DELIMITER + ;; else if (is_augment(t.data)) + ;return TOKEN.AUGMENT ;/ - /; if (is_reserved(t.data)) - /; if (is_delimiter(t.data)) - ;return TOKEN.DELIMITER - ;; else if (is_augment(t.data)) - ;return TOKEN.AUGMENT - ;/ - ;; else if (list_contains(KEYWORDS, t.data)) + /; if (list_contains(KEYWORDS, t.data)) ;return TOKEN.KEYWORD ;; else if (list_contains(KEYTYPES, t.data)) ;return TOKEN.KEYTYPE @@ -1409,7 +1419,7 @@ ;/ /; index (Variable i, ~CompData data) [Variable] - ;int sz = self.el_size() + ;int sz = self.el_size() ;log_debug(string_add("Index starting: ", self.sprint())) ;Variable out = self.strip_refs(data) @@ -1420,7 +1430,7 @@ ;/ ;Variable ind = {"#index", {8, "void", {PTYPE.POINTER}, {}, 0}, 3, LOCATION.REGISTER} - ;ind.set(i, data) + ;ind.set(i, data) ;ind.mul({"#mul", {8, "uint", {}, {}, 0}, sz, LOCATION.LITERAL}, data) /; if (out.is_ref()) @@ -1445,7 +1455,7 @@ ;/ /; length_of (Variable a, ~CompData data) - ;a = a.strip_refs() + ;a = a.strip_refs(data) ;a.data_type.name = "uint" ;a.data_type.s = 8 ;a.data_type.ptr_chain = {PTYPE.REFERENCE} @@ -2432,9 +2442,10 @@ ;/ /; if (tok`{cur`}.data{0} == '"') + ;{}uint8 data = unquote_str(tok`{cur`}.data) ;return string_join({ - declare_size(8), int_to_string(len unquote_str(tok`{cur`}.data)), "\n", - declare_size(1), tok`{cur`}.data, "\n"}, "") + declare_size(8), int_to_string(len data), "\n", + declare_size(1), string_to_csb(data), "\n"}, "") ;; else if (tok`{cur`}.data{0} == '\'') ;return string_join({ declare_size(1), tok`{cur`}.data, "\n"}, "") @@ -2581,7 +2592,7 @@ # Priority # 0 - deref # 1 - get -# 2 - ref +# 2 - ref, len # 3 - inc/dec # 4 - mul/div/mod # 5 - add/sub @@ -2596,6 +2607,8 @@ /; if (tok.cmp(".")) ;return 1 + ;; else if (tok.cmp("len")) + ;return 2 ;; else if (len (tok.data) == 1) /; if (tok.cmp("`")) ;return 0 @@ -2864,7 +2877,8 @@ ;/ ;; else if (tok`{start`}.cmp("{")) ;log_debug("Index!") - ;Variable i = _eval_value(tok, start` + 1, find_closing(tok, start), out, mov, current, scope, t, layer) + ;Type ut = {8, "uint", {}, {}, 0} + ;Variable i = _eval_value(tok, start` + 1, find_closing(tok, start), out, mov, current, scope, ut, layer) ;log_debug(i.sprint()) ;wk = wk.index(i, out) ;log_debug(wk.sprint()) @@ -2938,7 +2952,7 @@ out`.dsec, l, ":\n", declare_size(8), int_to_string(len unquote_str(data)), "\n", - declare_size(1), data, "\n"} + declare_size(1), string_to_csb(unquote_str(data)), "\n"} , "") ;v.data_type = {1, "uint8", "", {POINTER.ARRAY}, {}} ;v.loc_type = LOCATION.LABEL @@ -3092,6 +3106,9 @@ /; if (tok`{first}.cmp("=")) ;s1.set(s2, out) ;return s1 + ;; if (tok`{first}.cmp("++") || tok`{first}.cmp("--")) + ;t = s1.data_type + ;t.strip_refs() ;/ ;Variable wk = {"#wk", t, 1, LOCATION.REGISTER} @@ -3107,8 +3124,6 @@ # Inc and dec /; if (tok`{first}.cmp("++") || tok`{first}.cmp("--")) - ;wk.data_type = s1.data_type - ;wk.data_type.strip_refs() ;wk.set(s1, out) /; if (tok`{first}.cmp("++")) @@ -3184,6 +3199,8 @@ ;wk.ref(s1, out) ;; else if (tok`{first}.cmp("!")) ;wk.not(s1, out) + ;; else if (tok`{first}.cmp("len")) + ;wk.length_of(s1, out) ;/ ;return wk diff --git a/tnslc/tnslc_wrapped.tnsl b/tnslc/tnslc_wrapped.tnsl index f93c3c4..bfb41cc 100644 --- a/tnslc/tnslc_wrapped.tnsl +++ b/tnslc/tnslc_wrapped.tnsl @@ -1,4 +1,5 @@ :include "c_wrap.tnsl" +:include "vector.tnsl" /; main (int argc, ~~uint argv) [int] # On windows, the first two arguments are passed in RCX and RDX, so we need to @@ -13,14 +14,15 @@ Vector vec vec.start(1) - uint8 a = 97 - vec.push(~a) + uint8 a = _alert{0} vec.push(~a) vec.push(~a) + a = _alert{len _alert - 2} vec.push(~a) a = 0 vec.push(~a) - _printf(vec.dat) + _printf(vec.get(0)) + _printf(vec.get(0)) vec.clean() - return a + return 0 ;/ \ No newline at end of file diff --git a/tnslc/vector.tnsl b/tnslc/vector.tnsl new file mode 100644 index 0000000..ecb52e1 --- /dev/null +++ b/tnslc/vector.tnsl @@ -0,0 +1,69 @@ +struct Vector { + uint + el_size, + num_el, + dat_size, + ~uint8 dat +} + +/; method Vector + + /; resize (uint num_el) + self.dat_size = num_el + self.dat = _realloc(self.dat, num_el * self.el_size) + ;/ + + /; get (uint i) [~uint8] + /; if (i !< self.num_el) + return self.dat + ;/ + return self.dat + (i * self.el_size) + ;/ + + /; set (uint i, ~uint8 data) + ~uint8 index = self.get(i) + /; loop (i = 0; i < self.el_size) [i++] + index` = data` + index++ + data++ + ;/ + ;/ + + /; push (~uint8 data) + self.num_el++ + self.set(self.num_el - 1, data) + /; if (self.num_el !< self.dat_size) + self.resize(2 * self.dat_size) + ;/ + ;/ + + /; pop + self.num_el-- + /; if (self.num_el !== 0 && self.num_el < self.dat_size / 4) + self.resize(self.dat_size / 2) + ;/ + ;/ + + /; remove (int index) + index++ + /; loop (index < self.num_el) [index++] + self.set(index - 1, self.get(index)) + ;/ + self.pop() + ;/ + + /; start (int el_size) + self.num_el = 0 + self.el_size = el_size + self.dat_size = 1 + self.dat = _alloc(self.el_size) + ;/ + + /; clean + self.num_el = 0 + self.el_size = 0 + self.dat_size = 0 + _delete(self.dat) + self.dat = 0 + ;/ +;/ -- cgit v1.2.3