expressions::Expression* Parser::parseExpression() { Expression* lhs = parsePrimaryExpression(); if(!lhs) return NULL; Expression* expr = parseBinaryOperationRHS(0, lhs); if(lhs != expr) lhs->drop(); return expr; }
expressions::ArrayIndexExpression* Parser::parseArrayIndexExpression(expressions::Expression* array) { array->grab(); readNextToken(true); // Eat the '['. Expression* index = parseExpression(); // Parse the index. expect(TokenRightSquareBracket); // Expect a ']'. // Create the expression. ArrayIndexExpression* expr = new ArrayIndexExpression(array, index); // Drop temps. array->drop(); // We made a copy, drop our copy. index->drop(); return expr; }
expressions::Expression* Parser::parsePrimaryExpression() { if(isEndOfStream()) return NULL; if(m_currentToken == TokenMinusSign) { readNextToken(true); // Eat the '-'. Expression* expr = parseExpression(); NegativeExpression* result = new NegativeExpression(expr); expr->drop(); return result; } if(m_currentToken.getType() == Token::TokenType::NumericLiteral) // Check for a numeric literal. { return parseNumericLiteralExpression(); } else if(m_currentToken.getType() == Token::TokenType::StringLiteral) // Check for a string literal. { return parseStringLiteralExpression(); } else if(m_currentToken.getType() == Token::TokenType::Word) // Check for a word. { return parseWordExpression(); } else if(Token::Compare(m_strCmp, m_currentToken, TokenLeftParenthesis)) // Check for a parentheses expression. { return parseParenthesesExpression(); } else // Unexpected token. { onError("unexpected token"); return nullptr; } }
expressions::Expression* Parser::parseWordExpression() { std::string first = m_currentToken.getValue(); readNextToken(false); // Eat the identifier. if(m_currentToken == TokenPeriod) { readNextToken(true); // Eat the '.'. // Parse the name. while(1) { if((m_currentToken.getType() == Token::TokenType::Word)) first += "." + m_currentToken.getValue(); else { break; } readNextToken(true); // Eat the last part of the name. if(m_currentToken == TokenPeriod) { readNextToken(true); continue; } else if((m_currentToken == TokenLeftParenthesis)) break; } } // It has a '(', it is a function call expression. if(m_currentToken == TokenLeftParenthesis) { std::vector<Expression*> args; parseFunctionCall(args); // Parse the argument list. // Create the function call expression. Expression* expr = new FunctionCallExpression(first, args); // Check if we're indexing an item from the return value. if(m_currentToken == TokenLeftSquareBracket) { ArrayIndexExpression* indexExpr = parseArrayIndexExpression(expr); expr->drop(); // Drop the old expression. expr = indexExpr; // The expression is now the new index expression. } // Drop the argument list. for(unsigned int i=0; i<args.size(); i++) args[i]->drop(); return expr; } Expression* expr = new VariableExpression(first); while(m_currentToken == TokenLeftSquareBracket) { Expression* array = expr; expr = parseArrayIndexExpression(array); array->drop(); } return expr; }
expressions::Expression* Parser::parseBinaryOperationRHS(int expressionPrecedence, expressions::Expression* lhs) { Expression* origLHS = lhs; while(1) { int tokPrec = getOperatorPrecedence(m_currentToken); if(tokPrec < expressionPrecedence) return lhs; Token op = m_currentToken; readNextToken(true); Expression* rhs = parsePrimaryExpression(); if(!rhs) return nullptr; int nextPrec = getOperatorPrecedence(m_currentToken); if(tokPrec < nextPrec) { Expression* oldRHS = rhs; rhs = parseBinaryOperationRHS(tokPrec+1, rhs); oldRHS->drop(); if(!rhs) return nullptr; } Expression* oldLHS = lhs; // Check the operator. if(op == TokenPlusSign) { lhs = new AdditionExpression(lhs, rhs); // Operator is addition. } else if(op == TokenMinusSign) { lhs = new SubtractionExpression(lhs, rhs); // Operator is subtraction. } else if(op == TokenMulSign) { lhs = new MultipicationExpression(lhs, rhs); // Operator is multipication. } else if(op == TokenDivSign) { lhs = new DivisionExpression(lhs, rhs); // Operator is division. } else if(op == TokenEquals) { lhs = new EqualExpression(lhs, rhs); // Operator is equal comparison. } else if(op == TokenLessThan) { lhs = new LessThanExpression(lhs, rhs); // Operator is less than. } else if(op == TokenGreaterThan) { lhs = new GreaterThanExpression(lhs, rhs); // Operator is greater than. } else if(op == TokenLessThanOrEqualTo) { lhs = new LessThanOrEqualToExpression(lhs, rhs); // Operator is less than or equal to. } else if(op == TokenGreaterThenOrEqualTo) { lhs = new GreaterThanOrEqualToExpression(lhs, rhs); // Operator is greater than or equal to. } else if(op == TokenNotEquals) { lhs = new NotEqualExpression(lhs, rhs); // Operator is not equal. } else if(Token::Compare(m_strCmp, op, TokenAnd)) { lhs = new AndExpression(lhs, rhs); } else if(Token::Compare(m_strCmp, op, TokenOr)) { lhs = new OrExpression(lhs, rhs); } else { onError("undefined operator '" + op.getValue() + "'"); return nullptr; } if(oldLHS !=origLHS) oldLHS->drop(); // TODO: rhs->drop(); } }
statements::Statement* Parser::parseIdentifierStatement() { std::string first = m_currentToken.getValue(); // Attempt to read a token. if(readNextToken(false)) { if(m_currentToken == TokenColon) // The statement is a label. { readNextToken(true); // Eat the ':'. expectEOL(); // Expect a new line. return new LabelStatement(first); } if(m_currentToken == TokenPeriod) { readNextToken(true); // Eat the '.'. // Parse the name. while(1) { if((m_currentToken.getType() == Token::TokenType::Word)) first += "." + m_currentToken.getValue(); else { onError("expected identifier, '.', '=' or '('"); return nullptr; } readNextToken(true); // Eat the last part of the name. if(m_currentToken == TokenPeriod) { readNextToken(true); continue; } else if((m_currentToken == TokenLeftParenthesis) || (m_currentToken == TokenEquals)) break; } } // The statement is a function call statement. if(m_currentToken == TokenLeftParenthesis) { std::vector<Expression*> args; // The arguments to the function. parseFunctionCall(args); // Parse the function call. expectEOL(); // Expect an EOL. FunctionCallStatement* statement = new FunctionCallStatement(first, args); // Drop the argument list. for(unsigned int i=0; i<args.size(); i++) args[i]->drop(); return statement; } Expression* lhs = new VariableExpression(first); while(m_currentToken == TokenLeftSquareBracket) { Expression* array = lhs; lhs = parseArrayIndexExpression(array); array->drop(); } if(m_currentToken == TokenEquals) // The statement is in the form 'x = y'. { readNextToken(true); // Eat the '='. Expression* rhs = parseExpression(); expectEOL(); AssignmentStatement* statement = new AssignmentStatement(lhs, rhs); rhs->drop(); return statement; } } onError("expected '(', '=' or ':'"); return nullptr; }