Esempio n. 1
0
File: actions.py Progetto: wim-c/rpl
    def push_if(self, optimizer):
        if_ = optimizer.rewind()

        # Create mark beyond END of if statement.
        self.push_then_mark(optimizer)
        end_mark = self.then_marks[-1]

        # Push statements block followed by a jump to the end mark.
        def push_if_block(block):
            goto = tokens.Command(tokens.Command.GOTO, mark=end_mark)
            optimizer.push_node(goto)
            optimizer.push_node(block)

        # Push all statements blocks but the first and prepare a THEN mark for
        # each of them.
        for block in if_.blocks[:0:-1]:
            push_if_block(block)
            self.push_then_mark(optimizer)

        # Push first statements block and a conditional jump (if false) to the
        # current THEN mark.  This will be the end mark if there are no THEN
        # statements blocks.
        mark = self.then_marks[-1]
        beq = tokens.Command(tokens.Command.BEQ, mark=mark).from_node(if_)
        push_if_block(if_.blocks[0])
        optimizer.push_node(beq)

        return True
Esempio n. 2
0
 def word_cond(self, optimizer):
     word, cond = optimizer.rewind(2)
     type = cond.get_type()
     if (type == tokens.Command.BEQ and word.value == 0) or \
             (type == tokens.Command.BNE and word.value != 0):
         node = tokens.Command(tokens.Command.GOTO,
                               command=cond).from_node(cond)
         optimizer.push_node(node)
     return True
Esempio n. 3
0
File: lexer.py Progetto: wim-c/rpl
def make_command(t):
    t.type = 'COMMAND'

    if t.value == '?':
        t.value = 'print'
    elif t.value == '&':
        t.value = 'gosub'

    t.value = tokens.Command(t.value.lower()).from_token(t)
    return t
Esempio n. 4
0
 def word_eq_cond(self, optimizer):
     word, eq, cond = optimizer.peek(3)
     if word.value != 0:
         return False
     elif cond.get_type() == tokens.Command.BEQ:
         type = tokens.Command.BNE
     else:
         type = tokens.Command.BEQ
     node = tokens.Command(type, command=cond).from_node(cond)
     optimizer.rewind(3)
     optimizer.push_node(node)
     return True
Esempio n. 5
0
 def cond_goto_mark(self, optimizer):
     cond, goto, mark = optimizer.peek(3)
     if cond.mark is not mark or goto.mark is None:
         return False
     elif cond.get_type() == tokens.Command.BEQ:
         cond_type = tokens.Command.BNE
     else:
         cond_type = tokens.Command.BEQ
     node = tokens.Command(cond_type, mark=goto.mark).from_node(cond)
     optimizer.rewind(3)
     optimizer.push_node(mark)
     optimizer.push_node(node)
     return True
Esempio n. 6
0
 def cond_return_mark(self, optimizer):
     cond, return_, mark = optimizer.peek(3)
     if cond.mark is not mark:
         return False
     elif cond.get_type() == tokens.Command.BEQ:
         cond_type = tokens.Command.RNE
     else:
         cond_type = tokens.Command.REQ
     node = tokens.Command(cond_type).from_node(cond)
     optimizer.rewind(3)
     optimizer.push_node(mark)
     optimizer.push_node(node)
     return True
Esempio n. 7
0
File: actions.py Progetto: wim-c/rpl
    def compile_proc(self, mark, statements, optimizer):
        # Create new optimizer to compile data statements
        actions = ProcActions()
        parser = actions.make_parser()
        opt = optimizer.create_new(parser)

        # Add an implicit return statement to the procedure.
        return_ = tokens.Command(tokens.Command.RETURN)
        opt.push_node(return_)

        # Push a final THEN mark as target for any CONT IF statement.
        actions.push_then_mark(opt)

        # Compile the procedure statements to a CodeBlock.  Add all blocks to
        # the optimizer.
        opt.push_node(statements)
        opt.push_node(mark)
        opt.compile_to(blocks.CodeBlock, optimizer.blocks)
