struct Scope { ~uint8 name, ~Module mod, ~CompBuf cb, ~Scope parent, utils.Vector 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) ;/ /; end _delete(self.name) ~Var v /; loop (int i = 0; i < self.vars.count) [i++] v = self.vars.get(i) v`.end() ;/ self.vars.end() ;/ # # Make variables # /; _next_reg_slot [int] int out = 11 /; if (self.parent !== NULL) out = self.parent`._next_reg_slot() ;/ /; if (out < 0) return out ;/ ~Var v /; loop (int i = 0; i < self.vars.count) [i++] v = self.vars.get(i) /; if (v`.loc > 0) out++ /; if (out > 16) return 0 - 1 ;/ ;/ ;/ return out ;/ /; _next_stack_slot [int] int out = 0 - 56 /; if (self.parent !== NULL) out = self.parent`._next_stack_slot() ;/ ~Var v /; loop (int i = 0; i < self.vars.count) [i++] v = self.vars.get(i) /; if (v`.loc < 0) out = out - v`.actual_size() ;/ ;/ return out ;/ /; mk_aware (~Var v) Var mk = v`.copy() mk.offset = 0 # TODO: Make sure this works properly /; if (mk.loc > 0) mk.loc = 1 ;/ self.vars.push(~mk) ;/ /; mk_aware_node (~parse.Node n) ~parse.Node sub ~parse.Node tp = NULL /; loop (int i = 0; i < n`.sub.count) [i++] sub = n`.sub.get(i) /; if (n`._type == parse.NTYPE_TYPE) tp = n ;; else if (n`._type == parse.NTYPE_ID) /; if (tp == NULL) _printf("COMPILER ERROR: Should have type node before first id in decl node\n\0") return ;/ # Part 1: Add var Var v v.init(tp, n`.data) v._resolve_type(self.mod) # TODO: Make sure this works properly /; if (v.regable() == true) v.loc = 1 ;; else v.loc = 0 - 1 ;/ v.offset = 0 self.vars.push(~v) # Part 2: Compute via value (if exists) /; if (n`.sub.count > 0) n = n`.sub.get(0) /; if (n`._type == parse.NTYPE_VALUE) self.precheck_stmt(n) ;/ ;/ ;/ ;/ ;/ /; precheck_stmt (~parse.Node n) ;/ /; find_var (~uint8 name) [~Var] ~Var v /; loop (int i = 0; i < self.vars.count) [i++] v = self.vars.get(i) /; if (utils.strcmp(v`.name, name) == true) /; if (v`.loc > 1 || v`.offset !== 0) return v ;/ ;/ ;/ /; if (self.parent !== NULL) return self.parent`.find_var(name) ;/ return NULL ;/ /; mk_set_var (~Var src) ~Var v = self.find_var(src`.name) /; if (v == NULL) return ;/ /; if (v`.loc == 1) v`.loc = self._next_reg_slot() /; if (v`.loc + 1 == 0) v`.offset = self._next_stack_slot() ;/ ;; else if (v`.loc + 1 == 0) /; if (v`.offset == 0) v`.loc = 0 - 1 v`.offset = self._next_stack_slot() ;/ ;/ ~int32 p = v`.top_ptrc() /; if (p == NULL) v`.set(self.cb, src) ;; else if (p` == 0) v`.set_ref(self.cb, src) ;; else v`.set(self.cb, src) ;/ ;/ # # 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) ;/ ;/