Example #1
0
def pragmaSpace(ppt, line, result):
    "Reserves space in a data segment for a variable"
    lbl = line.expect("LABEL").value
    size = line.expect("NUM").value
    line.expect("EOL")
    result.append(IR.Node(ppt, "Label", lbl, IR.PCExpr()))
    result.append(IR.Node(ppt, "SetPC",
                          IR.SequenceExpr([IR.PCExpr(), "+",
                                           IR.ConstantExpr(size)])))
Example #2
0
 def visitZPRelative(self, node, env):
     (opcode, tested, expr) = node.data
     arg = expr.value(env)
     arg = arg - (env.getPC() + 3)
     if arg < -128 or arg > 127:
         # Otherwise, we replace it with a 'macro' of sorts by hand:
         # $branch LOC -> $reversed_branch ^+6; JMP LOC
         # We don't use temp labels here because labels need to have
         # been fixed in place by this point, and JMP is always 3
         # bytes long.
         expansion = [IR.Node(node.ppt, "ZPRelative",
                              ExtendBranches.reversed[opcode],
                              tested,
                              IR.SequenceExpr([IR.PCExpr(), "+",
                                               IR.ConstantExpr(6)])),
                      IR.Node(node.ppt, "Absolute", 'jmp', expr, None)]
         node.nodetype = 'SEQUENCE'
         node.data = expansion
         if Cmd.warn_on_branch_extend:
             print>>sys.stderr, str(node.ppt) + ": WARNING: " + \
                 opcode + " out of range, " \
                 "replacing with " + \
                 ExtendBranches.reversed[opcode] + \
                 "/jmp combo"
         self.changed = True
         node.accept(self, env)
     else:
         PCTracker.visitZPRelative(self, node, env)
Example #3
0
 def visitRelative(self, node, env):
     (opcode, expr) = node.data[:2]
     arg = expr.value(env)
     arg = arg - (env.getPC() + 2)
     if arg < -128 or arg > 127:
         if Cmd.enable_4502_exts:
             node.nodetype = "RelativeLong"
             if Cmd.warn_on_branch_extend:
                 print(str(node.ppt) + ": WARNING: " \
                     "branch out of range, replacing with 16-bit relative branch", file=sys.stderr)
         else:
             if opcode == 'bra':
                 # If BRA - BRanch Always - is out of range, it's a JMP.
                 node.data = ('jmp', expr, None)
                 node.nodetype = "Absolute"
                 if Cmd.warn_on_branch_extend:
                     print(str(node.ppt) + ": WARNING: " \
                         "bra out of range, replacing with jmp", file=sys.stderr)
             else:
                 # Otherwise, we replace it with a 'macro' of sorts by hand:
                 # $branch LOC -> $reversed_branch ^+5; JMP LOC
                 # We don't use temp labels here because labels need to have
                 # been fixed in place by this point, and JMP is always 3
                 # bytes long.
                 expansion = [
                     IR.Node(
                         node.ppt, "Relative",
                         ExtendBranches.reversed[opcode],
                         IR.SequenceExpr(
                             [IR.PCExpr(), "+",
                              IR.ConstantExpr(5)]), None),
                     IR.Node(node.ppt, "Absolute", 'jmp', expr, None)
                 ]
                 node.nodetype = 'SEQUENCE'
                 node.data = expansion
                 if Cmd.warn_on_branch_extend:
                     print(str(node.ppt) + ": WARNING: " + \
                                    opcode + " out of range, " \
                                    "replacing with " + \
                                    ExtendBranches.reversed[opcode] + \
                                    "/jmp combo", file=sys.stderr)
                 self.changed = True
                 node.accept(self, env)
     else:
         PCTracker.visitRelative(self, node, env)
Example #4
0
 def atom():
     "Parses lowest-priority expression components."
     global templabelcount
     next = line.lookahead(0).type
     if next == "NUM":
         return IR.ConstantExpr(line.expect("NUM").value)
     elif next in ["LABEL", "X", "Y", "Z", "SP", "OPCODE"]:
         return IR.LabelExpr(line.expect("LABEL").value)
     elif next == "^":
         line.expect("^")
         return IR.PCExpr()
     elif next == "[":
         line.expect("[")
         result = parse_expr(line)
         line.expect("]")
         return result
     elif next == "+":
         offset = 0
         while next == "+":
             offset += 1
             line.expect("+")
             next = line.lookahead(0).type
         return IR.LabelExpr("*" + str(templabelcount + offset))
     elif next == "-":
         offset = 1
         while next == "-":
             offset -= 1
             line.expect("-")
             next = line.lookahead(0).type
         return IR.LabelExpr("*" + str(templabelcount + offset))
     elif next == ">":
         line.expect(">")
         return IR.HighByteExpr(atom())
     elif next == "<":
         line.expect("<")
         return IR.LowByteExpr(atom())
     else:
         Err.log('Expected: expression')
