void CompilationEngine::readKeywordConstant() { if (jt.tokenType() == TokenType::kKEYWORD) { switch (jt.keyword()) { case Keyword::kTRUE: readKeyword("true", Keyword::kTRUE); break; case Keyword::kFALSE: readKeyword("false", Keyword::kFALSE); break; case Keyword::kNULL: readKeyword("null", Keyword::kNULL); break; case Keyword::kTHIS: readKeyword("this", Keyword::kTHIS); break; default: break; } } }
void CompilationEngine::readType() { if (jt.tokenType() == TokenType::kKEYWORD) { switch (jt.keyword()) { case Keyword::kINT: readKeyword("int", Keyword::kINT); break; case Keyword::kCHAR: readKeyword("char", Keyword::kCHAR); break; case Keyword::kBOOLEAN: readKeyword("boolean", Keyword::kBOOLEAN); break; default: break; } } else { readIdentifier(); } }
void CompilationEngine::compileClassVarDec() { /* ('static' | 'field') type varName (',' varName)* ';' */ tagNonTerminal("classVarDec"); if (jt.keyword() == Keyword::kFIELD) readKeyword("field", Keyword::kFIELD); else readKeyword("static", Keyword::kSTATIC); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readIdentifier(); nextToken(); } readSymbol(';'); untagNonTerminal("classVarDec"); nextToken(); }
void CompilationEngine::compileIf() { /* 'if' '(' expression ')' '{' statements '}' ('else' '{' statements '}')? */ tagNonTerminal("ifStatement"); readKeyword("if", Keyword::kIF); nextToken(); readSymbol('('); nextToken(); compileExpression(); readSymbol(')'); nextToken(); readSymbol('{'); nextToken(); compileStatements(); readSymbol('}'); nextToken(); if (jt.tokenType() == TokenType::kKEYWORD && jt.keyword() == Keyword::kELSE) { readKeyword("else", Keyword::kELSE); nextToken(); readSymbol('{'); nextToken(); compileStatements(); readSymbol('}'); nextToken(); } untagNonTerminal("ifStatement"); }
void CompilationEngine::compileSubroutine() { /* ('constructor' | 'function' | 'method') ('void' | type) subroutineName '(' parameterList ')' subroutineBody */ tagNonTerminal("subroutineDec"); if (jt.keyword() == Keyword::kCONSTRUCTOR) readKeyword("constructor", Keyword::kCONSTRUCTOR); else if (jt.keyword() == Keyword::kFUNCTION) readKeyword("function", Keyword::kFUNCTION); else readKeyword("method", Keyword::kMETHOD); nextToken(); if (jt.tokenType() == TokenType::kKEYWORD && jt.keyword() == Keyword::kVOID) readKeyword("void", Keyword::kVOID); else readType(); nextToken(); readIdentifier(); nextToken(); readSymbol('('); nextToken(); compileParameterList(); readSymbol(')'); nextToken(); compileSubroutineBody(); untagNonTerminal("subroutineDec"); }
void CompilationEngine::compileClass() { /* 'class' className '{' classVarDec* subroutineDec* '}' */ tagNonTerminal("class"); nextToken(); readKeyword("class", Keyword::kCLASS); nextToken(); readIdentifier(); nextToken(); readSymbol('{'); nextToken(); while (jt.tokenType() == TokenType::kKEYWORD && (jt.keyword() == Keyword::kFIELD || jt.keyword() == Keyword::kSTATIC)) compileClassVarDec(); while (jt.tokenType() == TokenType::kKEYWORD && (jt.keyword() == Keyword::kCONSTRUCTOR || jt.keyword() == Keyword::kFUNCTION || jt.keyword() == Keyword::kMETHOD)) compileSubroutine(); readSymbol('}'); untagNonTerminal("class"); if (jt.advance()) // jack language does not allow anything else beyond the class throw CompilationException("jack language does not allow anything else beyond the class"); }
void CompilationEngine::compileLet() { /*'let' varName('[' expression ']')? '=' expression ';' */ tagNonTerminal("letStatement"); readKeyword("let", Keyword::kLET); nextToken(); readIdentifier(); nextToken(); if (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == '[') { readSymbol('['); nextToken(); compileExpression(); readSymbol(']'); nextToken(); } readSymbol('='); nextToken(); compileExpression(); readSymbol(';'); untagNonTerminal("letStatement"); nextToken(); }
void CompilationEngine::compileDo() { /* 'do' subroutineCall ';' */ tagNonTerminal("doStatement"); readKeyword("do", Keyword::kDO); nextToken(); compileSubroutineCall(); readSymbol(';'); untagNonTerminal("doStatement"); nextToken(); }
void Parser::readBlock(Block& block) { do { std::string str = readKeyword(); switch (nextToken()) { case Parser::Error: return; case Parser::Begin: readBegin(); readBlock(block.addBlock(str)); readEnd(); break; case Parser::Equal: readEqual(); if (nextToken() == QuoteStr) { block.addString(str, readQuotedString()); while (nextToken() == Parser::Comma) { readComma(); block.addString(str, readQuotedString()); } } else if (nextToken() == Real) { block.addReal(str, readReal()); while (nextToken() == Parser::Comma) { readComma(); block.addReal(str, readReal()); } } else if (nextToken() == RelativeReal) { block.addRelativeReal(str, readRelativeReal()); while (nextToken() == Parser::Comma) { readComma(); block.addRelativeReal(str, readRelativeReal()); } } else if (nextToken() == Str) { block.addString(str, readString()); while (nextToken() == Parser::Comma) { readComma(); block.addString(str, readString()); } } else { throw utils::InternalError(); } readSemicolon(); break; default: throw utils::InternalError("bad file"); }; } while (nextToken() != Parser::End and mStream); }
void CompilationEngine::compileReturn() { /* 'return' expression? ';' */ tagNonTerminal("returnStatement"); readKeyword("return", Keyword::kRETURN); nextToken(); if (jt.tokenType() != TokenType::kSYMBOL || (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() != ';')) compileExpression(); readSymbol(';'); untagNonTerminal("returnStatement"); nextToken(); }
void CompilationEngine::compileWhile() { /* 'while' '(' expression ')' '{' statements '}' */ tagNonTerminal("whileStatement"); readKeyword("while", Keyword::kWHILE); nextToken(); readSymbol('('); nextToken(); compileExpression(); readSymbol(')'); nextToken(); readSymbol('{'); nextToken(); compileStatements(); readSymbol('}'); untagNonTerminal("whileStatement"); nextToken(); }
void CompilationEngine::compileVarDec() { /* 'var' type varName (',' varName)* ';' */ tagNonTerminal("varDec"); readKeyword("var", Keyword::kVAR); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readIdentifier(); nextToken(); } readSymbol(';'); untagNonTerminal("varDec"); nextToken(); }
void readDataFromFile( UDP req, char *filename ) { FILE *fp; char line[2048], *p1, *p2, *p3; int len, fldid, lineNum=1, fldtype; short sVal; int iVal; long lVal; float fVal; double dVal; fp = fopen( filename, "r" ); if( fp == NULL ) { printf( "open data file %s error : %s\n", filename, strerror(errno) ); exit( 0 ); } memset( line, 0, sizeof(line) ); while( fgets( line, sizeof(line), fp ) != NULL ) { fldid = (int)readLong(line); p2 = strchr( line, '=' ); p1 = p2 + 1; while( *p1 == ' ' ) p1++; fldtype = readKeyword( &p1 ); switch( fldtype ) { case UDT_STRING: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p1 = p2 + 1; p2 = strchr( p1, '"' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is '\"' \n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, '"' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, not enought char '\"' \n", lineNum ); exit( 0 ); } len = p3-p2-1; p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } UDO_AddField( req, fldid, UDT_STRING, p2+1, len ); break; case UDT_SHORT: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } sVal = (short)readLong( p2+1 ); UDO_AddField( req, fldid, UDT_SHORT, (char*)&sVal, len ); break; case UDT_INT: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } iVal = (int)readLong( p2+1 ); UDO_AddField( req, fldid, UDT_INT, (char*)&iVal, len ); break; case UDT_LONG: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } lVal = readLong( p2+1 ); UDO_AddField( req, fldid, UDT_LONG, (char*)&lVal, len ); break; case UDT_FLOAT: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } fVal = (float)readDouble( p2+1 ); UDO_AddField( req, fldid, UDT_FLOAT, (char*)&fVal, len ); break; case UDT_DOUBLE: p2 = strchr( p1, '(' ); if( p2 == NULL ) { printf( "LINE %d Invalid format, expected char is (\n", lineNum ); exit( 0 ); } p3 = strchr( p2+1, ')' ); if( p3 == NULL ) { printf( "LINE %d Invalid format, needed char is )\n", lineNum ); exit( 0 ); } dVal = readDouble( p2+1 ); UDO_AddField( req, fldid, UDT_DOUBLE, (char*)&dVal, len ); break; default: printf( "LINE %d Invalid datatype\n", lineNum ); exit( 0 ); } memset( line, 0, sizeof(line) ); lineNum++; } fclose( fp ); }