summaryrefslogtreecommitdiff
path: root/src/pim/Parser.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-09-23 14:14:56 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-09-23 14:14:56 (GMT)
commit2ddbd576770d2497af4b0a66149962956ef0ccf3 (patch)
tree1ba1231fb2e9f8c05394189366a0e5b9855d5a75 /src/pim/Parser.cpp
parent1905e497442bc39cf8896e54812718064a52d621 (diff)
downloadpowder-2ddbd576770d2497af4b0a66149962956ef0ccf3.zip
powder-2ddbd576770d2497af4b0a66149962956ef0ccf3.tar.gz
If/elseif with simple conditions
Diffstat (limited to 'src/pim/Parser.cpp')
-rw-r--r--src/pim/Parser.cpp100
1 files changed, 64 insertions, 36 deletions
diff --git a/src/pim/Parser.cpp b/src/pim/Parser.cpp
index 7badae9..4b164c8 100644
--- a/src/pim/Parser.cpp
+++ b/src/pim/Parser.cpp
@@ -1,5 +1,6 @@
//Syntax analyser
#include "Parser.h"
+#include "Format.h"
namespace pim
{
namespace compiler
@@ -157,7 +158,7 @@ namespace pim
void Parser::statementList()
{
statement();
- while(!look(Token::EndSymbol))
+ while(!look(Token::EndSymbol) && !look(Token::ElseIfSymbol))
statement();
}
@@ -387,54 +388,69 @@ namespace pim
*/
void Parser::ifStatement()
{
- //generator->Begin(NonTerminal::IfStatement);
+ std::string label = generator->UniqueLabel("if");
+ int blockNum = 0;
expect(Token::IfSymbol);
- condition();
+ condition(label+format::NumberToString<int>(blockNum));
expect(Token::ThenSymbol);
block();
+ while(accept(Token::ElseIfSymbol))
+ {
+ generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
+ condition(label+format::NumberToString<int>(blockNum));
+ expect(Token::ThenSymbol);
+ block();
+ }
+ if(accept(Token::ElseSymbol))
+ {
+ generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
+ block();
+ }
+ else
+ {
+ generator->ScopeLabel(label+format::NumberToString<int>(blockNum++));
+ }
expect(Token::EndSymbol);
//generator->End(NonTerminal::IfStatement);
}
/*
- <condition> ::= identifier <conditional operator> identifier | identifier <conditional operator> numberConstant | numberConstant <conditional operator> identifier | numberConstant <conditional operator> numberConstant
+ <condition> ::= <expression> <conditional operator> <expression>
*/
- void Parser::condition()
+ void Parser::condition(std::string jumpLabel)
{
- //generator->Begin(NonTerminal::Condition);
- if(look(Token::Identifier))
+ expression();
+
+ Token token = forward();
+
+ expression();
+
+ if(token.Symbol == Token::GreaterSymbol)
{
- conditionalOperator();
- if(!accept(Token::Identifier) && !accept(Token::IntegerConstant) && !accept(Token::DecimalConstant))
- throw ParserExpectException(token, "identifier or constant");
+ generator->JumpLessEqual(jumpLabel);
}
- else if(look(Token::DecimalConstant) || look(Token::IntegerConstant))
+ else if(token.Symbol == Token::GreaterEqualSymbol)
{
- conditionalOperator();
- if(!accept(Token::Identifier) && !accept(Token::IntegerConstant) && !accept(Token::DecimalConstant))
- throw ParserExpectException(token, "identifier or constant");
+ generator->JumpLess(jumpLabel);
}
- else
+ else if(token.Symbol == Token::EqualSymbol)
{
- throw ParserExpectException(token, "condition");
+ generator->JumpNotEqual(jumpLabel);
}
- //generator->End(NonTerminal::Condition);
- }
-
- /*
- <conditional operator> ::= > | >= | == | != | < | <=
- */
- void Parser::conditionalOperator()
- {
- //generator->Begin(NonTerminal::ConditionalOperator);
- if(!accept(Token::GreaterSymbol))
- if(!accept(Token::GreaterEqualSymbol))
- if(!accept(Token::EqualSymbol))
- if(!accept(Token::NotEqualSymbol))
- if(!accept(Token::LessSymbol))
- if(!accept(Token::LessEqualSymbol))
- throw ParserExpectException(token, "conditional operator");
- //generator->End(NonTerminal::ConditionalOperator);
+ else if(token.Symbol == Token::NotEqualSymbol)
+ {
+ generator->JumpEqual(jumpLabel);
+ }
+ else if(token.Symbol == Token::LessSymbol)
+ {
+ generator->JumpGreaterEqual(jumpLabel);
+ }
+ else if(token.Symbol == Token::LessEqualSymbol)
+ {
+ generator->JumpGreater(jumpLabel);
+ }
+ else
+ throw ParserExpectException(token, "conditional operator");
}
/*
@@ -586,7 +602,6 @@ namespace pim
{
if(symbol == token.Symbol)
{
- //generator->Insert(token);
lastToken = token;
if(previousTokens.size())
{
@@ -595,10 +610,10 @@ namespace pim
}
else
token = scanner->NextToken();
- std::cout << "Symbol " << Token::SymbolNames[symbol] << " " << lastToken.Source << std::endl;
+ //std::cout << "Symbol " << Token::SymbolNames[symbol] << " " << lastToken.Source << std::endl;
return true;
}
- std::cout << "Bad Symbol " << Token::SymbolNames[symbol] << " " << token.Source << " (" << token.GetName() << ")" << std::endl;
+ //std::cout << "Bad Symbol " << Token::SymbolNames[symbol] << " " << token.Source << " (" << token.GetName() << ")" << std::endl;
return false;
}
@@ -616,6 +631,19 @@ namespace pim
token = lastToken;
}
+ Token Parser::forward()
+ {
+ lastToken = token;
+ if(previousTokens.size())
+ {
+ token = previousTokens.top();
+ previousTokens.pop();
+ }
+ else
+ token = scanner->NextToken();
+ return lastToken;
+ }
+
void Parser::expect(int symbol)
{
if(!accept(symbol))