summaryrefslogtreecommitdiff
path: root/tnslc/tnslc.tnsl
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2023-03-23 01:03:28 -0400
committerKyle Gunger <kgunger12@gmail.com>2023-03-23 01:03:28 -0400
commit9066d5215225a32865cb628dad1c69997efffe62 (patch)
tree9a14a6445d0fd22013f944957ce41be9cd3c5f6d /tnslc/tnslc.tnsl
parent4611b333202bb548d0566e31cf97733deeeca158 (diff)
Simple if and loop statements
Diffstat (limited to 'tnslc/tnslc.tnsl')
-rw-r--r--tnslc/tnslc.tnsl307
1 files changed, 216 insertions, 91 deletions
diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl
index 12abbec..1054d7b 100644
--- a/tnslc/tnslc.tnsl
+++ b/tnslc/tnslc.tnsl
@@ -304,16 +304,6 @@
;return string_add(out, self.name)
;/
- /; extension [{}uint8]
- ;{}{}uint8 split_name = string_split(self.name, '.')
-
- /; if (len split_name > 1)
- ;return split_name{len split_name - 1}
- ;/
-
- ;return ""
- ;/
-
/; open_read [tnsl.io.File]
;return tnsl.io.readFile(self.full_path())
;/
@@ -568,8 +558,42 @@
;return out
;/
+/; to_jmp({}uint8 cmp) [{}uint8]
+ /; if (string_equate(cmp, "=="))
+ ;return "\tje "
+ ;; else if (string_equate(cmp, "!=="))
+ ;return "\tjne "
+ ;; else if (string_equate(cmp, "!<") || string_equate(cmp, ">=="))
+ ;return "\tjge "
+ ;; else if (string_equate(cmp, "!>") || string_equate(cmp, "<=="))
+ ;return "\tjle "
+ ;; else if (string_equate(cmp, ">"))
+ ;return "\tjg "
+ ;; else if (string_equate(cmp, "<"))
+ ;return "\tjl "
+ ;/
+ ;return "\tjnz "
+;/
+
+/; not_jmp({}uint8 cmp) [{}uint8]
+ /; if (string_equate(cmp, "=="))
+ ;return "\tjne "
+ ;; else if (string_equate(cmp, "!=="))
+ ;return "\tje "
+ ;; else if (string_equate(cmp, "!<") || string_equate(cmp, ">=="))
+ ;return "\tjl "
+ ;; else if (string_equate(cmp, "!>") || string_equate(cmp, "<=="))
+ ;return "\tjg "
+ ;; else if (string_equate(cmp, ">"))
+ ;return "\tjle "
+ ;; else if (string_equate(cmp, "<"))
+ ;return "\tjge "
+ ;/
+ ;return "\tjz "
+;/
+
# Methods on variables assume that the rax, rdx, rsi, and rdi registers are fair game.
-#
+# ONLY USES RDI ON SOME ASSIGNMENTS. SAFE FOR BOOLEAN STORAGE
/; method Variable
/; sprint [{}uint8]
@@ -611,8 +635,30 @@
/; match_types (Variable to_match, ~CompData data) [Variable]
/; if (to_match.loc_type == LOCATION.LITERAL)
;return to_match
+ ;; if (!(to_match.is_prim()) || (len(to_match.data_type.ptr_chain) > 0 && !(to_match.is_ref())))
+ ;return to_match
+ ;/
+
+ ;Variable out = {"#match", self.data_type, 4, LOCATION.REGISTER}
+ ;{}uint8 mov = "mov"
+
+ /; if (self.data_type.name{0} == 'i' && out.norm_size() > to_match.norm_size())
+ ;mov = string_add(mov, "sx")
+ /; if (out.norm_size() == 8 && to_match.norm_size() == 4)
+ ;mov.append('d')
+ ;/
+ ;; else if (self.data_type.name{0} == 'u' && out.norm_size() > to_match.norm_size() && out.norm_size() !== 8)
+ ;mov = string_add(mov, "zx")
+ ;; else
+ ;return to_match
;/
- ;return to_match
+
+ ;data`.csec = string_join( {
+ data`.csec,
+ "\t", mov, " ", out.norm_loc(out.norm_size()), ", ", to_match.norm_loc(to_match.norm_size()), "\n"
+ }, "")
+
+ ;return out
;/
/; norm_op ({}uint8 op, int sz, Variable v, ~CompData data)
@@ -728,7 +774,7 @@
;self.location = !v.location
;; else if (string_equate(v.data_type.name, "bool") && len (v.data_type.ptr_chain) == 0)
- ;self.xor({"#literal", get_primitive(is_primitive("bool")), 1, LOCATION.LITERAL}, data)
+ ;self.xor(literal_variable("true", "", data), data)
;; else
;v = self.match_types(v, data)
;self.set(v, data)
@@ -746,8 +792,8 @@
;; else
;self.location = 0
;/
- ;; else
- ;self.norm_op("add", self.norm_size(), v, data)
+ ;; else if (v.is_prim() && self.is_prim())
+ ;self.norm_op("cmp", self.norm_size(), v, data)
;/
;/
@@ -871,8 +917,25 @@
;/
;/
+ # Only to be called from a boolean variable
+ /; bool_from (Variable v, ~CompData data, {}uint8 landing_pad)
+ ;int sz = v.norm_size()
+ ;data`.csec = string_join( {
+ data`.csec,
+ "\tmov ", get_reg(4, sz), ", ", v.norm_loc(sz), "\n",
+ "\ttest ", get_reg(4, sz), ", ", get_reg(4, sz), "\n",
+ "\tmov ", self.norm_loc(1), ", 1\n",
+ "\tjnz ", skip_pad, "\n",
+ "\tmov ", self.norm_loc(1), ", 0\n",
+ landing_pad, ":\n"
+ }, "")
+ ;/
+
/; move_register (int new_reg, ~CompData data)
;int sz = self.norm_size()
+ /; if (self.is_ref())
+ ;sz = 8
+ ;/
;data`.csec = string_join( {
data`.csec,
"\tmov ", get_reg(new_reg, sz), ", ", get_reg(self.location, sz), "\n"
@@ -945,12 +1008,12 @@
}, "")
;/
- ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 5, LOCATION.REGISTER}
+ ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 0, LOCATION.REGISTER}
;t.set({"#literal", t.data_type, sz, LOCATION.LITERAL}, data)
;t.mul(i, data)
;data`.csec = string_join( {
data`.csec,
- "\tadd rsi, rdi\n"
+ "\tadd rsi, rax\n"
}, "")
/; if (out.is_ref())
@@ -1257,10 +1320,7 @@
;/
/; next_const [{}uint8]
- /; if (self.is_cf())
- ;return self.parent`.next_const()
- ;/
- ;{}uint8 out = string_add(self.name, string_add("#const_", int_to_string(self.c)))
+ ;{}uint8 out = string_add(self.full_label(), string_add("#const_", int_to_string(self.c)))
;self.c++
;return out
;/
@@ -1870,8 +1930,9 @@
# 3 - mul/div/mod
# 4 - add/sub
# 5 - bitwise
-# 6 - boolean
-# 7 - assignment
+# 6 - boolean cmp
+# 7 - boolean logic
+# 8 - assignment
/; priority (Token tok) [int]
/; if (!(tok.type_is(TOKEN.AUGMENT)))
;return -1
@@ -1893,16 +1954,18 @@
;; else if (tok.cmp("<") || tok.cmp(">"))
;return 6
;; else if (tok.cmp("="))
- ;return 7
+ ;return 8
;/
;; else if (len (tok.data) == 2)
/; if (tok.data{0} == tok.data{1})
/; if (tok.data{0} == '<' || tok.data{0} == '>')
;return 5
+ ;; else if (tok.data{0} == '=')
+ ;return 6
;/
- ;return 6
- ;; else if (tok.data{1} == '=')
;return 7
+ ;; else if (tok.data{1} == '=')
+ ;return 8
;; else if (tok.data{1} == '<' || tok.data{1} == '>')
;return 6
;/
@@ -2121,19 +2184,6 @@
;/
;/
- # TODO: Boolean logic
- /; if (pr == 6)
- # create a boolean scope
- /; if (!scope.is_cf() || !scope.cf_type("bool"))
- ;Scope bsc = scope`.new_sub_cf("bool")
- ;scope = ~bsc
- # do some kinda boolean magic
- # create an end clause as a landing pad for the result
- ;; else
- # boolean magic but without the end clause
- ;/
- ;/
-
# This is all kinda garbage, to fix.
/; if (is_call(tok, start))
;log_debug("Attempt to invoke a call")
@@ -2173,6 +2223,28 @@
;wk.location = 2
;/
+ # TODO: Boolean logic
+ /; if (pr == 6)
+ ;wk.set(s1, out)
+ ;wk.cmp(s2, out)
+ ;wk.data_type = {1, "bool", "_bool", {}, {}}
+
+ ;wk.set(literal_variable("true", "", out), out)
+ ;{}uint8 l = scope`.next_const()
+ # ;log_debug(l)
+ ;out`.csec = string_join( {
+ out`.csec,
+ to_jmp(tok`{first}.data), l, "\n"
+ }, "")
+ ;wk.set(literal_variable("false", "", out), out)
+ ;out`.csec = string_join( {
+ out`.csec,
+ l, ":\n"
+ }, "")
+
+ ;return wk
+ ;/
+
/; if (tok`{first}.cmp("+"))
;wk.set(s1, out)
;wk.add(s2, out)
@@ -2226,14 +2298,13 @@
;end = find_closing(tok, ~end)
;/
;/
-
;Variable val = _eval_value(tok, cur`, end, out, mov, current, scope, t, false)
+ ;cur` = end
/; if (save)
;Variable set = {"#tmp", t, 0, LOCATION.REGISTER}
;set.set(val, out)
;return val
;/
- ;cur` = end
;return { "", NO_TYPE, 0, 0 }
;/
@@ -2255,7 +2326,7 @@
;int i = start
/; loop (i < max) [i++]
/; if (tok`{i}.type_is(TOKEN.AUGMENT))
- /; if (priority(tok`{i}) == 6)
+ /; if (priority(tok`{i}) == 6 || priority(tok`{i}) == 7)
;return true
;/
;; else if (tok`{i}.type_is(TOKEN.LITERAL))
@@ -2282,47 +2353,53 @@
;/
-/; statement_list(~{}Token tok, int start, end, ~Module current, ~CompData out, mov, ~Scope parent) [CompData]
+/; statement_list(~{}Token tok, int start, end, ~Module current, ~CompData out, mov, ~Scope parent) [{}uint8]
;log_debug("Statement list!")
- ;bool b = false
+ ;int b = -1
;CompData carry = {"", "", ""}
- /; loop (start = next_non_nl(tok, start + 1); start < end) [start = next_non_nl(tok, start + 1)]
+ ;int s = next_non_nl(tok, start + 1)
+ /; loop (s < end) [s = next_non_nl(tok, s + 1)]
;out`.add(carry)
;carry = {"", "", ""}
- ;b = false
- /; if (is_definition(tok, ~start, current))
+ ;b = -1
+ /; if (is_definition(tok, ~s, current))
+
;log_debug("Block def")
- ;eval_def(tok, ~start, out, mov, current, parent)
+ ;eval_def(tok, ~s, out, mov, current, parent)
;; else
;log_debug("Block val")
- ;b = is_bool_statement(tok, start, end, current, parent)
+ /; if (is_bool_statement(tok, s, end, current, parent))
+ ;b = s
+ ;/
;Type t = NO_TYPE
- /; if (b)
+ /; if (b !< 0)
;t = {1, "bool", "_bool", {}, {}}
+ ;log_debug("Boolish")
;/
- ;eval_value(tok, ~start, carry, mov, current, parent, t, b)
+ ;eval_value(tok, ~s, out, mov, current, parent, t, b)
;/
;/
- ;out`.add(carry)
- /; if (!b)
- ;carry = {"", "", ""}
+
+ ;{}uint str = ""
+
+ /; if (b > 0)
+ ;str = int_to_string(b)
;/
- ;return carry
+ ;return str
;/
# FIXME:
# Need to impl:
# cf block scoping and contextual keywords such as
# continue, break, and return
-/; _compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out, mov, ~Scope parent)
+/; _compile_block (~{}Token tok, ~int cur, ~Module current, ~CompData out, mov, ~Scope parent, Type ret)
;int max = find_closing(tok, cur)
;Scope cf = parent`.new_sub_cf("wrap")
- ;CompData prelude = {"", "", ""}
- ;out`.csec = string_join( {
- out`.csec,
- cf.scope_start_label(), ":\n"
- }, "")
+
+ ;CompData outro = {"", "", ""}
+ ;{}uint8 condition = ""
+
/; loop (cur`++; cur` < max) [cur`++]
/; if (tok`{cur`}.type_is(TOKEN.KEYWORD))
/; if (tok`{cur` + 1}.cmp("if"))
@@ -2334,34 +2411,48 @@
;; else if (tok`{cur`}.cmp("(") || tok`{cur`}.cmp("["))
;int psl = find_closing(tok, cur)
/; if (tok`{cur`}.cmp("["))
- ;out`.csec = string_join( {
- out`.csec,
- cf.scope_end_label(), ":\n"
- }, "")
- ;CompData tmp = statement_list(tok, cur`, psl, current, out, mov, ~cf)
- /; if (len (tmp.csec) == 0 && cf.cf_type("loop"))
- ;out`.csec = string_add(out`.csec, prelude.csec)
+ ;outro.csec = string_add(cf.scope_rep_label(), ":\n")
+ ;{}uint8 tmp = statement_list(tok, cur`, psl, current, ~outro, mov, ~cf)
+
+ /; if (cf.cf_type("loop"))
+ /; if (len (tmp) == 0 && len (condition) > 0)
+ /; if (len (condition) > 0)
+ ;int tmps = string_to_int(condition)
+ ;eval_value(tok, ~tmps, ~outro, mov, current, ~cf, {1, "bool", "", {}, {}}, true)
+ ;; else
+ ;outro.csec = string_join( {
+ outro.csec,
+ "\tjmp ", cf.scope_start_label(), "\n"
+ }, "")
+ ;/
+ ;/
+
+ /; if (len (tmp) > 0 || len(condition) > 0)
+ ;outro.csec = string_join( {
+ outro.csec,
+ "\ttest al, al\n",
+ "\tjnz ", cf.scope_start_label(), "\n",
+ "\tjmp ", cf.scope_end_label(), "\n"
+ }, "")
+ ;/
;/
- /; if (cf.is_cf())
+ ;; else
+ ;condition = statement_list(tok, cur`, psl, current, out, mov, ~cf)
+ /; if (len (condition) == 0)
;out`.csec = string_join( {
out`.csec,
- "\tjmp ", cf.parent`.scope_end_label(), "\n"
+ "\tjmp ", cf.scope_start_label(), "\n"
}, "")
- ;/
- ;; else
- ;out`.csec = string_join( {
- out`.csec,
- cf.scope_start_label(), ":\n"
- }, "")
- ;prelude = statement_list(tok, cur`, psl, current, out, mov, ~cf)
- /; if (len (prelude.csec) == 0)
- ;prelude.csec = string_join( {
- "\tjmp ", cf.scope_rep_label(), "\n"
+ ;; else
+ ;out`.csec = string_join( {
+ out`.csec,
+ "\ttest al, al\n",
+ "\tjnz ", cf.scope_start_label(), "\n",
+ "\tjmp ", cf.scope_end_label(), "\n"
}, "")
- ;out`.csec = string_add(out`.csec, prelude.csec)
;/
;/
- ;cur` = ps1
+ ;cur` = psl
;; else
;break
;/
@@ -2369,7 +2460,7 @@
;out`.csec = string_join( {
out`.csec,
- cf.scope_rep_label(), ":\n"
+ cf.scope_start_label(), ":\n"
}, "")
/; if (tok`{cur`}.cmp("\n"))
@@ -2380,7 +2471,7 @@
/; loop (cur` < max && !returned) [cur` = next_non_nl(tok, cur` + 1)]
/; if (tok`{cur`}.cmp("/;") || tok`{cur`}.cmp(";;"))
;log_debug("Block in block")
- ;_compile_block(tok, cur, current, out, mov, ~cf)
+ ;_compile_block(tok, cur, current, out, mov, ~cf, ret)
/; if (tok`{cur`}.cmp(";;"))
;cur` = cur` - 1
@@ -2388,7 +2479,7 @@
;; else if (tok`{cur`}.type_is(TOKEN.KEYWORD))
/; if (tok`{cur`}.cmp("return"))
;cur`++
- ;eval_value(tok, cur, out, ~mov, current, ~cf, ret, true)
+ ;eval_value(tok, cur, out, mov, current, ~cf, ret, true)
;cf.end_scope(out)
;out`.csec = string_add(out`.csec, "\tret\n")
;returned = true
@@ -2397,7 +2488,7 @@
;log_err("Unable to perform a raw return from a non-raw block.")
;/
;cur` = cur` + 2
- ;eval_value(tok, cur, out, ~mov, current, ~root, ret, true)
+ ;eval_value(tok, cur, out, mov, current, ~cf, ret, true)
;out`.csec = string_add(out`.csec, "\tret\n")
;returned = true
;; else if (tok`{cur`}.cmp("asm"))
@@ -2410,12 +2501,45 @@
;/
;; else if (is_definition(tok, cur, current))
;log_debug("Block def")
- ;eval_def(tok, cur, out, mov, current, ~root)
+ ;eval_def(tok, cur, out, mov, current, ~cf)
;; else
;log_debug("Block val")
- ;eval_value(tok, cur, out, mov, current, ~root, NO_TYPE, false)
+ ;eval_value(tok, cur, out, mov, current, ~cf, NO_TYPE, false)
;/
;/
+ ;log_debug("Passing gauntlet 2")
+
+ /; if (len (outro.csec) > 0)
+ ;out`.add(outro)
+ ;; else
+ ;out`.csec = string_join( {
+ out`.csec,
+ cf.scope_rep_label(), ":\n"
+ }, "")
+
+ /; if (cf.cf_type("loop"))
+ /; if (len (condition) > 0)
+ ;int tmps = string_to_int(condition)
+ ;eval_value(tok, ~tmps, out, mov, current, ~cf, {1, "bool", "", {}, {}}, true)
+ ;out`.csec = string_join( {
+ out`.csec,
+ "\ttest al, al\n",
+ "\tjnz ", cf.scope_start_label(), "\n",
+ "\tjmp ", cf.scope_end_label(), "\n"
+ }, "")
+ ;; else
+ ;out`.csec = string_join( {
+ out`.csec,
+ "\tjmp ", cf.scope_start_label(), "\n"
+ }, "")
+ ;/
+ ;/
+ ;/
+
+ ;out`.csec = string_join( {
+ out`.csec,
+ cf.scope_end_label(), ":\n"
+ }, "")
/; if (cf.is_cf())
;out`.csec = string_join( {
@@ -2481,10 +2605,11 @@
;; else
;CompData mov = {"", "", ""}, tmp = {"", "", ""}
;log_debug("PRE COMPUTATION OF BLOCK\n")
- ;_compile_block(tok, cur, current, ~tmp, ~mov, ~root)
+ ;int tcr = cur`
+ ;_compile_block(tok, ~tcr, current, ~tmp, ~mov, ~root, ret)
;out`.add(mov)
;log_debug("POST COMPUTATION OF BLOCK")
- ;_compile_block(tok, cur, current, out, ~tmp, ~root)
+ ;_compile_block(tok, cur, current, out, ~tmp, ~root, ret)
;/
/; if (tok`{cur`}.cmp(";;"))
@@ -2765,7 +2890,7 @@
;{}uint8 PARENS = "()[]{}"
;{}uint8 SEPS = "\n;:,"
;{}uint8 RESERVED = "`~!%^&*()-+=[]{}|;:/?<>.,\""
-;{}uint8 AUGMENTS = "=~!<>&|^+-*/`."
+;{}uint8 AUGMENTS = "=~!<>&|^+-*/%`."
;{}{}uint8 MULTI_AUGMENTS = {
"~=", "`=", "%=", "^=", "&=", "*=",