summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tnslc/compile/function.tnsl63
-rw-r--r--tnslc/compile/module.tnsl2
-rw-r--r--tnslc/compile/scope.tnsl136
-rw-r--r--tnslc/utils/algo.tnsl2
4 files changed, 179 insertions, 24 deletions
diff --git a/tnslc/compile/function.tnsl b/tnslc/compile/function.tnsl
index a768596..bf06f80 100644
--- a/tnslc/compile/function.tnsl
+++ b/tnslc/compile/function.tnsl
@@ -70,30 +70,49 @@ struct Function {
;/
;/
- /; _fqn (~Module parent) [~uint8]
- utils.Vector out
-
- return out.as_cstr()
- ;/
-
- /; _build_scope(~Module parent, ~CompBuf cb) [Scope]
- ~uint8 fqn = self._fqn(parent)
+ /; _build_func(~Module parent, ~CompBuf cb) [Scope]
Scope out
- out.init(parent, cb, fqn)
+ out.init(parent, cb, self.name)
out.parent = NULL
- _delete(fqn)
- # TODO: Write label to cb
- # TODO: Push all saved vars and deal with parameters
+ /; if (parent`.e == true)
+ # Add to the global exports if the parent is exported
+ ~uint8 bl = out.base_label()
+ cb`.add_h("global \0")
+ cb`.add_h(bl)
+ cb`.add_h("\n\0")
+ _delete(bl)
+ ;/
+
+ # Write label and opening
+ out.place_base_label()
+ cb`.add_c(" push rbp\n\0")
+ cb`.add_c(" lea rbp, [rsp + 8]\n\0")
+ cb`.add_c(" push r10\n\0")
+ cb`.add_c(" push r11\n\0")
+ cb`.add_c(" push r12\n\0")
+ cb`.add_c(" push r13\n\0")
+ cb`.add_c(" push r14\n\0")
+ cb`.add_c(" push r15 ; scope init\n\n\0")
+
# TODO: Add all params to the scope
return out
;/
- /; _end_scope(~Scope scope, ~CompBuf cb)
+ /; _end_func(~Scope scope, ~CompBuf cb)
# TODO: place jmp label
# TODO: pop all saved vars
# TODO: ret
+ cb`.add_c(" lea rsp, [rbp - 56]\n\0")
+ cb`.add_c(" pop r15\n\0")
+ cb`.add_c(" pop r14\n\0")
+ cb`.add_c(" pop r13\n\0")
+ cb`.add_c(" pop r12\n\0")
+ cb`.add_c(" pop r11\n\0")
+ cb`.add_c(" pop r10\n\0")
+ cb`.add_c(" pop rbp\n\0")
+ cb`.add_c(" ret ; scope end\n\n\n\0")
scope`.end()
;/
@@ -102,8 +121,8 @@ struct Function {
# Sanity check
~parse.Node _up = self._up
/; if (_up`.sub.count < 1)
- ~Scope s = self._build_scope(parent, cb)
- self._end_scope(s, cb)
+ ~Scope s = self._build_func(parent, cb)
+ self._end_func(s, cb)
return
;/
@@ -120,11 +139,17 @@ struct Function {
/; if (n`._type == parse.NTYPE_TLIST)
i++
;/
+
+ # Create scope
+ Scope fscope = self._build_func(parent, cb)
+
+
+ # Compile and then end scope
+ self._compile_statements(~fscope, i)
+ self._end_func(~fscope, cb)
+ ;/
- # Create scope and start compiling statements from here.
- Scope fscope = self._build_scope(parent, cb)
- fscope._compile_statements(_up, i)
- self._end_scope(~fscope, cb)
+ /; _compile_statements(~Scope s, int off)
;/
/; _print (int idt)
diff --git a/tnslc/compile/module.tnsl b/tnslc/compile/module.tnsl
index 0cfaa37..38653da 100644
--- a/tnslc/compile/module.tnsl
+++ b/tnslc/compile/module.tnsl
@@ -30,6 +30,8 @@ struct Module {
Function f
Module m
+ self.parent = NULL
+
self.vars.init(len v)
self.structs.init(len s)
self.funcs.init(len f)
diff --git a/tnslc/compile/scope.tnsl b/tnslc/compile/scope.tnsl
index f4eefdd..c152d00 100644
--- a/tnslc/compile/scope.tnsl
+++ b/tnslc/compile/scope.tnsl
@@ -6,22 +6,50 @@ struct Scope {
~Scope parent,
utils.Vector
- vars
+ vars,
+
+ int unique
}
+/; _recursive_mod_name(~Module mod, ~utils.Vector vec)
+ ~Module p = mod`.parent
+ /; if (p !== NULL)
+ _recursive_mod_name(p, vec)
+ /; if (vec`.count !== 0)
+ vec`.push_char('.')
+ ;/
+ ;/
+ vec`.push_cstr(mod`.name)
+;/
+
+/; _recursive_scope_name(~Scope s, ~utils.Vector vec)
+ ~void p = s`.parent
+ /; if (p == NULL)
+ ~void m = s`.mod
+ /; if (m !== NULL)
+ _recursive_mod_name(m, vec)
+ /; if (vec`.count > 0)
+ vec`.push_char('.')
+ ;/
+ ;/
+ ;; else
+ _recursive_scope_name(p, vec)
+ ;/
+ vec`.push_cstr(s`.name)
+;/
+
/; method Scope
/; init (~Module mod, ~CompBuf cb, ~uint8 name)
self.name = utils.strcpy(name)
self.mod = mod
self.cb = cb
+ self.parent = NULL
+ self.unique = 0
Var v
self.vars.init(len v)
;/
- /; _compile_statements (~parse.Node up, int o)
- ;/
-
/; end
_delete(self.name)
@@ -30,6 +58,106 @@ struct Scope {
v = self.vars.get(i)
v`.end()
;/
+ self.vars.end()
+ ;/
+
+ #
+ # Sub scope
+ #
+
+ /; mk_sub (~uint8 name) [Scope]
+ Scope out
+ out.init(self.mod, self.cb, name)
+ out.parent = ~self
+ return out
+ ;/
+
+ # Generate a garantueed unique name for the sub scope, using
+ # the provided name as a base
+ /; gen_sub(~uint8 name) [Scope]
+ utils.Vector true_name
+ true_name.init(1)
+
+ # Append a 'unique' number
+ ~uint8 u = utils.int_to_str(self.unique)
+ true_name.push_char('#')
+ true_name.push_cstr(u)
+ true_name.push_char('#')
+ true_name.push_cstr(name)
+ _delete(u)
+
+ Scope out = self.mk_sub(true_name.as_cstr())
+ true_name.end()
+
+ # Inc for subsequent names
+ self.unique++
+
+ return out
+ ;/
+
+ #
+ # Label generation
+ #
+
+
+ /; _base_label [utils.Vector]
+ utils.Vector out
+ out.init(1)
+
+ _recursive_scope_name(~self, ~out)
+
+ return out
+ ;/
+
+ /; base_label [~uint8]
+ utils.Vector v = self._base_label()
+ return v.as_cstr()
+ ;/
+
+ /; place_base_label
+ ~uint8 bl = self.base_label()
+ self.cb`.add_c(bl)
+ self.cb`.add_c(":\n\0")
+ _delete(bl)
+ ;/
+
+ /; start_label [~uint8]
+ utils.Vector v = self._base_label()
+ v.push_cstr("#start\0")
+ return v.as_cstr()
+ ;/
+
+ /; place_start_label
+ ~uint8 sl = self.start_label()
+ self.cb`.add_c(sl)
+ self.cb`.add_c(":\n\0")
+ _delete(sl)
+ ;/
+
+ /; rep_label [~uint8]
+ utils.Vector v = self._base_label()
+ v.push_cstr("#rep\0")
+ return v.as_cstr()
+ ;/
+
+ /; place_rep_label
+ ~uint8 rl = self.rep_label()
+ self.cb`.add_c(rl)
+ self.cb`.add_c(":\n\0")
+ _delete(rl)
+ ;/
+
+ /; end_label [~uint8]
+ utils.Vector v = self._base_label()
+ v.push_cstr("#end\0")
+ return v.as_cstr()
+ ;/
+
+ /; place_end_label
+ ~uint8 el = self.end_label()
+ self.cb`.add_c(el)
+ self.cb`.add_c(":\n\0")
+ _delete(el)
;/
;/
diff --git a/tnslc/utils/algo.tnsl b/tnslc/utils/algo.tnsl
index 35ac35c..49c4636 100644
--- a/tnslc/utils/algo.tnsl
+++ b/tnslc/utils/algo.tnsl
@@ -150,7 +150,7 @@
/; loop (i > 0) [i = i / 16]
int n = i % 16
/; if (n > 9)
- out.push_char('a' + n - 10)
+ out.push_char('A' + n - 10)
;; else
out.push_char('0' + n)
;/