def createBreak(self, breakStatement, lineno): n = Jump(Token.BREAK, lineno) jumpStatement = None#Jump() t = breakStatement.getType() if (t == Token.LOOP) or (t == Token.LABEL): jumpStatement = breakStatement else: if (t == Token.BLOCK) and (breakStatement.getFirstChild().getType() == Token.SWITCH): jumpStatement = breakStatement.getFirstChild() else: raise Kit.codeBug() n.setJumpStatement(jumpStatement) return n
def addSwitchCase(self, switchBlock, caseExpression, statements): if (switchBlock.getType() != Token.BLOCK): raise Kit.codeBug() switchNode = switchBlock.getFirstChild() if (switchNode.getType() != Token.SWITCH): raise Kit.codeBug() gotoTarget = Node.newTarget() if caseExpression is not None: caseNode = Jump(Token.CASE, caseExpression) caseNode.target = gotoTarget switchNode.addChildToBack(caseNode) else: switchNode.setDefault(gotoTarget) switchBlock.addChildToBack(gotoTarget) switchBlock.addChildToBack(statements)
def createLoop(self, loop, loopType, body, cond, init, incr): bodyTarget = Node.newTarget() condTarget = Node.newTarget() if (loopType == self.LOOP_FOR) and (cond.getType() == Token.EMPTY): cond = Node(Token.TRUE) IFEQ = Jump(Token.IFEQ, cond) IFEQ.target = bodyTarget breakTarget = Node.newTarget() loop.addChildToBack(bodyTarget) loop.addChildrenToBack(body) if (loopType == self.LOOP_WHILE) or (loopType == self.LOOP_FOR): loop.addChildrenToBack(Node(Token.EMPTY, loop.getLineno())) loop.addChildToBack(condTarget) loop.addChildToBack(IFEQ) loop.addChildToBack(breakTarget) loop.target = breakTarget continueTarget = condTarget if (loopType == self.LOOP_WHILE) or (loopType == self.LOOP_FOR): loop.addChildToFront(self.makeJump(Token.GOTO, condTarget)) if (loopType == self.LOOP_FOR): if (init.getType() != Token.EMPTY): if (init.getType() != Token.VAR): init = Node(Token.EXPR_VOID, init) loop.addChildToFront(init) incrTarget = Node.newTarget() loop.addChildAfter(incrTarget, body) if (incr.getType() != Token.EMPTY): incr = Node(Token.EXPR_VOID, incr) loop.addChildAfter(incr, incrTarget) continueTarget = incrTarget loop.setContinue(continueTarget) return loop
def createIf(self, cond, ifTrue, ifFalse, lineno): condStatus = self.isAlwaysDefinedBoolean(cond) if (condStatus == self.ALWAYS_TRUE_BOOLEAN): return ifTrue else: if (condStatus == self.ALWAYS_FALSE_BOOLEAN): if ifFalse is not None: return ifFalse return Node(Token.BLOCK, lineno) result = Node(Token.BLOCK, lineno) ifNotTarget = Node.newTarget() IFNE = Jump(Token.IFNE, cond) IFNE.target = ifNotTarget result.addChildToBack(IFNE) result.addChildrenToBack(ifTrue) if ifFalse is not None: endTarget = Node.newTarget() result.addChildToBack(self.makeJump(Token.GOTO, endTarget)) result.addChildToBack(ifNotTarget) result.addChildrenToBack(ifFalse) result.addChildToBack(endTarget) else: result.addChildToBack(ifNotTarget) return result
def makeJump(self, type, target): n = Jump(type) n.target = target return n
def createTryCatchFinally(self, tryBlock, catchBlocks, finallyBlock, lineno): hasFinally = finallyBlock is not None and ( (finallyBlock.getType() != Token.BLOCK) or finallyBlock.hasChildren()) if (tryBlock.getType() == Token.BLOCK) and not tryBlock.hasChildren() and not hasFinally: return tryBlock hasCatch = catchBlocks.hasChildren() if not hasFinally and not hasCatch: return tryBlock handlerBlock = Node(Token.LOCAL_BLOCK) pn = Jump(Token.TRY, tryBlock, lineno) pn.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock) if hasCatch: endCatch = Node.newTarget() pn.addChildToBack(self.makeJump(Token.GOTO, endCatch)) catchTarget = Node.newTarget() pn.target = catchTarget pn.addChildToBack(catchTarget) catchScopeBlock = Node(Token.LOCAL_BLOCK) cb = catchBlocks.getFirstChild() hasDefault = False scopeIndex = 0 while cb is not None: catchLineNo = cb.getLineno() name = cb.getFirstChild() cond = name.getNext() catchStatement = cond.getNext() cb.removeChild(name) cb.removeChild(cond) cb.removeChild(catchStatement) catchStatement.addChildToBack(Node(Token.LEAVEWITH)) catchStatement.addChildToBack(self.makeJump(Token.GOTO, endCatch)) condStmt = None#Node() if (cond.getType() == Token.EMPTY): condStmt = catchStatement hasDefault = True else: condStmt = self.createIf(cond, catchStatement, None, catchLineNo) catchScope = Node(Token.CATCH_SCOPE, name, self.createUseLocal(handlerBlock)) catchScope.putProp(Node.LOCAL_BLOCK_PROP, catchScopeBlock) catchScope.putIntProp(Node.CATCH_SCOPE_PROP, scopeIndex) catchScopeBlock.addChildToBack(catchScope) catchScopeBlock.addChildToBack(self.createWith(self.createUseLocal(catchScopeBlock), condStmt, catchLineNo)) cb = cb.getNext() scopeIndex += 1 pn.addChildToBack(catchScopeBlock) if not hasDefault: rethrow = Node(Token.RETHROW) rethrow.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock) pn.addChildToBack(rethrow) pn.addChildToBack(endCatch) if hasFinally: finallyTarget = Node.newTarget() pn.setFinally(finallyTarget) pn.addChildToBack(self.makeJump(Token.JSR, finallyTarget)) finallyEnd = Node.newTarget() pn.addChildToBack(self.makeJump(Token.GOTO, finallyEnd)) pn.addChildToBack(finallyTarget) fBlock = Node(Token.FINALLY, finallyBlock) fBlock.putProp(Node.LOCAL_BLOCK_PROP, handlerBlock) pn.addChildToBack(fBlock) pn.addChildToBack(finallyEnd) handlerBlock.addChildToBack(pn) return handlerBlock
def createContinue(self, loop, lineno): if (loop.getType() != Token.LOOP): Kit.codeBug() n = Jump(Token.CONTINUE, lineno) n.setJumpStatement(loop) return n