Example #5
0
 def aux():
     "Accumulates all IR nodes defined by this line."
     if line.lookahead(0).type == "EOL":
         pass
     elif line.lookahead(1).type == ":":
         newlabel = line.expect("LABEL").value
         line.expect(":")
         result.append(IR.Node(ppt, "Label", newlabel, IR.PCExpr()))
         aux()
     elif line.lookahead(0).type == "*":
         global templabelcount
         templabelcount = templabelcount + 1
         result.append(
             IR.Node(ppt, "Label", "*" + str(templabelcount), IR.PCExpr()))
         line.expect("*")
         aux()
     elif line.lookahead(0).type == "." or line.lookahead(0).type == "`":
         which = line.expect(".", "`").type
         if (which == "."):
             pragma = line.expect("LABEL").value
         else:
             pragma = "invoke"
         pragmaFunction = "pragma" + pragma.title()
         for mod in pragma_modules:
             if hasattr(mod, pragmaFunction):
                 getattr(mod, pragmaFunction)(ppt, line, result)
                 break
         else:
             Err.log("Unknown pragma " + pragma)
     else:  # Instruction
         opcode = line.expect("OPCODE").value
         arg2 = None
         if line.lookahead(0).type == "#":
             mode = "Immediate"
             line.expect("#")
             arg = parse_expr(line)
             line.expect("EOL")
         elif line.lookahead(0).type == "(":
             line.expect("(")
             arg = parse_expr(line)
             if line.lookahead(0).type == ",":
                 line.expect(",")
                 if line.lookahead(0).type == "X":
                     mode = "PointerX"
                     line.expect("X")
                     line.expect(")")
                     line.expect("EOL")
                 else:
                     mode = "PointerSPY"
                     line.expect("SP")
                     line.expect(")")
                     line.expect(",")
                     line.expect("Y")
                     line.expect("EOL")
             else:
                 line.expect(")")
                 tok = line.expect(",", "EOL").type
                 if tok == "EOL":
                     mode = "Pointer"
                 else:
                     if line.lookahead(0).type == "Y":
                         mode = "PointerY"
                         line.expect("Y")
                         line.expect("EOL")
                     else:
                         mode = "PointerZ"
                         line.expect("Z")
                         line.expect("EOL")
         elif line.lookahead(0).type == "EOL":
             mode = "Implied"
             arg = None
         else:
             arg = parse_expr(line)
             tok = line.expect("EOL", ",").type
             if tok == ",":
                 # Parser has to special-case the BBXn instructions,
                 # Which uniquely take two addresses
                 if opcode[:3] in ["bbs", "bbr"]:
                     arg2 = parse_expr(line)
                     mode = "Memory2"
                 else:
                     tok = line.expect("X", "Y", "Z").type
                     if tok == "X":
                         mode = "MemoryX"
                     elif tok == "Y":
                         mode = "MemoryY"
                     else:
                         mode = "MemoryZ"
                 line.expect("EOL")
             else:
                 mode = "Memory"
         result.append(IR.Node(ppt, mode, opcode, arg, arg2))
    def aux():
        "Accumulates all IR nodes defined by this line."
        if line.lookahead(0).type == "EOL":
            pass
        elif line.lookahead(1).type == ":":
            newlabel = line.expect("LABEL").value
            line.expect(":")
            result.append(IR.Node(ppt, "Label", newlabel, IR.PCExpr()))
            aux()
        elif line.lookahead(0).type == "*":
            global templabelcount
            templabelcount = templabelcount + 1
            result.append(
                IR.Node(ppt, "Label", "*" + str(templabelcount), IR.PCExpr()))
            line.expect("*")
            aux()
        elif line.lookahead(0).type == "." or line.lookahead(0).type == "`":
            which = line.expect(".", "`").type
            if (which == "."): pragma = line.expect("LABEL").value
            else: pragma = "invoke"
            pragmaFunction = "pragma" + pragma.title()
            for mod in pragma_modules:
                if hasattr(mod, pragmaFunction):
                    getattr(mod, pragmaFunction)(ppt, line, result)
                    break
            else:
                Err.log("Unknown pragma " + pragma)

        else:  # Instruction
            opcode = line.expect("OPCODE").value
            if line.lookahead(0).type == "#":
                mode = "Immediate"
                line.expect("#")
                arg = parse_expr(line)
                line.expect("EOL")
            elif line.lookahead(0).type == "(":
                line.expect("(")
                arg = parse_expr(line)
                if line.lookahead(0).type == ",":
                    mode = "IndirectX"
                    line.expect(",")
                    line.expect("X")
                    line.expect(")")
                    line.expect("EOL")
                else:
                    line.expect(")")
                    tok = line.expect(",", "EOL").type
                    if tok == "EOL":
                        mode = "Indirect"
                    else:
                        mode = "IndirectY"
                        line.expect("Y")
                        line.expect("EOL")
            elif line.lookahead(0).type == "EOL":
                mode = "Implied"
                arg = None
            else:
                arg = parse_expr(line)
                tok = line.expect("EOL", ",").type
                if tok == ",":
                    tok = line.expect("X", "Y").type
                    if tok == "X": mode = "MemoryX"
                    else: mode = "MemoryY"
                    line.expect("EOL")
                else:
                    mode = "Memory"
            result.append(IR.Node(ppt, mode, opcode, arg))