std::unique_ptr<ExpressionSeriesAST> ExpressionSeriesAST::generate(Lexer &l) { std::vector<std::unique_ptr<ExpressionAST>> expressions; //a statement series ends with a curly bracket while (1) { //if there is a close curly bracket, stop the series if (l.curToken() == Token::Char_closeCurlyBracket) { return llvm::make_unique<ExpressionSeriesAST>(l, std::move(expressions)); } //parse an expression auto expr = ExpressionAST::generate(l); if (expr != nullptr) { if (l.curToken() == Token::Char_semicolon) { //generate an expressionkiller expressions.push_back(llvm::make_unique<ExpressionKillerAST>(l, std::move(expr))); //eat the semicolon and continue l.nextToken(); } else if (l.curToken() == Token::Char_closeCurlyBracket) { expressions.push_back(std::move(expr)); } else { COMPILE_GENERATE_AND_RETURN_ERROR(l, "Expected ';' or '}' in expressionseries."); } } } }
std::unique_ptr<FunctionPrototypeAST> FunctionPrototypeAST::generate(Lexer &l) { //eat the function token l.nextToken(); //get the name of the function and eat it COMPILE_ASSERT(l.curToken() == Token::Identifier, "Expected identifier in function prototype."); std::string name = l.value.string; l.nextToken(); std::vector<std::string> args; std::vector<std::string> types; std::string type; //make sure we are now in brackets COMPILE_ASSERT(l.curToken() == Token::Char_openRoundBracket, "Expected '(' after function identifier."); l.nextToken(); //keep fetching pairs of tokens until we have no more commas while (l.curToken() != Token::Char_closeRoundBracket) { //eat the type COMPILE_ASSERT(l.curToken() == Token::Identifier || l.curToken() == Token::Type, "Parameter should start with a type."); types.push_back(l.value.string); l.nextToken(); //and the name COMPILE_ASSERT(l.curToken() == Token::Identifier, "Parameter should end with an identifier."); args.push_back(l.value.string); l.nextToken(); //if we do not have a ',' break if (l.curToken() != Token::Char_comma) break; l.nextToken(); } //brackets should be closed COMPILE_ASSERT(l.curToken() == Token::Char_closeRoundBracket, "Expected ')' after function argument list."); l.nextToken(); //if the next token is a ->, we get the type if (l.curToken() == Token::Char_arrow) { l.nextToken(); COMPILE_ASSERT(l.curToken() == Token::Identifier || l.curToken() == Token::Type, "Function return type is not a type."); type = l.value.string; l.nextToken(); } else { type = "void"; } return llvm::make_unique<FunctionPrototypeAST>(l, type, name, std::move(args), std::move(types)); }