Example #1
0
ASTNode::Link StatementParser::statement() {
  if (accept(TT::TYPE)) {
    return type();
  } else if (accept(TT::IF)) {
    skip();
    return ifStatement();
  } else if (accept(TT::FOR)) {
    auto loop = Node<LoopNode>::make();
    loop->setTrace(current().trace);
    skip(); // Skip "for"
    loop->setInit(declaration(false));
    expectSemi();
    loop->setCondition(expression(false));
    expectSemi();
    loop->setUpdate(expression(false));
    loop->setCode(block(CODE_BLOCK));
    return loop;
  } if (accept(TT::WHILE)) {
    skip(); // Skip "while"
    auto loop = Node<LoopNode>::make();
    loop->setTrace(current().trace);
    loop->setCondition(expression());
    loop->setCode(block(CODE_BLOCK));
    return loop;
  } else if (accept(TT::DO)) {
    return block(CODE_BLOCK);
  } else if (accept(TT::DEFINE)) {
    auto decl = declaration();
    expectSemi();
    return decl;
  } else if (accept(TT::IDENTIFIER)) {
    skip();
    if (accept(TT::IDENTIFIER) || accept(",")) {
      skip(-1); // Go back to the prev identifier
      auto decl = declaration();
      expectSemi();
      return decl;
    } else {
      skip(-1); // Get the entire expression
      auto e = expression();
      expectSemi();
      return e;
    }
  } else if (accept(TT::BREAK)) {
    skip();
    return Node<BreakLoopNode>::make();
  } else if (accept(TT::CONTINUE)) {
    throw InternalError("Unimplemented", {METADATA_PAIRS, {"token", "loop continue"}});
  } else if (accept(TT::RETURN)) {
    auto trace = current().trace;
    skip(); // Skip "return"
    auto retValue = expression(false);
    expectSemi();
    auto retNode = Node<ReturnNode>::make();
    retNode->setTrace(trace);
    if (retValue != nullptr) retNode->setValue(retValue);
    return retNode;
  } else if (accept(TT::FUNCTION)) {
    return function();
  } else if (accept(TT::FOREIGN)) {
    return function(true);
  } else {
    auto e = expression();
    expectSemi();
    return e;
  }
}
Example #2
0
AST* Parser::statement(Scope* ps)
{
    AST* ret = NULL;

    if (expect(";"))
    {
        ret = emptyStatement();
    }
    else if (expect("var"))
    {
        ret = varStatement(ps);
        opteol();
    }
    else if (expect("{"))
    {
        ret = block(ps);
        opteol();
    }
    else if (expect("if"))
    {
        ret = ifStatement(ps);
    }
    else if (expect("switch"))
    {
        ret = switchStatement(ps);
    }
    else if (expect("do"))
    {
        ret = doStatement(ps);
        opteol();
    }
    else if (expect("while"))
    {
        ret = whileStatement(ps);
    }
    else if (expect("for"))
    {
        ret = forStatement(ps);
    }
    else if (expect("with"))
    {
        ret = withStatement(ps);
    }
    else if (expect("continue"))
    {
        ret = continueStatement();
        opteol();
    }
    else if (expect("break"))
    {
        ret = breakStatement();
        opteol();
    }
    else if (expect("return"))
    {
        ret = returnStatement(ps);
        opteol();
    }
    else if (expect("try"))
    {
        ret = tryStatement(ps);
    }
    else if (expect("throw"))
    {
        ret = throwStatement(ps);
        opteol();
    }
    else
    {
        ret = expression(0, ps);
        opteol();
    }

    return ret;
}
Example #3
0
void statement (void) {

	//-------------------------------------------------------------------
	// NOTE: Since we currently don't support generic BEGIN/END (compound
	// statement) blocks...
	if ((curToken != TKN_CODE) /*&& (curToken != TKN_BEGIN)*/)
			crunchStatementMarker();
	
	switch (curToken) {
		case TKN_IDENTIFIER: {
			SymTableNodePtr IdPtr = NULL;
			
			//--------------------------------------------------------------
			// First, do we have an assignment statement or a function call?		
			searchAndFindAllSymTables(IdPtr);
		
			if ((IdPtr->defn.key == DFN_FUNCTION)/* || (IdPtr->defn.key == DFN_MODULE)*/) {
				RoutineKey key = IdPtr->defn.info.routine.key;
				if ((key == RTN_ASSERT) || (key == RTN_PRINT) || (key == RTN_CONCAT)) {
					bool uncrunch = ((key == RTN_ASSERT) && !AssertEnabled) ||
									((key == RTN_PRINT) && !PrintEnabled) ||
									((key == RTN_CONCAT) && !StringFunctionsEnabled);
					if (uncrunch) {
						uncrunchStatementMarker();
						Crunch = false;
					}
				}
				crunchSymTableNodePtr(IdPtr);
				if (IdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) {
					if (NumOrderCalls == MAX_ORDERS)
						syntaxError(ABL_ERR_SYNTAX_TOO_MANY_ORDERS);
					crunchByte((unsigned char)(NumOrderCalls / 32));
					crunchByte((unsigned char)(NumOrderCalls % 32));
					NumOrderCalls++;
				}
				getToken();
				SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
				routineCall(IdPtr, 1);
				CurRoutineIdPtr = thisRoutineIdPtr;
				Crunch = true;
				}
			else
				assignmentStatement(IdPtr);
			}
			break;
		case TKN_REPEAT:
			repeatStatement();
			break;
		case TKN_WHILE:
			whileStatement();
			break;
		case TKN_IF:
			ifStatement();
			break;
		case TKN_FOR:
			forStatement();
			break;
		case TKN_SWITCH:
			switchStatement();
			break;
		case TKN_TRANS:
			transStatement();
			break;
		case TKN_TRANS_BACK:
			transBackStatement();
			break;
	}

	//---------------------------------------------------------------------
	// Now, make sure the statement is closed off with the proper block end
	// statement, if necessary (which is usually the case :).
	synchronize(statementEndList, NULL, NULL);
	if (tokenIn(statementStartList))
		syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
}