summaryrefslogtreecommitdiff
path: root/tnslc/compile
diff options
context:
space:
mode:
Diffstat (limited to 'tnslc/compile')
-rw-r--r--tnslc/compile/compile.tnsl768
-rw-r--r--tnslc/compile/isa_x86.tnsl182
-rw-r--r--tnslc/compile/value.tnsl362
3 files changed, 0 insertions, 1312 deletions
diff --git a/tnslc/compile/compile.tnsl b/tnslc/compile/compile.tnsl
deleted file mode 100644
index 034304c..0000000
--- a/tnslc/compile/compile.tnsl
+++ /dev/null
@@ -1,768 +0,0 @@
-/##
- Copyright 2021-2022 Kyle Gunger
-
- This file is licensed under the CDDL 1.0 (the License)
- and may only be used in accordance with the License.
- You should have received a copy of the License with this
- software/source code. If you did not, a copy can be found
- at the following URL:
-
- https://opensource.org/licenses/CDDL-1.0
-
- THIS SOFTWARE/SOURCE CODE IS PROVIDED "AS IS" WITH NO
- WARRANTY, GUARANTEE, OR CLAIM OF FITNESS FOR ANY PURPOSE
- EXPRESS OR IMPLIED
-#/
-
-
-;{}{}uint8 COMMON_ASM = {
- "\tret\n"
-}
-
-# Represents a type
-;struct VType {
- uint
- _size,
- int
- ptr,
-
- {}uint8 name,
-
- {}VType sub_types,
- {}{}uint8 sub_names
-}
-
-/; method VType
- /; get_sub_type({}uint8 name) [VType]
- /; loop (int i = 0; i < len (self.sub_types)) [i++]
- /; if (string_equate(~name, ~(self.sub_names{i})))
- ;return self.sub_types{i}
- ;/
- ;/
- ;return NT
- ;/
-
- /; get_offset({}uint8 name) [int]
- ;int out = 0
- /; loop (int i = 0; i < len (self.on_stack)) [i++]
- /; if (string_equate(~name, ~(self.sub_types{i*2 + 1})))
- ;return out
- ;; else if (self.on_stack{i})
- ;VType tmp = vtype_by_name(self.sub_types{i*2})
- ;out = out + tmp.size
- ;/
- ;/
- ;return -1
- ;/
-
- /; print
- ;tnsl.io.print("Size: ")
- ;tnsl.io.print(self._size)
- ;tnsl.io.print(" | Ptr: ")
- ;tnsl.io.print(self.ptr)
- ;tnsl.io.print(" | Name: ")
- ;tnsl.io.println(self.name)
- ;/
-;/
-
-# Tracks defined variables in a block
-;struct VTrack {
- {}{}uint8
- sym_names,
-
- {}Value
- sym_vals
-}
-
-/; method VTrack
-
- /; next_loc(VType vt) [int]
- /; if (is_struct(vt) && vt.ptr == 0)
- ;return -1
- ;/
-
- ;int count = 0
- /; loop (int i = 0; i < len (self.sym_vals)) [i++]
- /; if (!(self.sym_vals{i}.on_stack))
- ;count++
- ;/
-
- /; if (count > 7)
- ;return -1
- ;/
- ;/
-
- ;return count + 6
- ;/
-
- # returns with init commands
- /; add_track({}uint8 name, VType _type) [{}uint8]
- ;Value v = track_val(_type, to_stack, self.next_loc(_type))
-
- /; if (v.loc < 0)
- ;v.loc = 0
- ;/
-
- ;self.sym_names.append(name)
- ;self.sym_vals.append(v)
- ;return v.init_val()
- ;/
-
- # Returns true if the variable is being tracked
- /; in_vtrack({}uint8 name) [bool]
- /; loop (int i = 0; i < len (self.sym_names)) [i++]
- /; if (string_equate(name, self.sym_names{i}))
- ;return true
- ;/
- ;/
- ;return false
- ;/
-
- # Returns the total allocated memory on the stack for this tracker
- /; stack_total [int]
- ;int out = 0
- /; loop (int i = 0; i < len (self.on_stack)) [i++]
- /; if (self.on_stack{i})
- ;out = out + (self.sym_vals{i}._type._size)
- ;/
- ;/
- ;return out
- ;/
-
- # returns the type of the named variable
- /; get_val ({}uint8 name) [Value]
- /; loop (int i = 0; i < len (self.sym_names)) [i++]
- /; if (string_equate(name, self.sym_names{i}))
- ;return (self.sym_vals{i})
- ;/
- ;/
- ;/
-
- # push stack updates loc for every value on the stack
- /; push_stack (VType vt) [{}uint8]
- ;int tsz = vt._size
- /; if (vt.ptr !== 0)
- ;tsz = 8
- ;/
-
- /; loop (int i = 0; i < len (self.sym_vals)) [i++]
- /; if (self.sym_vals{i}.on_stack)
- ;self.sym_vals{i}.loc = self.sym_vals{i}.loc + tsz
- ;/
- ;/
-
- ;{}uint8 out = "\tsub $"
- ;{}uint8 tmp = string_from_int(tsz)
- ;add_strings(~out, ~tmp)
- ;out.append(',')
- ;out.append(' ')
- ;tmp = "%rsp"
- ;add_strings(~out, ~tmp)
- ;return out
- ;/
-;/
-
-# Sizes of items
-;{}VType type_table = {
- {1, 0, "int8", {}, {}},
- {2, 0, "int16", {}, {}},
- {4, 0, "int32", {}, {}},
- {8, 0, "int64", {}, {}},
- {8, 0, "int", {}, {}},
- {1, 0, "uint8", {}, {}},
- {2, 0, "uint16", {}, {}},
- {4, 0, "uint32", {}, {}},
- {8, 0, "uint64", {}, {}},
- {8, 0, "uint", {}, {}},
- {4, 0, "float32", {}, {}},
- {8, 0, "float64", {}, {}},
- {8, 0, "float", {}, {}},
- {1, 0, "bool", {}, {}},
- {8, 0, "void", {}, {}}
-}
-
-# Null type
-;VType NT = {0, 0, "null", {}, {}}
-
-# Returns an index in the vtrack for a given variable name
-/; name_to_index ({}uint8 name, ~VTrack tab) [int]
- /; loop (int i = 0; i < len (tab`.sym_names)) [i++]
- /; if (string_equate(tab`.sym_names{i}, name))
- ;return i
- ;/
- ;/
-
- ;tnsl.io.print("Failed to find vairable ")
- ;tnsl.io.println(name)
-
- ;return -1
-;/
-
-# Bool to j
-/; cmp_to_jxt ({}uint8 c) [{}uint8]
- /; if (string_equate(c, "<"))
- ;return "l"
- ;; else if (string_equate(c, ">"))
- ;return "g"
- ;; else if (string_equate(c, "!<") || string_equate(c, ">=="))
- ;return "nl"
- ;; else if (string_equate(c, "!>") || string_equate(c, "<=="))
- ;return "ng"
- ;; else if (string_equate(c, "=="))
- ;return "e"
- ;; else if (string_equate(c, "!=="))
- ;return "ne"
- ;/
- ;return "nz"
-;/
-
-# Is struct returns true if the type name given is a struct
-/; is_struct (VType t) [bool]
- ;VType tmp = NT
- /; loop (int i = 0; i < 15) [i++]
- ;tmp = tnslc.type_table{i}
- /; if (string_equate(tmp.name, t.name))
- ;return false
- ;/
- ;/
-
- ;return true
-;/
-
-# Using the given offset (in bytes), return an asm value of form ".quad <offset>"
-/; construct_value (int size, int offset) [{}uint8]
- ;{}uint8 out = ".byte "
- /; if (size == 2)
- ;out = ".word "
- ;; if (size == 4)
- ;out = ".long"
- ;; if (size == 8)
- ;out = ".quad "
- ;/
- ;{}uint8 tmp = string_from_int(offset)
- ;add_strings(~out, ~tmp)
- ;return out
-;/
-
-/; construct_text_value ({}uint8 t) [{}uint8]
- ;{}uint8 tmp = "\n\t.ascii "
- ;add_strings(~tmp, ~t)
- ;return tmp
-;/
-
-/; construct_mov_literal({}uint8 value, reg) [{}uint8]
- ;{}uint8 tmp = "$"
- ;add_strings(~tmp, ~value)
- ;return mov_asm(tmp, reg)
-;/
-
-# Parse a struct and add it to the table
-/; def_struct (~int cur, ~{}Token data, ~{}uint8 dsec) [VType]
- ;VType out = {0, 0, "", {}, {}}
- ;cur`++
-
- ;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`--
-
- /; if (ctype.ptr > 0)
- ;out._size = out._size + 8
- ;; else
- ;out._size = out._size + ctype._size
- ;/
- ;out.sub_types.append(ctype)
- ;out.sub_names.append(data`{cur`}.data`)
-
- ;; else
- # Get type
- ;cur`--
- ;ctype = get_vtype(cur, data)
- ;/
- ;/
- ;out.print()
- ;type_table.append(out)
-
- ;return out
-;/
-
-# Checks if the current token's data member is equal to a given string
-/; token_is(~int cur, ~{}Token data, {}uint8 str) [bool]
- ;return string_equate(data`{cur`}.data`, str)
-;/
-
-# Skips in a definition or list until it finds a name
-/; skip_to_name (~int cur, ~{}Token data)
- ;int tmp = 0
- /; loop (cur` < len data`) [cur`++]
- ;tmp = cur` + 1
- /; if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD &&
- ( token_is(~tmp, data, ",") || token_is(~tmp, data, ")") || token_is(~tmp, data, "}") || token_is(~tmp, data, ";") ))
- ;break
- ;/
- ;/
-;/
-
-# Searches the type table for a type
-/; vtype_by_name ({}uint8 name) [VType]
- /; loop (int i = 0; i < len type_table) [i++]
- ;VType tmp = tnslc.type_table{i}
- /; if (string_equate(name, tmp.name))
- ;return tmp
- ;/
- ;/
- ;return NT
-;/
-
-# Parses a type in a definition or list
-/; get_vtype (~int cur, ~{}Token data) [VType]
- ;uint ptr = 0
- ;VType out = NT
-
- /; loop (cur` < len data`) [cur`++]
- ;int i = data`{cur`}.token_type
- /; if (token_is(cur, data, "~") || token_is(cur, data, "{"))
- ;ptr++
- ;; else if (i == TOKEN_TYPE.DEFWORD || i == TOKEN_TYPE.KEYTYPE)
- ;out = vtype_by_name(data`{cur`}.data`)
- ;break
- ;; else if (!token_is(cur, data, "}"))
- ;break
- ;/
- ;/
-
- ;out.ptr = ptr
-
- ;return out
-;/
-
-# Assumes cur points to the beginning of the arguments list
-# Sets up the VTrack struct that is pointed to.
-/; setup_vtrack (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 csec)
- ;cur`++
-
- ;VType last = NT
- ;Value tmp = {false, false, 0, 0, last}
-
- /; loop (cur` < len data`) [cur`++]
- ;int pre_skip = cur`
- /; if (token_is(cur, data, ")"))
-
- ;break
- ;; else if (!token_is(cur, data, ","))
-
- ;skip_to_name(cur, data)
-
- /; if (pre_skip !== cur`)
- ;last = get_vtype(~pre_skip, data)
- ;tmp._type = last
- ;/
-
- ;tab`.sym_names.append(data`{cur`}.data`)
- ;int nloc = tab`.next_loc(last)
-
- ;Value store = {false, false, nloc, 0, last}
- /; if (store.loc !< 0 && tmp.loc !> 5)
- ;{}uint8 tstr = store.set_value(tmp)
- ;add_strings(csec, ~tstr)
- ;tmp.loc = tmp.loc + 1
- ;; else
- ;store.loc = 0
- ;store.on_stack = true
- ;tab`.push_stack(last)
- ;/
-
- ;tab`.sym_vals.append(store)
- ;/
- ;/
-;/
-
-# Mostly deals with structs and enums
-/; compile_global (~int cur, ~{}Token data, ~{}uint8 hsec, csec, dsec)
- ;cur`++
- /; if (token_is(cur, data, "struct"))
- ;def_struct(cur, data, dsec)
- ;/
-;/
-
-# Evaluate a value
-/; eval_value (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec, int val_layer) [Value]
- /; if (token_is(cur, data, ";/"))
- ;return NV
- ;/
-
- ;Value tmp = {false, false, val_layer % 5, 0, NT}
-
- /; if (val_layer > 5)
- ;tmp.on_stack = true
- ;/
-
- /; loop (cur` < len data`)
- ;tnsl.io.println("looping")
- /; if (data`{cur`}.token_type == TOKEN_TYPE.LITERAL)
- /; if (data`{cur`}.data`{0} == '"')
- # String literal
- ;tmp._type = type_table{5}
- ;tmp._type.ptr = 1
- ;; else if (data`{cur`}.data`{0} == '\'')
- # Char literal
- ;int val = unquote_char(data`{cur`}.data`)
- ;Value lit = {false, true, 0, val, type_table{5}}
- ;{}uint8 tmp = out.set_value(lit)
- ;add_strings(csec, ~tmp)
- ;; else
- # int literal
- ;tnsl.io.print("int literal ")
- ;tnsl.io.println(data`{cur`}.data`)
- ;tmp.val = int_from_string(data`{cur`}.data`)
- ;tmp.literal = true
- ;tmp._type = tnslc.type_table{4}
- ;cur`++
- ;tnsl.io.print("next tok ")
- ;tnsl.io.println(data`{cur`}.data`)
- ;/
- ;; else if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD)
-
- /; if (is_call(cur, data))
- ;; else if (tab`.in_vtrack(data`{cur`}.data`))
- ;tmp = tab`.get_val(data`{cur`}.data`)
- ;cur`++
- /; loop (token_is(cur, data, "."))
- ;cur`++
- ;tmp = tmp.get_member_value(data`{cur`}.data`)
- ;cur`++
- ;/
- ;/
-
- ;; else if (token_is(cur, data, "~"))
- ;; else if (data`{cur`}.token_type == TOKEN_TYPE.AUGMENT)
-
- ;int acr = cur`
- ;cur`++
- ;Value nxt = eval_value(cur, data, tab, hsec, csec, dsec, val_layer + 1)
- ;{}uint8 code = ""
- /; if (token_is(~acr, data, "="))
- ;code = tmp.set_value(nxt)
- ;; if (token_is(~acr, data, "+"))
- ;code = tmp.add_value(nxt)
- ;; if (token_is(~acr, data, "-"))
- ;tnsl.io.println("here")
- ;code = tmp.sub_value(nxt)
- ;; if (token_is(~acr, data, "*"))
- ;code = tmp.mul_value(nxt)
- ;; if (token_is(~acr, data, "/"))
- ;code = tmp.div_value(nxt)
- ;/
- ;add_strings(csec, ~code)
- ;break
- ;; else
- ;break
- ;/
- ;/
- ;return tmp
-;/
-
-/; get_function_label(~int cur, ~{}Token data) [{}uint8]
- /; if (string_equate(data`{cur` + 1}.data`, "("))
- ;return data`{cur`}.data`
- ;/
-
- ;{}{}uint8 func_path = {}
-
- /; loop (cur` < len data`) [cur`++]
- /; if (token_is(cur, data, "("))
- ;break
- ;; else if (!token_is(cur, data, "."))
- ;func_path.append(data`{cur`}.data`)
- ;/
- ;/
- ;{}uint8 out = "_."
- ;{}uint8 jn_tmp = join(func_path, '.')
- ;add_strings(~out, ~jn_tmp)
- ;return out
-;/
-
-# Sets up a call and reports back where the return value is stored
-/; eval_call (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec) [{}uint8]
-
- # Store the name of the function we are calling
- ;{}uint8 to_call = get_function_label(cur, data)
- ;tnsl.io.println(to_call)
- # Set read head to first parameter
- ;cur`++
- /; loop (!token_is(cur, data, ")"))
- /; if (token_is(cur, data, ","))
- ;cur`++
- ;; else
- /; if (reg < 7)
- ;eval_value(cur, data, tab, hsec, csec, dsec)
- ;reg++
- ;; else
- ;eval_value(cur, data, tab, hsec, csec, dsec)
- ;push_asm(get_reg(8, "bp"))
- ;/
- ;/
- ;/
- ;cur`++
-
- ;{}uint8 call_ist = call_asm(to_call)
-
- ;add_strings(csec, ~call_ist)
- ;return "ax"
-;/
-
-/; is_call (~int cur, ~{}Token data) [bool]
- ;bool look_def = true
- /; loop (int i = cur`; i < len data`) [i++]
- /; if (look_def && data`{i}.token_type == TOKEN_TYPE.DEFWORD)
- ;look_def = false
- ;; else if (!look_def && token_is(~i, data, "."))
- ;look_def = true
- ;; else if (!look_def && token_is(~i, data, "("))
- ;return true
- ;; else
- ;break
- ;/
- ;/
- ;return false
-;/
-
-# Compile a statement in a function
-/; compile_statement (~int cur, ~{}Token data, ~VTrack tab, ~{}uint8 hsec, csec, dsec) [bool]
- ;cur`++
- ;bool r = false
- /; if (cur` !< len data`)
- ;return false
- ;/
-
- /; if (token_is(cur, data, "asm"))
- ;cur`++
- ;{}uint8 raw_asm = unquote_string(data`{cur`}.data`)
- ;raw_asm.append('\n')
- ;csec`.append('\t')
- ;add_strings(csec, ~raw_asm)
- ;cur`++
- ;; else if (token_is(cur, data, "raw"))
- ;cur`++
- ;r = true
- ;; else if (token_is(cur, data, "return"))
- ;cur`++
- ;Value out = eval_value(cur, data, tab, hsec, csec, dsec, 0)
- ;{}uint8 mv = out.mov_to_reg(0)
- ;add_strings(csec, ~mv)
- ;tail_guard(csec)
- ;add_strings(csec, ~(tnslc.COMMON_ASM{0}))
- ;return true
- ;; else if (is_call(cur, data))
- # Function call
- ;eval_call(cur, data, tab, hsec, csec, dsec)
- ;; else if (tab.in_vtrack(data`{cur`}.data`))
- # set value
- ;int i = name_to_index(data`{cur`}.data`, tab)
- ;{}uint8 tmp = index_to_loc(i)
- ;eval_value(cur, data, tab, hsec, csec, dsec)
- ;tmp = mov_asm(get_reg(tab`.sym_types{i}._size, "ax"), tmp)
- ;add_strings(csec, ~tmp)
- ;; else
- #Definition
- ;VType def_t = get_vtype(cur, data)
- ;cur`++
-
- /; loop (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD)
- ;{}uint8 init = tab`.add_track(data`{cur`}.data`, def_t)
- ;add_strings(~out, ~init)
- ;cur`++
- /; if (token_is(cur, data, ","))
- ;cur`++
- ;; else if (token_is(cur, data, "="))
- ;{}uint8 set = index_to_loc(len tab`.sym_names - 1, tab)
- ;eval_value(cur, data, tab, hsec, csec, dsec, loc)
- /; if (token_is(cur, data, ","))
- ;cur`++
- ;/
- ;; else
- ;break
- ;/
- ;/
- /; if (string_equate(data`{cur`+1}.data`, "="))
- ;/
- ;; if (token_is(cur, data, "return"))
- ;add_strings(csec, ~(tnslc.COMMON_ASM{0}))
- ;return true
- ;/
-
- ;return false
-;/
-
-
-
-/; compile_block (~int cur, ~{}Token data, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path, Path rel)
- ;VTrack tab = { {}, {} }
- ;VType out_type = tnslc.type_table{14}
- ;{}uint8 name = ""
- ;bool r = false
-
- /; loop (cur`++; cur` < len data`) [cur`++]
- /; if (token_is(cur, data, "module"))
- ;mod_path.append(data`{cur` + 1}.data`)
- ;cur` = cur` + 2
- ;break
- ;/
- /; if (data`{cur`}.token_type == TOKEN_TYPE.DEFWORD && len name == 0)
- ;name = data`{cur`}.data`
- /; if (len mod_path > 0)
- ;{}uint8 frs = "_."
- ;{}uint8 jn = join(mod_path, '.')
- ;add_strings(~frs, ~jn)
- ;add_strings(csec, ~frs)
- ;csec`.append('.')
- ;/
- ;add_strings(csec, ~name)
- ;csec`.append(':')
- ;csec`.append('\n')
- /; if (!r)
- ;header_guard(csec)
- ;/
- ;; else if (token_is(cur, data, "("))
- ;setup_vtrack(cur, data, ~tab, csec)
- ;; else if (token_is(cur, data, "["))
- ;cur`++
- ;out_type = get_vtype(cur, data)
- ;cur`++
- ;; else if (token_is(cur, data, "raw"))
- ;r = true
- ;; else
- ;break
- ;/
- ;/
-
- ;tnsl.io.println(out_type.name)
-
- ;bool ret = false
- /; loop (cur` < len data` && !ret)
- /; if (token_is(cur, data, ";/"))
- /; if (!r)
- ;tail_guard(csec)
- ;/
- ;add_strings(csec, ~(tnslc.COMMON_ASM{0}))
- ;break
- ;; else if (token_is(cur, data, "/;"))
- ;bool ch = true
- /; loop (ch)
- ;compile_block(cur, data, hsec, csec, dsec, mod_path)
- /; if (cur` !< len data`)
- ;break
- ;/
- ;ch = token_is(cur, data, ";;")
- ;/
- ;; else if (string_equate(data`{cur`}.data`, ":"))
- ;cur` = cur` + 2
- ;Path inc = rel.rel_file(unquote_string(data`{cur`}.data`))
- ;compile_include(inc, hsec, csec, dsec, mod_path)
- ;cur`++
- ;; else if (string_equate(data`{cur`}.data`, ";"))
- ;ret = compile_statement(cur, data, ~tab, hsec, csec, dsec)
- ;; else
- ;tnsl.io.print("Failed to compile token [compile_block]: ")
- ;data`{cur`}.print()
- ;tnsl.io.println("")
- ;break
- ;/
- ;/
-
- ;csec`.append('\n')
-;/
-
-/; compile_include (Path file_path, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path)
- # Autocomplete in the case of module syntax
- ;bool d = file_path.extension_is("tnsl")
- /; if (!d)
- ;file_path.dirs.append(file_path.file)
- ;{}uint8 ftmp = file_path.file
- ;{}uint8 tmp = ".tnsl"
- ;add_strings(~ftmp, ~tmp)
- ;file_path.file = ftmp
- ;/
-
- ;tnsl.io.print("[TNSLC:INCLUDE] ")
- ;tnsl.io.println(file_path.full_path())
-
- ;tnsl.io.File inc = file_path.open_r()
- ;~{}Token data = parse.tokenize(inc)
- ;inc.close()
-
- ;tnsl.io.print(len data`)
- ;tnsl.io.println(" tokens parsed.")
-
- ;compile_file(file_path, data, hsec, csec, dsec, mod_path)
-;/
-
-/; compile_file (Path rel, ~{}Token data, ~{}uint8 hsec, csec, dsec, {}{}uint8 mod_path)
-
- ;int j = len data`
-
- /; loop (int i = 0; i < j) [i++]
- /; if (string_equate(data`{i}.data`, "/;"))
- ;compile_block(~i, data, hsec, csec, dsec, mod_path, rel)
- ;; else if (string_equate(data`{i}.data`, ";"))
- ;compile_global(~i, data, hsec, csec, dsec)
- ;; else if (string_equate(data`{i}.data`, ":"))
- ;i = i + 2
- ;Path inc = rel.rel_file(unquote_string(data`{i}.data`))
- ;compile_include(inc, hsec, csec, dsec, mod_path)
- ;; else
- ;break
- ;/
- ;/
-
-;/
-
-/; do_compile ({}uint8 file_out, Path rel)
- ;{}uint8 hsec = ".global main\n"
- ;{}uint8 csec = ".text\n"
- ;{}uint8 dsec = ".data\n"
-
- ;tnslc.compile_include(rel, ~hsec, ~csec, ~dsec, {})
-
- ;tnsl.io.File out = tnsl.io.writeFile(file_out)
-
- /; loop (int i = 0; i < len hsec) [i++]
- ;out.write(hsec{i})
- ;/
-
- ;out.write('\n')
-
- /; loop (int i = 0; i < len dsec) [i++]
- ;out.write(dsec{i})
- ;/
-
- ;out.write('\n')
-
- /; loop (int i = 0; i < len csec) [i++]
- ;out.write(csec{i})
- ;/
-
- ;out.write('\n')
- ;out.close()
-;/
-
diff --git a/tnslc/compile/isa_x86.tnsl b/tnslc/compile/isa_x86.tnsl
deleted file mode 100644
index 1cb09ab..0000000
--- a/tnslc/compile/isa_x86.tnsl
+++ /dev/null
@@ -1,182 +0,0 @@
-/##
- Copyright 2021-2022 Kyle Gunger
-
- This file is licensed under the CDDL 1.0 (the License)
- and may only be used in accordance with the License.
- You should have received a copy of the License with this
- software/source code. If you did not, a copy can be found
- at the following URL:
-
- https://opensource.org/licenses/CDDL-1.0
-
- THIS SOFTWARE/SOURCE CODE IS PROVIDED "AS IS" WITH NO
- WARRANTY, GUARANTEE, OR CLAIM OF FITNESS FOR ANY PURPOSE
- EXPRESS OR IMPLIED
-#/
-
-/; construct_statement({}uint8 base, {}{}uint8 args) [{}uint8]
- /; loop (int i = 0; i < len args) [i++]
- ;add_strings(~base, ~(args{i}))
- /; if (i < len args - 1)
- ;base.append(',')
- ;base.append(' ')
- ;/
- ;/
- ;base.append('\n')
- ;return base
-;/
-
-/; literal_num ({}uint8 num) [{}uint8]
- ;{}uint8 out = "$"
- ;add_strings(~out, ~num)
- ;return out
-;/
-
-/; add_asm ({}uint8 from, to) [{}uint8]
- ;return construct_statement("\tadd ", {from, to})
-;/
-
-/; sub_asm({}uint8 from, to) [{}uint8]
- ;return construct_statement("\tsub ", {from, to})
-;/
-
-/; push_asm ({}uint8 reg) [{}uint8]
- ;return construct_statement("\tpush ", {reg})
-;/
-
-/; pop_asm ({}uint8 reg) [{}uint8]
- ;return construct_statement("\tpop ", {reg})
-;/
-
-/; cmp_asm ({}uint8 a, b) [{}uint8]
- ;return construct_statement("\tcmp ", {a, b})
-;/
-
-/; mov_asm ({}uint8 a, b) [{}uint8]
- ;return construct_statement("\tmov ", {a, b})
-;/
-
-/; jmp_asm ({}uint8 pos) [{}uint8]
- ;return construct_statement("\tjmp ", {pos})
-;/
-
-/; call_asm ({}uint8 pos) [{}uint8]
- ;return construct_statement("\tcall ", {pos})
-;/
-
-/; cjmp_asm ({}uint8 suffix, pos) [{}uint8]
- ;{}uint8 p = "\tj"
- ;add_strings(~p, ~suffix)
- ;p.append(' ')
- ;return construct_statement(p, {pos})
-;/
-
-/; mem_offset ({}uint8 pos, offset, scale) [{}uint8]
- ;{}uint8 tmp = construct_statement("(", {pos, offset, scale})
- ;tmp{len tmp - 1} = ')'
- ;return tmp
-;/
-
-/; header_guard (~{}uint8 csec) [{}uint8]
- ;{}uint8 out = "", tmp = ""
- ;tmp = push_asm("%r8")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r9")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r10")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r11")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r12")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r13")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r14")
- ;add_strings(~out, ~tmp)
- ;tmp = push_asm("%r15")
- ;add_strings(~out, ~tmp)
- ;add_strings(csec, ~out)
-;/
-
-/; tail_guard (~{}uint8 csec) [{}uint8]
- ;{}uint8 out = "", tmp = ""
- ;tmp = pop_asm("%r15")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r14")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r13")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r12")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r11")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r10")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r9")
- ;add_strings(~out, ~tmp)
- ;tmp = pop_asm("%r8")
- ;add_strings(~out, ~tmp)
- ;add_strings(csec, ~out)
-;/
-
-/; is_common_reg ({}uint8 n) [bool]
- ;return string_equate(n, "ax") || string_equate(n, "bx") || string_equate(n, "cx") || string_equate(n, "dx")
- || string_equate(n, "sp") || string_equate(n, "bp") || string_equate(n, "si") || string_equate(n, "di")
- || string_equate(n, "8") || string_equate(n, "9") || string_equate(n, "10") || string_equate(n, "11")
- || string_equate(n, "12") || string_equate(n, "13") || string_equate(n, "14") || string_equate(n, "15")
-;/
-
-/# Accepted common names:
-# - ax
-# - bx
-# - cx
-# - dx
-# - si
-# - di
-# - bp
-# - sp
-# - 8-15
-#/
-/; get_reg (uint size, {}uint8 common) [{}uint8]
- ;{}uint8 out = "%"
-
- /; if (common{0} !< 'a')
-
- /; if (size == 1)
- /; if(common{1} == 'x')
- ;common{1} = 'l'
- ;; else
- ;common.append('l')
- ;/
- ;; else if (size == 4)
- ;out.append('e')
- ;; else if (size == 8)
- ;out.append('r')
- ;/
-
- ;add_strings(~out, ~common)
-
- ;; else
-
- ;out.append('r')
- ;add_strings(~out, ~common)
- /; if (size == 1)
- ;out.append('b')
- ;; else if (size == 2)
- ;out.append('w')
- ;; else if (size == 4)
- ;out.append('d')
- ;/
- ;return out
- ;/
-
- ;return out
-;/
-
-/; make_label ({}uint8 func_name, func_place, ~{}uint8 csec)
- ;func_name.append("_")
- ;add_strings(~func_name, ~func_place)
- ;func_name.append(':')
- ;func_name.append('\n')
- ;add_strings(csec, ~func_name)
-;/
diff --git a/tnslc/compile/value.tnsl b/tnslc/compile/value.tnsl
deleted file mode 100644
index da76ac8..0000000
--- a/tnslc/compile/value.tnsl
+++ /dev/null
@@ -1,362 +0,0 @@
-;struct Value {
- bool
- on_stack,
- literal,
-
- int
- loc,
- val,
-
- VType
- _type
-}
-
-;Value NV = {false, false, 0, 0, 0, {0, 0, "null", {}, {}}}
-
-/; val_from_address (int offset, {}uint8 reg) [{}uint8]
- ;{}uint8 out = string_from_int(offset)
- ;out.append('(')
- ;add_strings(~out, ~reg)
- ;out.append(')')
- ;return out
-;/
-
-
-# The temp registers in order
-/; reg_by_num(int r) [{}uint8]
- /; if (r == 0)
- ;return "ax"
- ;; if (r == 1)
- ;return "bx"
- ;; if (r == 2)
- ;return "cx"
- ;; if (r == 3)
- ;return "dx"
- ;; if (r == 4)
- ;return "si"
- ;; if (r == 5)
- ;return "di"
- ;; if (r == -1)
- ;return "sp"
- ;/
- ;return string_from_int(r + 2)
-;/
-
-/; ext_by_size(int s) [uint8]
- /; if (r == 1)
- ;return 'b'
- ;; if (r == 2)
- ;return 'w'
- ;; if (r == 4)
- ;return 'l'
- ;/
- ;return 'q'
-;/
-
-
-/; method Value
-
- /; get_norm_sz [int]
- /; if (self._type.ptr !== 0)
- ;return 8
- ;/
- ;returnself._type._size
- ;/
-
- /; get_norm_loc [{}uint8]
- /; if (self.on_stack)
- ;return val_from_address(self.loc, "%rsp")
- ;; if (!(self.on_stack) && self._type.ptr == 0 && is_struct(self._type))
- ;{}uint8 out = "("
- ;{}uint8 tmp = get_reg(8, reg_by_num(self.loc))
- ;add_strings(~out, ~tmp)
- ;out.append(')')
- ;return out
- ;/
-
- /; if (self.literal)
- ;{}uint8 out = "$"
- ;{}uint8 num = string_from_int(self.val)
- ;add_strings(~out, ~num)
- ;return out
- ;/
-
- ;int sz = self._type._size
- /; if (self._type.ptr !== 0)
- ;sz = 8
- ;/
-
- ;return get_reg(sz, reg_by_num(self.loc))
- ;/
-
- /; init_val [{}uint8]
- /; if (self.literal || !self.on_stack)
- ;return ""
- ;/
-
- ;{}uint8 out = "\tsub $"
- ;{}uint8 tmp = string_from_int(self._type._size)
- ;add_strings(~out, ~tmp)
- ;tmp = ", %rsp\n"
- ;add_strings(~out, ~tmp)
- ;return out
- ;/
-
- /; standard_op(Value other, {}uint8 op) [{}uint8]
- ;tnsl.io.print("Std op ")
- ;tnsl.io.println(op)
- ;int tsz = other._type._size
- ;other._type._size = self._type._size
- ;{}uint8 tmp = other.get_norm_loc()
- ;other._type._size = tsz
- ;{}uint8 out = "\t"
- ;add_strings(~out, ~op)
- ;out.append(' ')
- ;add_strings(~out, ~tmp)
- ;out.append(',')
- ;out.append(' ')
- ;tmp = self.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;out.append('\n')
- ;return out
- ;/
-
- /; add_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = self.val + v.val
- ;return ""
- ;; else if (!(self.on_stack))
- ;return self.standard_op(v, "add")
- ;/
- ;/
-
- /; sub_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = self.val - v.val
- ;return ""
- ;; else if (!(self.on_stack))
- ;return self.standard_op(v, "sub")
- ;/
- ;/
-
- /; ax_compute(Value v, {}uint8 op, bool save_dx)
- ;{}uint8 out = "\tpush %rax\n\tpush %rdx\n"
-
- /; if (v.on_stack)
- ;v.loc = v.loc + 16
- ;; if (self.on_stack)
- ;self.loc = self.loc + 16
- ;/
-
- ;{}uint8 tmp = "\tmov "
- ;{}uint8 t2 = v.get_norm_loc()
- ;add_strings(~tmp, ~t2)
- ;t2 = ", %rax\n"
- ;add_strings(~tmp, ~t2)
- ;add_strings(~out, ~tmp)
-
- ;tmp = "\txor %rdx, %rdx\n"
- ;add_strings(~out, ~tmp)
-
- ;tmp = "\t"
- ;add_strings(~tmp, ~op)
- ;tmp.append(' ')
- ;{}uint8 t2 = self.get_norm_loc()
- ;add_strings(~tmp, ~t2)
- ;tmp.append('\n')
- ;add_strings(~out, ~tmp)
-
- /; if (save_dx)
- ;tmp = "\tmov %rdx, "
- ;; else
- ;tmp = "\tmov %rax, "
- ;/
- ;add_strings(~tmp, ~t2)
- ;tmp.append('\n')
- ;add_strings(~out, ~tmp)
-
- /; if (v.on_stack)
- ;v.loc = v.loc - 16
- ;; if (self.on_stack)
- ;self.loc = self.loc - 16
- ;/
-
- ;tmp = "\tpop %rdx\n\tpop %rax"
- ;add_strings(~out, ~tmp)
- ;return out
- ;/
-
- /; mul_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = self.val * v.val
- ;return ""
- ;; else if (!(self.on_stack))
- /; if (self._type.name{0} !== 'u')
- ;return self.standard_op(v, "imul")
- ;/
-
- ;return self.ax_compute(v, "mul", false)
- ;/
- ;/
-
- /; div_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = self.val + v.val
- ;return ""
- ;; else if (!(self.on_stack))
- /; if (self._type.name{0} !== 'u')
- ;return self.ax_compute(v, "idiv", false)
- ;/
-
- ;return self.ax_compute(v, "div", false)
- ;/
- ;/
-
- /; mod_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = self.val / v.val
- ;return ""
- ;; else if (!self.on_stack)
- /; if (self._type.name{0} !== 'u')
- ;return self.ax_compute(v, "idiv", true)
- ;/
-
- ;return self.ax_compute(v, "div", true)
- ;/
- ;/
-
- /; ref_value (Value to_ref) [{}uint8]
- /; if (!to_ref.on_stack)
- ;return ""
- ;/
-
- ;return self.standard_op(to_ref, "lea")
- ;/
-
- /; deref_value [{}uint8]
- /; if (self._type.ptr == 0)
- ;return ""
- ;/
-
- ;Value new = self
- ;new._type.ptr = new._type.ptr - 1
- ;{}uint8 out = "\tmov ("
- ;{}uint8 tmp = self.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;out.append(')')
- ;out.append(',')
- ;out.append(' ')
- ;tmp = new.get_norm_loc()
- ;add_strings(~out, ~tmp)
-
- ;self = new
- ;return out
- ;/
-
- /; get_index (Value index) [Value]
- /; if (self._type.ptr == 0)
- ;return NV
- ;/
- ;/
-
- /; set_value (Value v) [{}uint8]
- /; if (self.literal)
- ;self.val = v.val
- ;return ""
- ;; else if (!(self.on_stack))
- /; if (!is_struct(self._type))
- ;return self.standard_op(v, "mov")
- ;/
- # This is the case where we are storing an address to
- # a struct in a register.
- ;{}charp out = "\tpush %rcx\n\tmov "
- ;{}charp tmp = self.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;tmp = ", %rcx\n"
- ;add_strings(~out, ~tmp)
- ;tmp = self.standard_op(v, "movsb")
- ;add_strings(~out, ~tmp)
- ;tmp = "\tpop %rcx"
- ;add_strings(~out, ~tmp)
- ;return out
- ;/
-
- /; if (self._type._size !> 8)
- /; if (!v.on_stack)
- ;return self.standard_op(v, "mov")
- ;/
- ;{}charp out = "\tpush %rax\n\tmov "
- ;{}charp tmp = v.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;tmp = ", %rax\n"
- ;add_strings(~out, ~tmp)
- ;tmp = self.standard_op(v, "mov")
- ;add_strings(~out, ~tmp)
- ;return out
- ;/
-
- ;/
-
- /; load_label_address ({}uint8 lab) [{}uint8]
- ;{}uint8 out = "\tlea "
- ;{}uint8 tmp = "(%rip), "
- ;add_strings(~out, ~lab)
- ;add_strings(~out, ~tmp)
- ;tmp = self.get_norm_loc()
- ;add_strings(~out, tmp)
- ;out.append('\n')
- ;return out
- ;/
-
- /; get_member_value ({}uint8 name) [Value]
- ;Value out = self
- /; if (self.on_stack)
- ;out.loc = out.loc + self._type.get_offset(name)
- ;; else
- ;out.val = out.val + self._type.get_offset(name)
- ;/
- ;out._type = self._type.get_sub_type(name)
- ;out._type.ptr = -1
- ;return out
- ;/
-
- /; mov_to_reg (int reg) [{}uint8]
- /; if (!(self.on_stack))
- ;return self.update_loc(0)
- ;/
- ;/
-
- /; update_loc(int loc) [{}uint8]
- /; if (self.on_stack)
- ;self.loc = self.loc + loc
- ;; else if (!(self.literal))
- ;{}uint8 out = "\tmov "
- ;int tsz = self._type._size
- ;self._type._size = 8
-
- ;{}uint8 tmp = self.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;out.append(',')
- ;out.append(' ')
-
- ;self.loc = loc
-
- ;tmp = self.get_norm_loc()
- ;add_strings(~out, ~tmp)
- ;out.append('\n')
-
- ;self._type._size = tsz
- ;return out
- ;/
- ;return ""
- ;/
-
-;/
-
-/; literal_val (int l, VType t) [Value]
- ;return {false, true, 0, l, t}
-;/
-
-/; track_val(VType ty, bool on_stack, int loc) [Value]
- ;return {on_stack, false, loc, 0, ty}
-;/