package de.fuberlin.projecta.analysis.ast; import java.util.List; import de.fuberlin.commons.lexer.TokenType; import de.fuberlin.commons.parser.ISyntaxTree; import de.fuberlin.projecta.codegen.LLVM; /** * root node of do-while-loop * */ public class Do extends Statement { private Block block; protected boolean hasReturnStatement() { return false; } protected boolean couldAmmendReturnStatement() { ISyntaxTree doBody = this.getChild(0); if (doBody instanceof Block) { return ((Block) doBody).couldAmmendReturnStatement(); } else if (doBody instanceof Do) { return ((Do) doBody).couldAmmendReturnStatement(); } else if (doBody instanceof IfElse) { return ((IfElse) doBody).couldAmmendReturnStatement(); } else if (doBody instanceof BinaryOp) { BinaryOp binOp = (BinaryOp) doBody; if (binOp.getOp() == TokenType.OP_ASSIGN) { // first child has to be an identifier. This is checked beforehand! List<ISyntaxTree> children = this.getChildren(); children.remove(0); Block block = new Block(); block.addChild(binOp); Return r = new Return(); r.addChild(binOp.getChild(0)); block.addChild(r); for(ISyntaxTree tree : children){ block.addChild(tree); } this.addChild(block); return true; } // it is an operation. A return statement will be created with this operation } else if (doBody instanceof Break || doBody instanceof Print || doBody instanceof If || doBody instanceof While){ return false; } Return r = new Return(); r.addChild(doBody); this.removeChild(this.getChildrenCount() - 1); return true; } public String genCode(){ String ret = ""; block = getHighestBlock(); if (block != null) { AbstractSyntaxTree uOp = (AbstractSyntaxTree) getChild(0); boolean not = false; while (uOp instanceof UnaryOp) { if (((UnaryOp) uOp).getOp() == TokenType.OP_NOT) { not = !not; } uOp = (AbstractSyntaxTree) uOp.getChild(0); } int label = block.getNewVar(); this.setBeginLabel(label); ret += "br label %" + label + "\n\n"; ret += "; <label> %" + label + "\n"; ret += ((AbstractSyntaxTree) getChild(0)).genCode(); ret += ((AbstractSyntaxTree)getChild(1)).genCode(); ret += LLVM.genBranch(this, ((AbstractSyntaxTree) getChild(1)),null, not, true); } return ret; } }