If/elseif with simple conditions
This commit is contained in:
parent
1905e49744
commit
2ddbd57677
@ -225,6 +225,8 @@ namespace pim
|
||||
Scope * prevScope = currentScope;
|
||||
currentScope = new Scope();
|
||||
defineLabel(label);
|
||||
|
||||
output << "." << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::PushLocalScope(std::string label)
|
||||
@ -235,6 +237,8 @@ namespace pim
|
||||
currentScope->Definitions.insert(currentScope->Definitions.begin(), prevScope->Definitions.begin(), prevScope->Definitions.end());
|
||||
currentScope->FrameSize = prevScope->FrameSize;
|
||||
defineLabel(label);
|
||||
|
||||
output << "." << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::PopScope()
|
||||
@ -242,6 +246,9 @@ namespace pim
|
||||
|
||||
writeOpcode(Opcode::Return);
|
||||
writeConstant(currentScope->LocalFrameSize);
|
||||
|
||||
output << "return " << currentScope->LocalFrameSize << std::endl;
|
||||
|
||||
currentScope = scopes.top();
|
||||
scopes.pop();
|
||||
}
|
||||
@ -250,12 +257,16 @@ namespace pim
|
||||
{
|
||||
//defineLabelwriteOpcode("." << label);
|
||||
defineLabel(label);
|
||||
|
||||
output << "." << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::LocalEnter()
|
||||
{
|
||||
writeOpcode(Opcode::LocalEnter);
|
||||
writeConstantPlaceholder(&(currentScope->LocalFrameSize));
|
||||
|
||||
output << "enter " << "#" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::ScopeVariableType(int type)
|
||||
@ -268,6 +279,8 @@ namespace pim
|
||||
currentScope->Definitions.push_back(Definition(label, variableType, currentScope->FrameSize));
|
||||
currentScope->FrameSize += 4;
|
||||
currentScope->LocalFrameSize += 4;
|
||||
|
||||
output << "#declare " << label << " " << currentScope->FrameSize-4 << std::endl;
|
||||
}
|
||||
|
||||
void Generator::PushVariableAddress(std::string label)
|
||||
@ -279,108 +292,148 @@ namespace pim
|
||||
{
|
||||
writeOpcode(Opcode::Load);
|
||||
writeConstant(currentScope->GetDefinition(label).StackPosition);
|
||||
|
||||
output << "load " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::StoreVariable(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::Store);
|
||||
writeConstant(currentScope->GetDefinition(label).StackPosition);
|
||||
|
||||
output << "store " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::RTConstant(std::string name)
|
||||
{
|
||||
writeOpcode(Opcode::Constant);
|
||||
writeConstantMacroPlaceholder(name);
|
||||
|
||||
output << "const " << name << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Constant(std::string constant)
|
||||
{
|
||||
writeOpcode(Opcode::Constant);
|
||||
writeConstant(constant);
|
||||
|
||||
output << "const " << constant << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void Generator::Increment(std::string constant)
|
||||
{
|
||||
writeOpcode(Opcode::Increment);
|
||||
writeConstant(constant);
|
||||
|
||||
output << "inc " << constant << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Discard()
|
||||
{
|
||||
writeOpcode(Opcode::Discard);
|
||||
|
||||
output << "discard" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Duplicate()
|
||||
{
|
||||
writeOpcode(Opcode::Duplicate);
|
||||
|
||||
output << "duplicate" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Add()
|
||||
{
|
||||
writeOpcode(Opcode::Add);
|
||||
|
||||
output << "add" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Subtract()
|
||||
{
|
||||
writeOpcode(Opcode::Subtract);
|
||||
|
||||
output << "sub" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Multiply()
|
||||
{
|
||||
writeOpcode(Opcode::Multiply);
|
||||
|
||||
output << "mul" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Divide()
|
||||
{
|
||||
writeOpcode(Opcode::Divide);
|
||||
|
||||
output << "div" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Modulus()
|
||||
{
|
||||
writeOpcode(Opcode::Modulus);
|
||||
|
||||
output << "add" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Negate()
|
||||
{
|
||||
writeOpcode(Opcode::Negate);
|
||||
|
||||
output << "neg" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::CreateParticle()
|
||||
{
|
||||
writeOpcode(Opcode::Create);
|
||||
|
||||
output << "create" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::TransformParticle()
|
||||
{
|
||||
writeOpcode(Opcode::Transform);
|
||||
|
||||
output << "transform" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::GetParticle()
|
||||
{
|
||||
writeOpcode(Opcode::Get);
|
||||
|
||||
output << "getpart" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::GetPosition()
|
||||
{
|
||||
writeOpcode(Opcode::Position);
|
||||
|
||||
output << "getpos" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::KillParticle()
|
||||
{
|
||||
writeOpcode(Opcode::Kill);
|
||||
|
||||
output << "kill" << std::endl;
|
||||
}
|
||||
|
||||
void Generator::LoadProperty(std::string property)
|
||||
{
|
||||
writeOpcode(Opcode::LoadProperty);
|
||||
writeConstantPropertyPlaceholder(property);
|
||||
|
||||
output << "loadprop " << property << std::endl;
|
||||
}
|
||||
|
||||
void Generator::StoreProperty(std::string property)
|
||||
{
|
||||
writeOpcode(Opcode::StoreProperty);
|
||||
writeConstantPropertyPlaceholder(property);
|
||||
|
||||
output << "storeprop " << property << std::endl;
|
||||
}
|
||||
|
||||
void Generator::IntegerToDecimal()
|
||||
@ -398,42 +451,56 @@ namespace pim
|
||||
{
|
||||
writeOpcode(Opcode::JumpEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumpe " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::JumpNotEqual(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::JumpNotEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumpne " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::JumpGreater(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::JumpGreater);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumpg " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::JumpGreaterEqual(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::JumpGreaterEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumpge " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::JumpLess(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::JumpLess);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumpl " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::JumpLessEqual(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::JumpLessEqual);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jumple " << label << std::endl;
|
||||
}
|
||||
|
||||
void Generator::Jump(std::string label)
|
||||
{
|
||||
writeOpcode(Opcode::Jump);
|
||||
writeConstantPlaceholder(label);
|
||||
|
||||
output << "jump " << label << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 if(token.Symbol == Token::EqualSymbol)
|
||||
{
|
||||
generator->JumpNotEqual(jumpLabel);
|
||||
}
|
||||
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, "condition");
|
||||
}
|
||||
//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);
|
||||
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))
|
||||
|
@ -51,8 +51,7 @@ namespace pim
|
||||
void statement();
|
||||
void neighbourStatement();
|
||||
void ifStatement();
|
||||
void condition();
|
||||
void conditionalOperator();
|
||||
void condition(std::string jumpLabel);
|
||||
void assigmentStatement();
|
||||
void particleAction();
|
||||
void killStatement();
|
||||
@ -60,11 +59,13 @@ namespace pim
|
||||
void createStatement();
|
||||
void transformStatement();
|
||||
void expressionList();
|
||||
|
||||
void expression();
|
||||
void term();
|
||||
void factor();
|
||||
void variableValue();
|
||||
|
||||
Token forward();
|
||||
bool accept(int symbol);
|
||||
bool look(int symbol);
|
||||
void back();
|
||||
|
@ -33,6 +33,8 @@ namespace pim
|
||||
"break",
|
||||
"continue",
|
||||
"if",
|
||||
"else",
|
||||
"elseif",
|
||||
"then",
|
||||
"end",
|
||||
"kill",
|
||||
|
@ -45,6 +45,8 @@ namespace pim
|
||||
BreakSymbol,
|
||||
ContinueSymbol,
|
||||
IfSymbol,
|
||||
ElseSymbol,
|
||||
ElseIfSymbol,
|
||||
ThenSymbol,
|
||||
EndSymbol,
|
||||
|
||||
|
Reference in New Issue
Block a user