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::compileSubroutineCall(string subName) { /* subroutineName '(' expressionList ')' | (className | varName) '.' subroutineName '(' expression ')' */ string oldTok = jt.getToken(); jt.setToken(subName); readIdentifier(); jt.setToken(oldTok); if (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == '(') { readSymbol('('); nextToken(); compileExpressionList(); readSymbol(')'); } else { readSymbol('.'); nextToken(); readIdentifier(); nextToken(); readSymbol('('); nextToken(); compileExpressionList(); readSymbol(')'); } nextToken(); }
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::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::compileSubroutineBody() { /* '{' varDec* statements '}' */ tagNonTerminal("subroutineBody"); readSymbol('{'); nextToken(); while (jt.tokenType() == TokenType::kKEYWORD && jt.keyword() == Keyword::kVAR) compileVarDec(); compileStatements(); readSymbol('}'); untagNonTerminal("subroutineBody"); nextToken(); }
void CompilationEngine::compileParameterList() { /* ((type varName)(',' type varName)*)? */ tagNonTerminal("parameterList"); if (jt.tokenType() != TokenType::kSYMBOL) { readType(); nextToken(); readIdentifier(); nextToken(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); readType(); nextToken(); readIdentifier(); nextToken(); } } untagNonTerminal("parameterList"); }
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::compileDo() { /* 'do' subroutineCall ';' */ tagNonTerminal("doStatement"); readKeyword("do", Keyword::kDO); nextToken(); compileSubroutineCall(); readSymbol(';'); untagNonTerminal("doStatement"); nextToken(); }
void LexicalAnalyzer::LexicalAnalyze(const string& srcCodeFilePath) // an integrated automaton using if-else sentence // according to current input symbol, a sub-automaton would be activated { FILE* fp = fopen("./test.cpp", "r"); char ch; ch = fgetc(fp); while(ch != EOF) { // cout << ch; if(isalpha(ch) || ch == '_') { // cout << "will read id" << endl; readID(fp, ch); // cout << "read id ok" << endl; } else if(ch == '\'') { // cout << "will read character" << endl; readCh(fp, ch); // cout << "read character ok" << endl; } else if(ch == '\"') { // cout << "will read string" << endl; readStr(fp, ch); // cout << "read string ok" << endl; } else if(isdigit(ch)) { // cout << "will read constant" << endl; readConst(fp, ch); // cout << "read constant ok" << endl; } else if(ch == ' ' || ch == '\t' || ch == '\n') { // cout << "will read space tab and newline" << endl; readSpaceTabNewline(fp, ch); // cout << "read space tab and newline ok" << endl; } else { // cout << "will read symbol" << endl; readSymbol(fp, ch); // cout << "read symbol ok" << endl; } } // cout << endl; fclose(fp); }
static Object* ReaderReadInternal(Context* ctx, Reader* r) { const char* token = r->tokenizer->token; Object* result = readNumber(ctx, token); if(!result) { result = readList(ctx, token, r); } if(!result) { result = readSymbol(ctx, token); } return result; }
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::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 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::compileExpressionList() { // (expression(',' expression)*)? tagNonTerminal("expressionList"); if (jt.tokenType() != TokenType::kSYMBOL || (jt.symbol() == '(' )) compileExpression(); while (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == ',') { readSymbol(','); nextToken(); compileExpression(); } untagNonTerminal("expressionList"); }
static void findAsmTags (void) { vString *name = vStringNew (); vString *operator = vStringNew (); const unsigned char *line; boolean inCComment = FALSE; while ((line = readLineFromInputFile ()) != NULL) { const unsigned char *cp = line; boolean labelCandidate = (boolean) (! isspace ((int) *cp)); boolean nameFollows = FALSE; const boolean isComment = (boolean) (*cp != '\0' && strchr (";*@", *cp) != NULL); /* skip comments */ if (strncmp ((const char*) cp, "/*", (size_t) 2) == 0) { inCComment = TRUE; cp += 2; } if (inCComment) { do { if (strncmp ((const char*) cp, "*/", (size_t) 2) == 0) { inCComment = FALSE; cp += 2; break; } ++cp; } while (*cp != '\0'); } if (isComment || inCComment) continue; /* read preprocessor defines */ if (*cp == '#') { ++cp; readPreProc (cp); continue; } /* skip white space */ while (isspace ((int) *cp)) ++cp; /* read symbol */ cp = readSymbol (cp, name); if (vStringLength (name) > 0 && *cp == ':') { labelCandidate = TRUE; ++cp; } if (! isspace ((int) *cp) && *cp != '\0') continue; /* skip white space */ while (isspace ((int) *cp)) ++cp; /* skip leading dot */ #if 0 if (*cp == '.') ++cp; #endif cp = readOperator (cp, operator); /* attempt second read of symbol */ if (vStringLength (name) == 0) { while (isspace ((int) *cp)) ++cp; cp = readSymbol (cp, name); nameFollows = TRUE; } makeAsmTag (name, operator, labelCandidate, nameFollows); } vStringDelete (name); vStringDelete (operator); }
llvm::Expected<IndexFileIn> readRIFF(llvm::StringRef Data) { auto RIFF = riff::readFile(Data); if (!RIFF) return RIFF.takeError(); if (RIFF->Type != riff::fourCC("CdIx")) return makeError("wrong RIFF type"); llvm::StringMap<llvm::StringRef> Chunks; for (const auto &Chunk : RIFF->Chunks) Chunks.try_emplace(llvm::StringRef(Chunk.ID.data(), Chunk.ID.size()), Chunk.Data); for (llvm::StringRef RequiredChunk : {"meta", "stri"}) if (!Chunks.count(RequiredChunk)) return makeError("missing required chunk " + RequiredChunk); Reader Meta(Chunks.lookup("meta")); if (Meta.consume32() != Version) return makeError("wrong version"); auto Strings = readStringTable(Chunks.lookup("stri")); if (!Strings) return Strings.takeError(); IndexFileIn Result; if (Chunks.count("srcs")) { Reader SrcsReader(Chunks.lookup("srcs")); Result.Sources.emplace(); while (!SrcsReader.eof()) { auto IGN = readIncludeGraphNode(SrcsReader, Strings->Strings); auto Entry = Result.Sources->try_emplace(IGN.URI).first; Entry->getValue() = std::move(IGN); // We change all the strings inside the structure to point at the keys in // the map, since it is the only copy of the string that's going to live. Entry->getValue().URI = Entry->getKey(); for (auto &Include : Entry->getValue().DirectIncludes) Include = Result.Sources->try_emplace(Include).first->getKey(); } if (SrcsReader.err()) return makeError("malformed or truncated include uri"); } if (Chunks.count("symb")) { Reader SymbolReader(Chunks.lookup("symb")); SymbolSlab::Builder Symbols; while (!SymbolReader.eof()) Symbols.insert(readSymbol(SymbolReader, Strings->Strings)); if (SymbolReader.err()) return makeError("malformed or truncated symbol"); Result.Symbols = std::move(Symbols).build(); } if (Chunks.count("refs")) { Reader RefsReader(Chunks.lookup("refs")); RefSlab::Builder Refs; while (!RefsReader.eof()) { auto RefsBundle = readRefs(RefsReader, Strings->Strings); for (const auto &Ref : RefsBundle.second) // FIXME: bulk insert? Refs.insert(RefsBundle.first, Ref); } if (RefsReader.err()) return makeError("malformed or truncated refs"); Result.Refs = std::move(Refs).build(); } return std::move(Result); }
static void findAsmTags (void) { vString *name = vStringNew (); vString *operator = vStringNew (); const unsigned char *line; cppInit (false, false, false, false, KIND_GHOST_INDEX, 0, KIND_GHOST_INDEX, 0, 0); unsigned int lastMacroCorkIndex = CORK_NIL; while ((line = asmReadLineFromInputFile ()) != NULL) { const unsigned char *cp = line; bool labelCandidate = (bool) (! isspace ((int) *cp)); bool nameFollows = false; bool directive = false; const bool isComment = (bool) (*cp != '\0' && strchr (";*@", *cp) != NULL); /* skip comments */ if (isComment) continue; /* skip white space */ while (isspace ((int) *cp)) ++cp; /* read symbol */ if (*cp == '.') { directive = true; labelCandidate = false; ++cp; } cp = readSymbol (cp, name); if (vStringLength (name) > 0 && *cp == ':') { labelCandidate = true; ++cp; } if (! isspace ((int) *cp) && *cp != '\0') continue; /* skip white space */ while (isspace ((int) *cp)) ++cp; /* skip leading dot */ #if 0 if (*cp == '.') ++cp; #endif cp = readOperator (cp, operator); /* attempt second read of symbol */ if (vStringLength (name) == 0) { while (isspace ((int) *cp)) ++cp; cp = readSymbol (cp, name); nameFollows = true; } makeAsmTag (name, operator, labelCandidate, nameFollows, directive, &lastMacroCorkIndex); } cppTerminate (); vStringDelete (name); vStringDelete (operator); }
OBJ js_read(OBJ inStream){ OBJ retVal; prompt_off(); char ch = skipWhiteSpace(inStream); if( ch == -1){ retVal = js_eof; unreadChar(inStream, ch); } else if(ch == '('){ retVal = readList(inStream); } else if(ch =='\''){ OBJ expr = js_read(inStream); // (quote (expr* (nil))) -> expr must be a cons return newCons(symbolTableGetOrAdd("quote"), newCons(expr, js_nil)); } else if(ch == '"'){ retVal = readString(inStream); } else if(isDigit(ch)){ retVal = readNumber(inStream, ch, 0); }else if(ch == '-'){ /* * TO-DO refactor: implement proper read ahead solution */ // simple read ahead to catch negative numbers char nextCh = nextChar(inStream); if(isDigit(nextCh)){ retVal = readNumber(inStream, nextCh, 1); }else{ unreadChar(inStream, nextCh); retVal = readSymbol(inStream, ch); } } #ifdef DEBUG else if(ch == '%'){ ch = nextChar(inStream); OBJ debugOption; if(ch == '\n' ){ unreadChar(inStream, ch); debugOption = newSymbol(""); }else{ debugOption = readSymbol(inStream, ch); } switchDebugOptions( debugOption ); retVal = js_void; } #endif else { retVal = readSymbol(inStream, ch); } if(thisIsTheEnd(inStream)){ prompt_on(); }; return retVal; }
void CompilationEngine::compileTerm() // 362 { // integerConst | stringConst | keywordConst | // varName | varName '[' expression ']' | subroutineCall | // '(' expression ')' | unaryOp term tagNonTerminal("term"); string id; string oldTok; switch(jt.tokenType()) { case TokenType::kINT_CONST: readIntConst(); break; case TokenType::kSTRING_CONST: readStringConst(); break; case TokenType::kKEYWORD: readKeywordConstant(); break; case TokenType::kIDENTIFIER: id = jt.getToken(); // save current token nextToken(); if (jt.tokenType() == TokenType::kSYMBOL && jt.symbol() == '[') { oldTok = jt.getToken(); jt.setToken(id); readIdentifier(); jt.setToken(oldTok); readSymbol('['); nextToken(); compileExpression(); readSymbol(']'); nextToken(); } else if (jt.tokenType() == TokenType::kSYMBOL && (jt.symbol() == '.' || jt.symbol() == '(')) { compileSubroutineCall(id); } else { oldTok = jt.getToken(); jt.setToken(id); readIdentifier(); jt.setToken(oldTok); } untagNonTerminal("term"); return; // has already advanced break; case TokenType::kSYMBOL: if (jt.symbol() == '(') { // '(' expression ')' readSymbol('('); nextToken(); compileExpression(); readSymbol(')'); } else { // unaryOp term readUnaryOp(); nextToken(); compileTerm(); untagNonTerminal("term"); return; // has already advanced } break; default: break; } nextToken(); untagNonTerminal("term"); }