def make_il(self, il_code, symbol_table, c): """ Make code for this node """ symbol_table.new_scope() if self.first: self.first.make_il(il_code, symbol_table, c) start = il_code.get_label() cont = il_code.get_label() end = il_code.get_label() c = c.set_continue(cont).set_break(end) il_code.add(control_cmds.Label(start)) with report_err(): if self.second: cond = self.second.make_il(il_code, symbol_table, c) il_code.add(control_cmds.JumpZero(cond, end)) with report_err(): self.stat.make_il(il_code, symbol_table, c) il_code.add(control_cmds.Label(cont)) with report_err(): if self.third: self.third.make_il(il_code, symbol_table, c) il_code.add(control_cmds.Jump(start)) il_code.add(control_cmds.Label(end)) symbol_table.end_scope()
def make_il(self, il_code, symbol_table, c): # ILValue for storing the output of this boolean operation out = ILValue(ctypes.integer) # ILValue for initial value of output variable. init = ILValue(ctypes.integer) il_code.register_literal_var(init, self.initial_value) # ILValue for other value of output variable. other = ILValue(ctypes.integer) il_code.register_literal_var(other, 1 - self.initial_value) # Label which immediately precedes the line which sets out to 0 or 1. set_out = il_code.get_label() # Label which skips the line which sets out to 0 or 1. end = il_code.get_label() err = f"'{str(self.op)}' operator requires scalar operands" left = self.left.make_il(il_code, symbol_table, c) if not left.ctype.is_scalar(): raise CompilerError(err, self.left.r) il_code.add(value_cmds.Set(out, init)) il_code.add(self.jump_cmd(left, set_out)) right = self.right.make_il(il_code, symbol_table, c) if not right.ctype.is_scalar(): raise CompilerError(err, self.right.r) il_code.add(self.jump_cmd(right, set_out)) il_code.add(control_cmds.Jump(end)) il_code.add(control_cmds.Label(set_out)) il_code.add(value_cmds.Set(out, other)) il_code.add(control_cmds.Label(end)) return out
def make_il(self, il_code, symbol_table, c): """ Make code for this node """ expr = self.expr.make_il(il_code, symbol_table, c) if not expr.ctype.is_scalar(): err = "'!' operator requires scalar operand" raise CompilerError(err, self.r) # ILValue for storing the output out = ILValue(ctypes.integer) # ILValue for zero. zero = ILValue(ctypes.integer) il_code.register_literal_var(zero, "0") # ILValue for one. one = ILValue(ctypes.integer) il_code.register_literal_var(one, "1") # Label which skips the line which sets out to 0. end = il_code.get_label() il_code.add(value_cmds.Set(out, one)) il_code.add(control_cmds.JumpZero(expr, end)) il_code.add(value_cmds.Set(out, zero)) il_code.add(control_cmds.Label(end)) return out
def make_il(self, il_code, symbol_table, c): """ Make code for this node """ start = il_code.get_label() end = il_code.get_label() il_code.add(control_cmds.Label(start)) c = c.set_continue(start).set_break(end) with report_err(): self.stat.make_il(il_code, symbol_table, c) with report_err(): cond = self.cond.make_il(il_code, symbol_table, c) il_code.add(control_cmds.JumpZero(cond, end)) il_code.add(control_cmds.Jump(start)) il_code.add(control_cmds.Label(end))
def make_il(self, il_code, symbol_table, c): """ Make code for this if statement """ endif_label = il_code.get_label() with report_err(): cond = self.cond.make_il(il_code, symbol_table, c) il_code.add(control_cmds.JumpZero(cond, endif_label)) with report_err(): self.stat.make_il(il_code, symbol_table, c) if self.else_stat: end_label = il_code.get_label() il_code.add(control_cmds.Jump(end_label)) il_code.add(control_cmds.Label(endif_label)) with report_err(): self.else_stat.make_il(il_code, symbol_table, c) il_code.add(control_cmds.Label(end_label)) else: il_code.add(control_cmds.Label(endif_label))