struct Function { ~uint8 name, utils.Vector inputs, outputs, ~parse.Node _up, } /; method Function /; init (~parse.Node n) self.name = utils.strcpy(n`.data) self._up = n Var v self.inputs.init(len v) self.outputs.init(len v) ;/ /; _resolve_dlist (~Module parent, ~parse.Node dl) ~parse.Node tn = NULL ~parse.Node n /; loop (int i = 0; i < dl`.sub.count) [i++] n = dl`.sub.get(i) /; if (n`._type == parse.NTYPE_TYPE) tn = n ;; else if (n`._type == parse.NTYPE_ID) /; if (tn == NULL) _printf("Identifier declared in parameter list before any type was found!\n\0") return ;/ Var p p.init(tn, n) p._resolve_type(parent) self.inputs.push(~p) ;/ ;/ ;/ /; _resolve_tlist (~Module parent, ~parse.Node tl) ~parse.Node n parse.Node dummy dummy.data = "### OUTPUT ###\0" /; loop (int i = 0; i < tl`.sub.count) [i++] n = tl`.sub.get(i) /; if (n`._type == parse.NTYPE_TYPE) Var r r.init(n, ~dummy) r._resolve_type(parent) self.outputs.push(~r) ;/ ;/ ;/ /; _resolve_type (~Module parent) ~parse.Node _up = self._up /; if (_up`.sub.count < 1) return ;/ ~parse.Node lst = _up`.sub.get(0) /; if (lst`._type == parse.NTYPE_DLIST) self._resolve_dlist(parent, lst) /; if (_up`.sub.count > 1) lst = _up`.sub.get(1) ;/ ;/ /; if (lst`._type == parse.NTYPE_TLIST) self._resolve_tlist(parent, lst) ;/ ;/ /; _build_func(~Module parent, ~CompBuf cb) [Scope] Scope out out.init(parent, cb, self.name) out.parent = NULL /; 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_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() ;/ /; _compile (~Module parent, ~CompBuf cb) # Sanity check ~parse.Node _up = self._up /; if (_up`.sub.count < 1) ~Scope s = self._build_func(parent, cb) self._end_func(s, cb) return ;/ # Skip past parameters and outputs int i = 0 ~parse.Node n = _up`.sub.get(i) /; if (n`._type == parse.NTYPE_DLIST) i++ /; if (_up`.sub.count > 1) n = _up`.sub.get(1) ;/ ;/ /; 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) ;/ /; _compile_statements(~Scope s, int off) ;/ /; _print (int idt) _indent(idt) _printf("{ Function : \0") _printf(self.name) _printf("\n\0") _indent(idt) _printf(" inputs:\n\0") ~Var prtv /; loop (int i = 0; i < self.inputs.count) [i++] prtv = self.inputs.get(i) prtv`._print(idt + 1) ;/ _indent(idt) _printf(" outputs:\n\0") /; loop (int i = 0; i < self.outputs.count) [i++] prtv = self.outputs.get(i) prtv`._print(idt + 1) ;/ _indent(idt) _printf("}\n\0") ;/ /; end _delete(self.name) ~Var v /; loop (int i = 0; i < self.inputs.count) [i++] v = self.inputs.get(i) v`.end() ;/ self.inputs.end() /; loop (int i = 0; i < self.outputs.count) [i++] v = self.outputs.get(i) v`.end() ;/ self.outputs.end() ;/ ;/