package de.fuberlin.projecta.analysis.ast; import de.fuberlin.commons.lexer.TokenType; import de.fuberlin.commons.parser.ISyntaxTree; import de.fuberlin.projecta.analysis.SymbolTableStack; public class Block extends Statement { /** * Used for naming conventions in declarations */ private int memoryCounter; @Override public void buildSymbolTable(SymbolTableStack stack) { stack.push(); for (int i = 0; i < this.getChildrenCount(); i++) { ((AbstractSyntaxTree) (this.getChild(i))).buildSymbolTable(stack); } table = stack.pop(); } // using super implementation for genCode public int getNewVar() { return ++memoryCounter; } public int getCurrentRegister() { return memoryCounter; } protected boolean hasReturnStatement() { if (this.getChildrenCount() > 0) { ISyntaxTree last = this.getChild(this.getChildrenCount() - 1); if (last instanceof Block) { return ((Block) last).hasReturnStatement(); } else { return last instanceof Return; } } return false; } protected boolean couldAmmendReturnStatement() { // Blocks don't exist if they are empty! ISyntaxTree lastStatement = this.getChild(this.getChildrenCount() - 1); if (lastStatement instanceof Block) { return ((Block) lastStatement).couldAmmendReturnStatement(); } else if (lastStatement instanceof Do) { return ((Do) lastStatement).couldAmmendReturnStatement(); } else if (lastStatement instanceof IfElse) { return ((IfElse) lastStatement).couldAmmendReturnStatement(); } else if (lastStatement instanceof BinaryOp) { BinaryOp binOp = (BinaryOp) lastStatement; if (binOp.getOp() == TokenType.OP_ASSIGN) { // first child has to be an identifier. This is checked // beforehand! Return r = new Return(); r.addChild(binOp.getChild(0)); this.addChild(r); return true; } // it is an operation. A return statement will be created with // this operation } else if (lastStatement instanceof Break || lastStatement instanceof Print || lastStatement instanceof If || lastStatement instanceof While) { return false; } Return r = new Return(); r.addChild(lastStatement); this.removeChild(this.getChildrenCount() - 1); this.addChild(r); return true; } }