コード例 #1
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_assign_to(self, src, context):
        out = ''
        type = context.get_type(self.type_name)
        offset = type.get_field_offset(self.field_name)

        basecalc, base_dest = self.base.emit_with_dest(context)
        out += basecalc

        loc = None
        if offset == 0:
            loc = base_dest
        elif offset == 4:
            loc = base_dest.with_flag(asm.DataFlag.PLUSFOUR)
        else:
            out += asm.Instruction(asm.Opcode.ADD, [
                base_dest,
                asm.DataLoc(asm.LocType.CONST, asm.ConstWord(offset)),
                TEMPSTACK
            ]).emit()
            loc = TEMPSTACK

        out += asm.Instruction(asm.Opcode.MOVE,
                               [src, loc.with_flag(asm.DataFlag.MEM)]).emit()

        return out
コード例 #2
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_with_dest(self, context):

        type = context.get_type(self.type_name)
        if type is None:
            raise Exception("Type {} does not exist in context {}".format(
                self.type_name, context))
        offset = type.get_field_offset(self.field_name)
        out = ''
        basecalc, base_dest = self.base.emit_with_dest(context)
        out += basecalc

        loc = None
        if offset == 0:
            loc = base_dest
        elif offset == 4:
            loc = base_dest.with_flag(asm.DataFlag.PLUSFOUR)
        else:
            out += asm.Instruction(asm.Opcode.ADD, [
                base_dest,
                asm.DataLoc(asm.LocType.CONST, asm.ConstWord(offset)),
                TEMPSTACK
            ]).emit()
            loc = TEMPSTACK

        #out += asm.Instruction(asm.Opcode.ADD, [base_dest, asm.DataLoc(asm.LocType.CONST, asm.ConstWord(offset)), TEMPSTACK]).emit()

        return (out, loc.with_flag(asm.DataFlag.MEM))
コード例 #3
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_with_dest(self, context):
        argcalcs = []
        dests = []
        for arg in self.args:
            calc, dest = arg.emit_with_dest(context)
            argcalcs.append(calc)

            dests.append(dest)

        # If the function returns a value, it's going to have to be cleared off of the
        # function result stack one way or another.
        try:
            has_result = context.does_fn_return_value(self.fname)
        except SymbolNotRegisteredException:
            # We don't know about this function, we'll just have to assume the user knows best.
            # The safe default is to not cause a stack underflow.
            has_result = False

        if has_result:
            result_dest = RESULT_STACK
        else:
            result_dest = ZERO_WORD

        func_loc = context.get_loc_for_name(self.fname)

        call = asm.Instruction(asm.Opcode.FUNCCALL, [func_loc] + dests)
        return (''.join(argcalcs) + call.emit(), result_dest)
コード例 #4
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit(self, context):
     out = ''
     calc, dest = self.expr.emit_with_dest(context)
     out += calc
     if self.expr.must_read_result(context):
         # out += asm.Instruction(asm.Opcode.MOVE, [dest, asm.DataLoc(asm.LocType.CONST, asm.ConstWord(0))]).emit()
         out += asm.Instruction(asm.Opcode.READ, [dest]).emit()
     return out
コード例 #5
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_jump_true(self, dest, context):
        out = ''
        if type(self.b) is ConstExpr and self.b.has_value(0):
            acalc, adest = self.a.emit_with_dest(context)
            out += acalc
            out += asm.Instruction(asm.Opcode.JUMPZERO, [adest, dest]).emit()
            return out

        elif type(self.b) is ConstExpr and self.b.has_value('ZZZZ'):
            acalc, adest = self.a.emit_with_dest(context)
            out += acalc
            out += asm.Instruction(
                asm.Opcode.JUMPZERO,
                [adest.with_flag(asm.DataFlag.NEG), dest]).emit()
            return out
        else:
            return super().emit_jump_true(dest, context)
コード例 #6
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_jump_false(self, jump_dest, context):
        out = ''
        calc, calc_dest = self.emit_with_dest(context)

        out += calc
        out += asm.Instruction(asm.Opcode.JUMPZERO,
                               [calc_dest, jump_dest]).emit()

        return out
