From d3dfc56318829e212a87da6874011d8304be31b0 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Sun, 6 Aug 2023 03:00:18 -0400 Subject: Frame out port of compiler --- tnslc/compiler.tnsl | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 tnslc/compiler.tnsl (limited to 'tnslc/compiler.tnsl') diff --git a/tnslc/compiler.tnsl b/tnslc/compiler.tnsl new file mode 100644 index 0000000..ab43e6b --- /dev/null +++ b/tnslc/compiler.tnsl @@ -0,0 +1,275 @@ +# Actual compilation of the vector of tokens, ported from the "dirty tnsl" +# that was originally written for the interpreter + +# CompData represents three vectors: +# hsec - the heading of the output assembly +# dsec - the data tied to the assembly +# csec - the .text section that is the code of the assembly +struct CompData { + Vector + hsec, + dsec, + csec +} + +/; method CompData + /; start + self.hsec.start(1) + self.dsec.start(1) + self.csec.start(1) + ;/ + + /; add (CompData c) + self.hsec.add(c.hsec) + self.dsec.add(c.dsec) + self.csec.add(c.csec) + ;/ + + /; _del + self.hsec._del() + self.dsec._del() + self.csec._del() + ;/ +;/ + +# Path represents the actual path of a file +# that we are trying to tokenize +# Assumes that the last item in the path array is a file name +struct Path { + int + path_count, + ~~uint8 + split_path +} + +/; method Path + /; start (~uint8 path) + self.split_path = _alloc(8) + self.split_path{0} = _alloc(1) + self.path_count = 1 + + int i = 0 + int j = cstr_len(path) + + /; loop (i < j) [i++] + /; if (path{i} == '\\' || path{i} == '/') + + ;/ + ;/ + ;/ + + /; copy [Path] + Path out + out.start(self.full_path()) + ;/ + + /; sub_folder (~uint8 sub) + ~uint8 file_name + ;/ + + /; relative_file(~uint8 rel_pth) [Path] + + ;/ + + /; full_path [~uint8] + ~uint8 pth = _alloc(1) + + /; loop (pth) + + ;/ + ;/ + + /; open_read [~void] + ~uint8 path = self.full_path() + ~void out = _open_file(path) + _delete(path) + return out + ;/ + + /; open_write [~void] + ~uint8 path = self.full_path() + ~void out = _create_file(path) + _delete(path) + return out + ;/ + + /; _del + /; loop (int i = 0; i < self.path_count) [i++] + _delete(self.split_path{i}) + ;/ + + _delete(self.split_path) + ;/ +;/ + + +# +# Actual compiler code -- here be dragons +# + +# Types of pointers the compiler may generate or work with +enum PTR_TYPE [uint] { + POINTER = 0, + REFERENCE = 1, + ARRAY = 2 +} + +# Represents a type of a variable +struct Type { + int + s, # size of type (bytes) + p_ct, # ptr_chain count + m_ct, # member count + ~uint8 + name, # name of the type + ~uint + ptr_chain, # for every pointer augment on the type, give it an extra PTR_TYPE in the chain + ~Variable + members, # member variables (their types and names) + ~Module + mod # the methods (if any) that are associated with this type +} + +/; method Type + /; start + + ;/ + + /; size [int] + /; loop (int i = 0; i < self.p_ct) [i++] + /; if (self.ptr_chain{i} == PTR_TYPE.REFERENCE) + return 8 + ;/ + ;/ + return self.s + ;/ + + /; _del + _delete(self.name) + _delete(self.ptr_chain) + _delete(self.members) + _delete(self.mod) + ;/ +;/ + +/; NO_TYPE [Type] + Type t + t.s = 0 + t.name = 0 + t.ptr_chain = 0 + t.members = 0 + t.mod = 0 + return t +;/ + +/; is_primitive (~uint8 name) + +;/ + +# Location type represents the type of memory +# that the variable is stored in +enum LOCATION [uint] { + REGISTER = 0, + STACK = 1, + LABEL = 2, + LITERAL = 3 +} + +# The Big Kahuna +struct Variable { + ~uint8 + name, + Type + _type, + uint + location, # Actual location. If literal, the literal value. + # If register, corrosponds to a register name. + # If stack, represents the offset from the base pointer + # Ignore if label. + loc_type +} + +# I hate c-like strings. Hopefully once I'm done with this +# language I'll have something that doesn't use them + + +# This part sucks ass +/; method Variable + +;/ + +# Scopes +struct Scope { + int + num, + c, # Figure it out yourself + tmp, + ~Scope + parent, + ~uint8 + name +} + +/; method Scope + +;/ + +struct Function { + ~uint8 + name, + ~Type + inputs, + Type + output, + ~Module mod +} + +/; method Function + +;/ + +struct Module { + ~Module + parent, + bool + exp, # Export functions or not + ~uint8 + name, + ~Type + types, # Types defined in this module + ~Variable + defs, # Variables defined in this module + ~Function + functions, # Functions defined in this module + ~Module + sub # Sub modules +} + +/; method Module + +;/ + +# +# Actual compiler functions +# + +# Used in the first pass +/; get_type_P1 + +;/ + +/; get_type_P2 + +;/ + +/; get_artifact [~~uint8] + +;/ + +/; is_call [bool] + +;/ + +/; is_definition + +;/ \ No newline at end of file -- cgit v1.2.3