summaryrefslogtreecommitdiff
path: root/tnslc/tnslc.tnsl
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2023-03-18 17:16:50 -0400
committerKyle Gunger <kgunger12@gmail.com>2023-03-18 17:16:50 -0400
commitd21c66af96878e5efff081ec861af4350d37bffe (patch)
tree9e01632266a4f83095da33f1c602c109e3af26fc /tnslc/tnslc.tnsl
parentf51b86ff3cf980fa558dfafd24ffd4a327e0890b (diff)
Reference and dereference
Diffstat (limited to 'tnslc/tnslc.tnsl')
-rw-r--r--tnslc/tnslc.tnsl316
1 files changed, 217 insertions, 99 deletions
diff --git a/tnslc/tnslc.tnsl b/tnslc/tnslc.tnsl
index 20a7ef3..582afbd 100644
--- a/tnslc/tnslc.tnsl
+++ b/tnslc/tnslc.tnsl
@@ -1,4 +1,32 @@
##
+## LOG UTILITIES
+##
+
+;{}uint8 log_level = "2"
+
+/; log_err ({}uint8 msg)
+ ;tnsl.io.print("\n[TNSLC] [ERR]: ")
+ ;tnsl.io.println(msg)
+ ;tnsl.exit()
+;/
+
+/; log_info ({}uint8 msg)
+ ;uint l = string_to_int(log_level)
+ /; if (l > 0)
+ ;tnsl.io.print("\n[TNSLC] [INFO]: ")
+ ;tnsl.io.println(msg)
+ ;/
+;/
+
+/; log_debug ({}uint8 msg)
+ ;uint l = string_to_int(log_level)
+ /; if (l > 1)
+ ;tnsl.io.print("\n[TNSLC] [DEBUG]: ")
+ ;tnsl.io.println(msg)
+ ;/
+;/
+
+##
## UTIL FUNCS
##
@@ -350,6 +378,20 @@
members
}
+/; method Type
+ /; sprint [{}uint8]
+ ;log_debug("Sprinting Type")
+ ;{}uint8 out = string_join( {"{ ", int_to_string(self.s), ", ", self.name, ", ", self.mod_name, ", { "}, "")
+ ;{}{}uint8 pch = {}
+ /; loop (int i = 0; i < len(self.ptr_chain)) [i++]
+ ;pch.append(int_to_string(self.ptr_chain{i}))
+ ;/
+ ;out = string_add(out, string_join(pch, ", "))
+ ;out = string_add(out, " } }")
+ ;return out
+ ;/
+;/
+
;{}{}uint8 PRIM_NAMES = {
"uint8", "uint16", "uint32", "uint64", "uint",
"int8", "int16", "int32", "int64", "int",
@@ -485,18 +527,24 @@
;return string_join( {pre, "[", str, offset, "]" }, "")
;/
-/; strip_one({}int p) [{}int]
+/; strip_int({}int p) [{}int]
;{}int out = {}
- /; loop (int i = 0; i < len p) [i++]
+ /; loop (int i = 0; i < len p - 1) [i++]
;out.append(p{i})
;/
;return out
;/
-# Methods assume that the rax, rdx, rsi, and rdi registers are fair game.
+# Methods on variables assume that the rax, rdx, rsi, and rdi registers are fair game.
#
/; method Variable
+ /; sprint [{}uint8]
+ ;return string_join( {
+ "{ ", self.name, ", ", self.data_type.sprint(), ", ", int_to_string(self.location), ", ", int_to_string(self.loc_type), " }"
+ },"")
+ ;/
+
/; norm_loc (int sz) [{}uint8]
/; if (self.loc_type == LOCATION.LABEL)
;return loc_from_str(string_add("rel ", self.name), string_add(" + ", int_to_string(self.location)), sz)
@@ -513,11 +561,16 @@
;/
/; norm_size [int]
- /; if (len (self.data_type.ptr_chain) > 0)
+ /; if (len (self.data_type.ptr_chain) > 1)
;return 8
- ;; else
+ ;; else if (len (self.data_type.ptr_chain) == 0)
;return self.data_type.s
;/
+
+ /; if (self.data_type.ptr_chain{0} == PTYPE.REFERENCE)
+ ;return self.data_type.s
+ ;/
+ ;return 8
;/
# TODO: Match a type to another type if possible
@@ -554,29 +607,41 @@
;return false
;/
- /; strip_refs (Variable to_strip, ~CompData data) [Variable]
- ;int pc = len (self.data_type.ptr_chain)
-
+ /; strip_one (~CompData data)
;data`.csec = string_join( {
data`.csec,
- "\tmov rsi, ", to_strip.norm_loc(8), "\n"
+ "\tmov rsi, [rsi]\n"
}, "")
- ;to_strip.loc_type = LOCATION.REGISTER
- ;to_strip.location = 4
+ ;self.data_type.ptr_chain = strip_int(self.data_type.ptr_chain)
+ ;/
- /; loop (pc > 1) [pc = len (to_strip.data_type.ptr_chain)]
- /; if (to_strip.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE && to_strip.data_type.ptr_chain{pc - 2} == PTYPE.REFERENCE)
- ;data`.csec = string_join( {
- data`.csec,
- "\tmov rsi, [rsi]\n"
- }, "")
- ;to_strip.data_type.ptr_chain = strip_one(to_strip.data_type.ptr_chain)
+ /; strip_refs (~CompData data) [Variable]
+ ;int pc = len (self.data_type.ptr_chain)
+
+ /; if (self.loc_type == LOCATION.REGISTER)
+ ;data`.csec = string_join( {
+ data`.csec,
+ "\tmov rsi, ", get_reg(self.location, 8), "\n"
+ }, "")
+ ;; else
+ ;data`.csec = string_join( {
+ data`.csec,
+ "\tmov rsi, ", self.norm_loc(8), "\n"
+ }, "")
+ ;/
+ ;Variable out = {"#ref", self.data_type, 4, LOCATION.REGISTER}
+
+ /; loop (pc > 1) [pc = len (out.data_type.ptr_chain)]
+ /; if (out.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE)
+ ;log_debug("Stripping")
+ ;out.strip_one(data)
;; else
+ ;log_debug("Breaking")
;break
;/
;/
-
- ;return to_strip
+ ;log_debug("Strip complete")
+ ;return out
;/
# functions that do work on this variable
@@ -739,10 +804,19 @@
;/
;/
+ /; move_register (int new_reg, ~CompData data)
+ ;int sz = self.norm_size()
+ ;data`.csec = string_join( {
+ data`.csec,
+ "\tmov ", get_reg(new_reg, sz), ", ", get_reg(self.location, sz), "\n"
+ }, "")
+ ;/
+
/; ref (Variable to_ref, ~CompData data)
;int l = len (to_ref.data_type.ptr_chain)
/; if (l > 0)
/; if (to_ref.data_type.ptr_chain{l - 1} == PTYPE.REFERENCE)
+ ;to_ref.data_type.ptr_chain{l - 1} = PTYPE.POINTER
;self.set(to_ref, data)
;; else
;data`.csec = string_join( {
@@ -760,46 +834,18 @@
;/
;/
- /; deref (Variable to_deref, ~CompData data)
- ;to_deref = self.strip_refs(to_deref, data)
- ;int dpc = len (to_deref.data_type.ptr_chain)
- ;int spc = len (self.data_type.ptr_chain)
- /; if (dpc == 0)
- ;tnsl.io.println("Can not deref a variable that is not a pointer (ERR: ONPTRC)")
- ;tnsl.quit
- ;; else if (spc == 0)
- ;tnsl.io.println("Can not deref into a variable that is not a reference (ERR: SNPTRC)")
- ;tnsl.quit
+ /; deref (~CompData data) [Variable]
+ ;Variable out = self.strip_refs(data)
+ ;int opc = len (out.data_type.ptr_chain)
+ /; if (opc == 0)
+ ;log_err("Can not deref a variable that is not a pointer (ERR: SNPTRC)")
;/
-
- ;data`.csec = string_join( {
- data`.csec,
- "\tmov rsi, ", to_deref.norm_loc(8), "\n",
- "\tmov ", self.norm_loc(8), ", rsi\n"
- }, "")
- ;/
-
- # for use on tmp variables or in a dotchain
- /; deref_self (~CompData data)
- ;int pc = len (self.data_type.ptr_chain)
- /; if (pc == 0)
- ;tnsl.io.println("Can not self_deref into a variable that is not a reference (ERR: SNPTRC)")
- ;tnsl.quit
- ;; else if (pc > 1 && self.data_type.ptr_chain{pc - 1} == PTYPE.REFERENCE)
- ;data`.csec = string_join( {
- data`.csec,
- "\tmov rsi, ", self.norm_loc(8), "\n",
- "\tmov ", self.norm_loc(8), ", [rsi]\n"
- }, "")
- ;self.data_type.ptr_chain = strip_one(self.data_type.ptr_chain)
- ;pc = pc - 1
- ;/
-
- ;self.data_type.ptr_chain{pc - 1} = PTYPE.REFERENCE
+ ;out.data_type.ptr_chain{opc - 1} = PTYPE.REFERENCE
+ ;return out
;/
/; member (Variable s, ~CompData data, {}uint8 name)
- ;tnsl.io.println("member")
+ ;log_debug("member")
;int accum = 0
;self.data_type.name = ""
;int i = 0
@@ -831,21 +877,12 @@
;/
;/
- /; index (Variable a, ~CompData data, Variable i)
- /; if (a.loc_type == LOCATION.REGISTER)
- ;data`.csec = string_join( {
- data`.csec,
- "\tlea rsi, ", a.norm_loc(8), "\n"
- }, "")
- ;; else
- ;data`.csec = string_join( {
- data`.csec,
- "\tmov rsi, ", a.norm_loc(8), "\n"
- }, "")
- ;/
+ /; index (Variable i, ~CompData data) [Variable]
+ ;Variable out = self.strip_refs(data)
- ;int sz = self.norm_size()
- ;bool ts_arr = a.data_type.ptr_chain{0} == PTYPE.ARRAY
+ ;int sz = out.norm_size()
+ ;int opc = len (out.data_type.ptr_chain)
+ ;bool ts_arr = out.data_type.ptr_chain{opc - 1} == PTYPE.ARRAY
;Variable t = {"#tmp", a.data_type, 4, LOCATION.REGISTER}
/; if (ts_arr)
@@ -874,13 +911,14 @@
}, "")
;/
- ;self.deref(t, data)
+ ;return out.deref(data)
;/
/; length_of (Variable a, ~CompData data)
- ;Variable t = {"#tmp", get_primitive(is_primitive("uint")), 0, LOCATION.REGISTER}
- ;t.deref(a, data)
- ;self.set(t, data)
+ ;a.data_type.name = "uint"
+ ;a.data_type.s = 8
+ ;a.data_type.ptr_chain = {PTYPE.REFERENCE}
+ ;self.set(a, data)
;/
# Uses rax, does not resolve any ending state after function returns
@@ -964,7 +1002,7 @@
;/
/; loop (int i = 0; i < len (self.vars) && out < 16) [i++]
- /; if (is_primitive(self.vars{i}.data_type.name) !< 0 || len (self.vars{i}.data_type.ptr_chain) > 0)
+ /; if (self.vars{i}.loc_type == LOCATION.REGISTER)
;out++
;/
;/
@@ -1091,11 +1129,11 @@
;new.location = self.next_loc(t)
;; else
;new.loc_type = LOCATION.STACK
- ;new.location = self.get_full_stack()
- ;new.location = new.location + t.s
- ;out`.csec = string_add(out`.csec, "\tsub rsp, ")
- ;out`.csec = string_add(out`.csec, int_to_string(t.s))
- ;out`.csec.append('\n')
+ ;new.location = self.get_full_stack() + new.norm_size()
+ ;out`.csec = string_join( {
+ out`.csec,
+ "\tsub rsp, ", int_to_string(new.norm_size()), "\n"
+ }, "")
;/
;self.vars.append(new)
;/
@@ -1113,6 +1151,59 @@
;return self.parent`.find_var(artifact, current)
;/
+ /; find_reg_variable (int reg) [~Variable]
+ /; loop (int i = 0; i < len (self.vars)) [i++]
+ /; if (self.vars{i}.loc_type == LOCATION.REGISTER && self.vars{i}.location == reg)
+ ;return ~(self.vars{i})
+ ;/
+ ;/
+
+ /; if (!(self.is_cf()))
+ ;tnsl.io.print(reg)
+ ;log_err("Can't move variable to stack as it does not exist in the current context")
+ ;/
+ ;return self.parent`.find_reg_variable(reg)
+ ;/
+
+ /; move_to_stack (int reg, ~CompData out) [Variable]
+ ;int last_var = self.next_register()
+ /; if (last_var < 0)
+ ;last_var = 16
+ ;/
+
+ /; if (reg < 8 || reg > last_var - 1)
+ ;tnsl.io.println(reg)
+ ;log_err("Can't move a register to stack as it is not in scope.")
+ ;/
+
+ ;log_debug(string_join( {
+ "Attempting to move variable at register ",
+ int_to_string(reg), " to stack. last_var = ", int_to_string(last_var)
+ }, ""))
+
+ ;~Variable rv = self.find_reg_variable(reg)
+ ;Variable copy = {rv`.name, rv`.data_type, 0, 0}
+ ;copy.loc_type = LOCATION.STACK
+ ;copy.location = self.get_full_stack() + copy.norm_size()
+ ;out`.csec = string_join( {
+ out`.csec,
+ "\tsub rsp, ", int_to_string(copy.norm_size()), "\n"
+ }, "")
+ ;copy.set(rv`, out)
+ ;rv` = copy
+
+ /; if (reg < last_var)
+ ;rv = self.find_reg_variable(last_var - 1)
+ ;log_debug(string_join({
+ "Moving variable from ", int_to_string(last_var - 1), " to ", int_to_string(reg), ". ",
+ "Variable name: ", rv`.name
+ }, ""))
+ ;rv`.move_register(reg, out)
+ ;/
+
+ ;return copy
+ ;/
+
/; next_const [{}uint8]
/; if (self.is_cf())
;return self.parent`.next_const()
@@ -1193,18 +1284,23 @@
/; _find_def ({}{}uint8 artifact, int r) [Variable]
/; if (len artifact !> r)
- ;retirn {{}, "", 0, 0, 0}
+ ;return {"", NO_TYPE, 0, 0}
;/
/; if (len artifact - 1 > r)
/; loop (int i = 0; i < len (self.sub)) [i++]
/; if (string_equate(artifact{r}, self.sub{i}.name))
- ;return self.sub{i}._find_type(artifact, r + 1)
+ ;log_debug(artifact{r})
+ ;return self.sub{i}._find_def(artifact, r + 1)
;/
;/
;; else if (len artifact - 1 == r)
+ ;{}uint8 true_name = self.full_path()
+ /; if (len true_name > 0)
+ ;true_name.append('.')
+ ;/
+ ;true_name = string_add(true_name, artifact{r})
/; loop (int i = 0; i < len (self.defs)) [i++]
- ;{}uint8 true_name = string_add(self.full_path(), artifact{r})
/; if (string_equate(self.defs{i}.name, true_name))
;return self.defs{i}
;/
@@ -1212,7 +1308,7 @@
;/
/; if (string_equate(self.name, ""))
- ;return {{}, "", 0, 0, 0}
+ ;return {"", NO_TYPE, 0, 0}
;/
;~Module m = self.parent
@@ -1464,10 +1560,10 @@
;out.members = parse_param_list(tok, cur, current)
/; loop (int i = 0; i < len (out.members)) [i++]
- ;tnsl.io.print(string_join({"[", out.members{i}.name, ":", out.members{i}.data_type.name, "]"}, ""))
+ ;log_debug(string_join({"[", out.members{i}.name, ":", out.members{i}.data_type.name, "]"}, ""))
;/
- ;tnsl.io.print(string_add("Generated type ", string_add(out.name, string_add(":", out.mod_name))))
+ ;log_debug(string_add("Generated type ", string_add(out.name, string_add(":", out.mod_name))))
;current`.types.append(out)
;/
@@ -1650,7 +1746,7 @@
;; else if (d.cmp("/;"))
;return ";/"
;/
- ;tnsl.io.println(string_add("Error, unrecognized delim: ", d.data))
+ ;log_err(string_add("Error, unrecognized delim: ", d.data))
;/
# Finds closing bracket
@@ -1770,34 +1866,54 @@
/; _eval_dot (~{}Token tok, int start, max, ~CompData out, ~Module current, ~Scope scope, Type t, bool alt) [Variable]
;Variable wk
;{}{}uint8 art = {}
+
/; loop (tok`{start}.type_is(TOKEN.DEFWORD) && start < max) [start++]
;art.append(tok`{start}.data)
;wk = scope`.find_var(art, current)
/; if (!string_equate(wk.name, ""))
+ ;start++
;break
;/
/; if (tok`{start + 1}.cmp("."))
;start++
;; else
+ ;start++
;break
;/
;/
-
+
+ /; if (string_equate(wk.name, "") || start !< max)
+ ;return wk
+ ;/
+
;Variable refer = {"#tmp", wk.data_type, 1, LOCATION.REGISTER}
/; if (alt)
;refer.location = 2
;/
- ;refer.set(wk, out)
+
+ ;log_debug(wk.sprint())
+
+ ;refer.data_type.ptr_chain.append(PTYPE.REFERENCE)
+ /; if (tok`{start}.cmp("."))
+ ;log_debug("Pre loop ref")
+ ;refer.ref(wk, out)
+ ;; else
+ ;log_debug("Pre loop deref")
+ ;refer = wk.deref(out)
+ ;/
+ ;start++
;tnsl.io.println(refer.name)
- ;tnsl.io.println(refer.data_type.name)
+ ;tnsl.io.println(refer.data_type)
/; loop (start < max) [start++]
/; if (tok`{start}.cmp("`"))
- ;refer.deref(refer, out)
+ ;log_debug("Loop deref")
+ ;refer = refer.deref(out)
;; else if (tok`{start}.cmp(".") && tok`{start + 1}.type_is(TOKEN.DEFWORD))
+ ;log_debug("Loop member")
;refer.member(refer, out, tok`{start + 1}.data)
;start++
;/
@@ -1891,20 +2007,20 @@
;t = s1.data_type
;/
;s2 = _eval_value(tok, first + 1, max, out, current, scope, t, !alt)
- ;tnsl.io.print("Calculated s2 as ")
- ;tnsl.io.println(s2.name)
+ ;log_debug(string_add("Calculated s2 as ", s2.name))
;/
- ;tnsl.io.print("Calculated s1 as ")
- ;tnsl.io.println(s1.name)
+ ;log_debug(string_add("Calculated s2 as ", s1.name))
/; if (tok`{first}.cmp("="))
;s1.set(s2, out)
;return s1
;/
- ;tnsl.io.println(t.name)
- ;tnsl.io.println(t.s)
+ ;log_debug(string_join( {
+ "_eval_value called with following type info:", t.name, int_to_string(t.s)
+ }, " "))
+
;Variable wk = {"#wk", t, 1, LOCATION.REGISTER}
/; if (alt)
;wk.location = 2
@@ -1941,9 +2057,10 @@
;; else if (tok`{first}.cmp("%"))
;wk.set(s1, out)
;wk.mod(s2, out)
- ;; else if (tok`{first}.cmp("`"))
- ;wk.deref(s1, out)
;; else if (tok`{first}.cmp("~"))
+ /; if (!(s1.is_ref()) && s1.loc_type == LOCATION.REGISTER)
+ ;s1 = scope`.move_to_stack(s1.location, out)
+ ;/
;wk.ref(s1, out)
;; else if (tok`{first}.cmp("!"))
;wk.not(s1, out)
@@ -2639,6 +2756,7 @@
##
/; main ({}{}uint8 args) [int]
+ ;log_debug("TNSLC version 0.0.1, built with debugging enabled")
/; if (len args < 1)
;tnsl.io.println("Give me something to compile!")
;return 1