コード例 #7
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_jump_true(self, jump_dest, context):
        '''Emits code that jumps to a location if the expr is truthy.'''
        out = ''
        calc, calc_dest = self.emit_with_dest(context)

        out += calc
        out += asm.Instruction(asm.Opcode.JUMPGREATER,
                               [calc_dest, ZERO_WORD, jump_dest]).emit()

        return out
コード例 #8
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit_with_dest(self, context):
        out = ''
        equal_label = asm.AnonLabel('equal')
        equaldone_label = asm.AnonLabel('equal_done')

        acalc, adest = self.a.emit_with_dest(context)
        bcalc, bdest = self.b.emit_with_dest(context)
        out += asm.comment("Begin equality check")

        out += bcalc  # Eval B
        out += acalc  # Eval A

        out += self.emit_conditional(adest, bdest, equal_label.as_dataloc())

        out += asm.Instruction(asm.Opcode.MOVE, [ZERO_WORD, TEMPSTACK]).emit()
        out += asm.Jump(equaldone_label.as_dataloc()).emit()

        out += equal_label.emit()
        out += asm.Instruction(asm.Opcode.MOVE, [MAX_WORD, TEMPSTACK]).emit()
        out += equaldone_label.emit()
        out += asm.comment("End equality check")

        return (out, TEMPSTACK)
コード例 #9
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit(self, context):
     if self.expr:
         out = ''
         calc, dest = self.expr.emit_with_dest(context)
         out += calc
         # If the calc dest is already the return stack,
         # it's really just a waste of time to move it.
         if dest == RESULT_STACK:
             out += asm.comment("Omitting return move")
         else:
             out += asm.Instruction(asm.Opcode.MOVE,
                                    [dest, RESULT_STACK]).emit()
         out += asm.Jump(RETURN_LOC).emit()
         return out
     else:
         return asm.Jump(RETURN_LOC).emit()
コード例 #10
0
ファイル: ast.py プロジェクト: thestuckster/4LW
    def emit(self, context):
        if 'returns' in self.options:
            context.register_fn(self.name, True)
        else:
            context.register_fn(self.name, False)
        c = Context(parent=context, name="Function {}".format(self.name))
        move_args = ''
        # Args are pushed backwards
        for arg in reversed(self.args):
            c.make_var(arg)
            reg = c.get_loc_for_name(arg)
            move_args += asm.Instruction(asm.Opcode.MOVE,
                                         [ARGSTACK, reg]).emit()

        inner = move_args + self.sequence.emit(c)
        to_preserve = c.get_used_regs()
        context.inherit(c)
        return asm.Function(self.name, inner, preserving=to_preserve).emit()
コード例 #11
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_assign_to(self, src, context):
     return asm.Instruction(
         asm.Opcode.MOVE,
         [src,
          asm.DataLoc(asm.LocType.TAPE, asm.ConstWord(self.letter))
          ]).emit()
コード例 #12
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_assign_to(self, src, context):
     return asm.Instruction(asm.Opcode.MOVE,
                            [src, asm.DataLoc(asm.LocType.IO)]).emit()
コード例 #13
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_assign_to(self, src, context):
     assert type(src) is asm.DataLoc
     loccalc, locto = self.loc.emit_with_dest(context)
     refloc = locto.with_flag(asm.DataFlag.MEM)
     return loccalc + asm.Instruction(asm.Opcode.MOVE, [src, refloc]).emit()
コード例 #14
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_conditional(self, aloc, bloc, successloc):
     return asm.Instruction(asm.Opcode.AND, [aloc, bloc, successloc]).emit()
コード例 #15
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_with_dest(self, context):
     acalc, adest = self.a.emit_with_dest(context)
     bcalc, bdest = self.b.emit_with_dest(context)
     ins = asm.Instruction(self.opcode(), [adest, bdest, TEMPSTACK])
     return ("{}{}{}".format(acalc, bcalc, ins.emit()), TEMPSTACK)
コード例 #16
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit(self, context):
     return asm.Instruction(asm.Opcode.NOP).emit()
コード例 #17
0
ファイル: ast.py プロジェクト: thestuckster/4LW
 def emit_assign_to(self, src, context):
     assert type(src) is asm.DataLoc
     var_reg = context.get_reg_for_var(self.name)
     return asm.Instruction(
         asm.Opcode.MOVE,
         [src, context.get_loc_for_name(self.name)]).emit()