diff --git a/src/pim/Generator.cpp b/src/pim/Generator.cpp index 75b4a1907..a79121182 100644 --- a/src/pim/Generator.cpp +++ b/src/pim/Generator.cpp @@ -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; } diff --git a/src/pim/Parser.cpp b/src/pim/Parser.cpp index 7badae92b..4b164c897 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(blockNum)); expect(Token::ThenSymbol); block(); + while(accept(Token::ElseIfSymbol)) + { + generator->ScopeLabel(label+format::NumberToString(blockNum++)); + condition(label+format::NumberToString(blockNum)); + expect(Token::ThenSymbol); + block(); + } + if(accept(Token::ElseSymbol)) + { + generator->ScopeLabel(label+format::NumberToString(blockNum++)); + block(); + } + else + { + generator->ScopeLabel(label+format::NumberToString(blockNum++)); + } expect(Token::EndSymbol); //generator->End(NonTerminal::IfStatement); } /* - ::= identifier identifier | identifier numberConstant | numberConstant identifier | numberConstant numberConstant + ::= */ - 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); - } - - /* - ::= > | >= | == | != | < | <= - */ - 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)) diff --git a/src/pim/Parser.h b/src/pim/Parser.h index c66011ea3..9a4f736a2 100644 --- a/src/pim/Parser.h +++ b/src/pim/Parser.h @@ -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(); diff --git a/src/pim/Token.cpp b/src/pim/Token.cpp index 240716791..453e92f74 100644 --- a/src/pim/Token.cpp +++ b/src/pim/Token.cpp @@ -33,6 +33,8 @@ namespace pim "break", "continue", "if", + "else", + "elseif", "then", "end", "kill", diff --git a/src/pim/Token.h b/src/pim/Token.h index 8f19617c2..15cd48f4c 100644 --- a/src/pim/Token.h +++ b/src/pim/Token.h @@ -45,6 +45,8 @@ namespace pim BreakSymbol, ContinueSymbol, IfSymbol, + ElseSymbol, + ElseIfSymbol, ThenSymbol, EndSymbol,