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);
}
Exemple #11
0
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");
}
Exemple #16
0
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);
}
Exemple #18
0
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);
}
Exemple #19
0
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");
}