Esempio n. 8
0
File: actions.py Progetto: wim-c/rpl
 def compare_not(self, optimizer):
     compare, not_ = optimizer.rewind(2)
     op = compare.get_type()
     if op == tokens.Command.LT:
         op = tokens.Command.GEQ
     elif op == tokens.Command.LEQ:
         op = tokens.Command.GT
     elif op == tokens.Command.NEQ:
         op = tokens.Command.EQ
     elif op == tokens.Command.EQ:
         op = tokens.Command.NEQ
     elif op == tokens.Command.GT:
         op = tokens.Command.LEQ
     elif op == tokens.Command.GEQ:
         op = tokens.Command.LT
     node = tokens.Command(op).from_node(not_)
     optimizer.push_node(node)
     return True
Esempio n. 9
0
File: actions.py Progetto: wim-c/rpl
    def push_program(self, optimizer):
        program = optimizer.rewind()

        # End with a mark for any contif statement and an implicit stop
        # statement.
        stop = tokens.Command(tokens.Command.STOP)
        optimizer.push_node(stop)
        self.push_then_mark(optimizer)

        # Optimize the program body statements.
        optimizer.push_node(program.statements)

        # Begin the program with an implicit preamble to invoke the byte code
        # interpreter at the provided runtime address..
        preamble = tokens.Preamble(program.rt)
        optimizer.push_node(preamble)

        # Create program level scope.
        optimizer.open_scope()

        # Program node has been reduced.
        return True
Esempio n. 10
0
def newToken(text, *args, **kwargs):
    "Returns an instance of the correct Token subclass."
    if text in operators.operators:
        return tokens.Operator(text)
    elif text in operators.commands:
        return tokens.Command(text)
    elif text[0] == "'":
        return tokens.Char(text)
    elif text[0] == '"':
        return tokens.String(text)
    elif text[:2] == '\\"':
        return tokens.EscapedString(text)
    elif text[0] == '`':
        return tokens.Pattern(text)
    elif symbolsRgx.fullmatch(text):
        return tokens.Symbol(text)
    elif nameRgx.fullmatch(text):
        return tokens.Name(text)
    elif numberRgx.fullmatch(text):
        return tokens.Number(text)
    # Others as needed
    else:
        return None
Esempio n. 11
0
 def gosub_return(self, optimizer):
     gosub, return_ = optimizer.rewind(2)
     goto = tokens.Command(tokens.Command.GOTO,
                           command=gosub).from_node(gosub)
     optimizer.push_node(goto)
     return True
Esempio n. 12
0
            return False
        elif (marked_type := marked.get_type()) != tokens.Command.RETURN and \
                (marked_type != tokens.Command.GOTO or marked.mark is None):
            # Marked command is not a RETURN and not a GOTO with a target mark.
            # Nothing to optimize.
            return False

        # Replace conditional branch by a new conditional node.
        optimizer.rewind()

        # Get the branch type (either BEQ or BNE).
        cond_type = cond.get_type()

        if marked_type == tokens.Command.GOTO:
            # Replace branch to a GOTO by a short circuited branch.
            node = tokens.Command(cond_type, mark=marked.mark)
        elif cond_type == tokens.Command.BEQ:
            # Replace BEQ to a RETURN by a REQ.
            node = tokens.Command(tokens.Command.REQ)
        else:
            # Replace BNE to a RETURN by a RNE.
            node = tokens.Command(tokens.Command.RNE)

        node.from_node(cond)
        optimizer.push_node(node)
        return True

    def push_gosub(self, optimizer):
        gosub = optimizer.peek()
        if (mark := gosub.mark) is None or \
                (marked := mark.marked) is None:
Esempio n. 13
0
File: actions.py Progetto: wim-c/rpl
 def push_if_block(block):
     goto = tokens.Command(tokens.Command.GOTO, mark=end_mark)
     optimizer.push_node(goto)
     optimizer.push_node(block)
Esempio n. 14
0
File: actions.py Progetto: wim-c/rpl
 def push_contif(self, optimizer):
     contif = optimizer.rewind()
     mark = self.then_marks[-1]
     beq = tokens.Command(tokens.Command.BEQ, mark=mark).from_node(contif)
     optimizer.push_node(beq)
     return True
Esempio n. 15
0
 def p_contif(self, p):
     'contif : CONT IF'
     p[0] = tokens.Command(tokens.Command.CONTIF).from_node(p[1])