;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" ;/ ;return string_from_int(r + 2) ;/ /; 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.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.on_stack) ;{}uint8 out = "\tmov $0, " ;{}uint8 reg = get_reg(8, reg_by_num(self.loc)) ;add_strings(~out, ~reg) ;return out ;; else if (!self.literal) ;{}uint8 out = "\tsub $" ;{}uint8 tmp = string_from_int(self._type._size) ;add_strings(~out, ~tmp) ;out.append(',') ;out.append(' ') ;tmp = "%rsp\n" ;add_strings(~out, ~tmp) ;return out ;/ ;return "" ;/ /; standard_op(Value other, {}uint8 op) [{}uint8] ;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" ;{}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) ;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 ;/ /; arr_value (Value index, Value store) /; if (self._type.ptr == 0) ;return ;/ ;/ /; set_value (Value v) [{}uint8] /; if (self.literal) ;self.val = v.val ;return "" ;; else if (!(self.on_stack)) ;return self.standard_op(v, "mov") ;/ ;/ /; get_member_value ({}uint8 name) [Value] ;Value out = self ;out.loc = out.loc + self._type.get_offset(name) ;out._type = self._type.get_sub_type(name) ;return out ;/ /; 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 ;{}uint8 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} ;/