static String getBlock(SamTokenizer f) throws TokenizerException { try { String asmCode = ""; Boolean returnFlag = false; Boolean tempFlag; while (!f.check('}')) { asmCode += getStmt(f); tempFlag = returnFlags.pop(); if (tempFlag) { returnFlag = true; } } if (!returnFlag) returnFlags.push(false); else returnFlags.push(true); return asmCode; } catch (Exception e) { System.out.println(e.getMessage()); throw new TokenizerException("Error: Invalid block."); } }
static String getBody(SamTokenizer f) throws TokenizerException { try { String asmCode = ""; Boolean returnFlag = false; Boolean tempFlag; myCheck(f, '{'); switch (f.peekAtKind()) { case WORD: // Check if it is a variable declaration. while (f.check("int")) { asmCode += getVariables(f); myCheck(f, ';'); } // Parse all the statement before }. while (!f.check('}')) { asmCode += getStmt(f); tempFlag = returnFlags.pop(); if (tempFlag) { returnFlag = true; } } if (!returnFlag) throw new TokenizerException("Error: No return."); return asmCode; case OPERATOR: while (!f.check('}')) { asmCode += getStmt(f); tempFlag = returnFlags.pop(); if (tempFlag) { returnFlag = true; } } if (!returnFlag) throw new TokenizerException("Error: No return."); return asmCode; default: throw new TokenizerException("Error: Invalid body."); } } catch (Exception e) { System.out.println(e.getMessage()); throw new TokenizerException("Error: Invalid body."); } }
static String getStmt(SamTokenizer f) throws TokenizerException { try { String asmCode = ""; Boolean returnFlag1; Boolean returnFlag2; switch (f.peekAtKind()) { case WORD: { String newWord = f.getWord(); switch (newWord) { case "return": { asmCode += getExp(f); myCheck(f, ';'); // SaM code for return. asmCode += "STOREOFF -" + Integer.toString(params.size() + 1) + "\n" + "ADDSP -" + Integer.toString(varCounter - 2) + "\n" + "JUMPIND\n"; returnFlags.push(true); return asmCode; } case "if": { // Generate two valid lables for divergence. String label1 = getLabel(); String label2 = getLabel(); myCheck(f, '('); asmCode += getExp(f); myCheck(f, ')'); asmCode += ("JUMPC " + label1 + "\n"); // Buffer the statements for if condition. String tempString = getStmt(f); returnFlag1 = returnFlags.pop(); myCheck(f, "else"); asmCode += getStmt(f); returnFlag2 = returnFlags.pop(); // Manage the divergence. asmCode += ("JUMP " + label2 + "\n" + label1 + ":\n" + tempString + label2 + ":\n"); if (returnFlag1 && returnFlag2) returnFlags.push(true); else returnFlags.push(false); return asmCode; } case "while": { String label1 = getLabel(); String label2 = getLabel(); // Push the label as the return position. labels.push(label2); myCheck(f, '('); asmCode += (label1 + ":\n"); asmCode += getExp(f); asmCode += ("ISNIL\n" + "JUMPC " + label2 + "\n"); myCheck(f, ')'); // Flag indicating that we are in a while loop (possibly nested while loops.) flags.push(true); asmCode += getStmt(f); asmCode += ("JUMP " + label1 + "\n" + label2 + ":\n"); // Once finish parsing the while loop, pop out the labels and flags. labels.pop(); flags.pop(); return asmCode; } case "break": { // flags.empty() indicates that we are not currently in a while loop. if (flags.empty()) throw new TokenizerException("Error: Invalid break statement."); myCheck(f, ';'); returnFlags.push(false); // Jump to the current inner most return postion. return "JUMP " + labels.peek() + "\n"; } default: // Assign statement // Check if the variable is already defined. if (!symTables.lastElement().containsKey(newWord)) throw new TokenizerException("Error: Variable not declared."); myCheck(f, '='); asmCode += getExp(f); myCheck(f, ';'); // Get the address of the variable from the symbol table. int addr = symTables.lastElement().get(newWord); asmCode += ("STOREOFF " + Integer.toString(addr) + "\n"); returnFlags.push(false); return asmCode; } } case OPERATOR: { switch (f.getOp()) { case '{': { asmCode += getBlock(f); return asmCode; } case ';': returnFlags.push(false); return asmCode; default: throw new TokenizerException("Error: Invalid operator inside a statement."); } } default: throw new TokenizerException("Error: Invalid Statement."); } } catch (Exception e) { System.out.println(e.getMessage()); throw new TokenizerException("Error: Invalid Statement."); } }