diff options
| Commit | 9b0c6501113169cacc6a6c4ca996959e4586e304 (patch) | |
|---|---|---|
| Author | 2018-09-21 09:21:29 +0300 | |
| Committer | 2018-09-21 09:23:15 +0300 | |
| Files | de1cad98fbe893a46be20dcb67cef0ea072262c4 /JSImpl/src | |
| IPL-9b0c6501113169cacc6a6c4ca996959e4586e304.tar IPL-9b0c6501113169cacc6a6c4ca996959e4586e304.tar.gz IPL-9b0c6501113169cacc6a6c4ca996959e4586e304.zip | ||
| Parent | 7ee2c286210ed2ef684636ec031b722dc939c5ec (diff) | |
Implement TopStatement and Program rules.
4 files changed, 263 insertions, 57 deletions
| -rw-r--r-- | JSImpl/src/Expression.cpp | 83 | ||||
| -rw-r--r-- | JSImpl/src/Expression.h | 35 | ||||
| -rw-r--r-- | JSImpl/src/Parser.cpp | 200 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 2 |
diff --git a/JSImpl/src/Expression.cpp b/JSImpl/src/Expression.cpp index c96e550..fcccd07 100644 --- a/JSImpl/src/Expression.cpp +++ b/JSImpl/src/Expression.cpp @@ -1,6 +1,24 @@ #include "Expression.h" #include <assert.h> +void PrintExpressionMember(ExpressionPtr expr, const char* name, std::ostream& os) +{ + os << name << ": {" << std::endl; + expr->Print(os); + os << "}"; +} + +void PrintExpressionMember(IPLVector<ExpressionPtr> exprs, const char* name, std::ostream& os) +{ + os << name << ": {" << std::endl; + for (auto& it : exprs) + { + it->Print(os); + os << ",\n"; + } + os << "}"; +} + BinaryExpression::BinaryExpression(IPLSharedPtr<Expression> exprLeft, IPLSharedPtr<Expression> exprRight, TokenType op) : m_Left(exprLeft) , m_Right(exprRight) @@ -129,9 +147,8 @@ void LiteralExpression::Print(std::ostream& os) const os << "\n}\n"; } -IdentifierExpression::IdentifierExpression(IPLString& name, ExpressionPtr value) +IdentifierExpression::IdentifierExpression(IPLString& name) : m_Name(name) - , m_Value(value) { } @@ -140,7 +157,6 @@ void IdentifierExpression::Print(std::ostream& os) const os << "{ \n"; os << " Expression Type: Identifier" << std::endl; os << "Identifier name: " << m_Name << std::endl; - m_Value->Print(os); os << "\n}\n"; } @@ -183,7 +199,7 @@ LabeledStatement::LabeledStatement(IPLString& identifier, ExpressionPtr statemen void LabeledStatement::Print(std::ostream& os) const { - os << "{ Not implemented yet !!}"; + os << "{ LabeledStatement Not implemented yet !!}"; } IfStatement::IfStatement(ExpressionPtr cond, ExpressionPtr ifStatement, ExpressionPtr elseStatement) @@ -195,7 +211,7 @@ IfStatement::IfStatement(ExpressionPtr cond, ExpressionPtr ifStatement, Expressi void IfStatement::Print(std::ostream& os) const { - os << "{ Not implemented yet !!}"; + os << "{ IfStatement Not implemented yet !!}"; } SwitchStatement::SwitchStatement(ExpressionPtr cond, IPLVector<Case>& cases, ExpressionPtr defaultCase) @@ -207,7 +223,7 @@ SwitchStatement::SwitchStatement(ExpressionPtr cond, IPLVector<Case>& cases, Exp void SwitchStatement::Print(std::ostream& os) const { - os << "{ Not implemented yet !!}"; + os << "{ SwitchStatement Not implemented yet !!}"; } WhileStatement::WhileStatement(ExpressionPtr cond, ExpressionPtr body, bool doWhile) @@ -220,7 +236,7 @@ WhileStatement::WhileStatement(ExpressionPtr cond, ExpressionPtr body, bool doWh void WhileStatement::Print(std::ostream& os) const { - os << "{ Not implemented yet !!}"; + os << "{ WhileStatement Not implemented yet !!}"; } ForStatement::ForStatement(ExpressionPtr initialization, ExpressionPtr cond, ExpressionPtr iteration, ExpressionPtr body) @@ -233,7 +249,58 @@ ForStatement::ForStatement(ExpressionPtr initialization, ExpressionPtr cond, Exp void ForStatement::Print(std::ostream& os) const { - os << "{ Not implemented yet !!}"; + os << "{ Expression Type: ForStatement " << std::endl; + os << "{ Initialization:" << std::endl; + m_Initialization->Print(os); + os << "}" << std::endl; + os << "{ Condition:" << std::endl; + m_Condition->Print(os); + os << "}" << std::endl; + os << "{ Iteration:" << std::endl; + m_Condition->Print(os); + os << "}" << std::endl; + os << "{ Body:" << std::endl; + m_Body->Print(os); + os << "}" << std::endl; +} + + +FunctionDeclaration::FunctionDeclaration(IPLString& functionName, IPLVector<IPLString>& argumentsIdentifiers, ExpressionPtr body) + : m_Name(functionName) + , m_ArgumentsIdentifiers(argumentsIdentifiers) + , m_Body(body) +{ +} + +void FunctionDeclaration::Print(std::ostream& os) const +{ + os << "{ Expression Type: FunctionDeclaration " << std::endl; + os << "{ Function name: " << m_Name << std::endl; + os << "{ Function parameters: " << std::endl; + os << "{ " << std::endl; + for (auto it : m_ArgumentsIdentifiers) + { + os << it; + } + os << "}" << std::endl; + os << "{ Function body:" << std::endl; + m_Body->Print(os); + os << "}" << std::endl; + os << "}" << std::endl; } +void TopStatements::Print(std::ostream& os) const +{ + os << "{ Expression Type: TopStatements " << std::endl;; + for (auto it : m_Values) + { + it->Print(os); + } + os << "}"; +} + +void EmptyExpression::Print(std::ostream& os) const +{ + os << "{ EmptyExpression }"; +} diff --git a/JSImpl/src/Expression.h b/JSImpl/src/Expression.h index 51cdd21..03a2c54 100644 --- a/JSImpl/src/Expression.h +++ b/JSImpl/src/Expression.h @@ -73,12 +73,12 @@ private: class IdentifierExpression : public Expression { public: - IdentifierExpression(IPLString& name, ExpressionPtr value); + IdentifierExpression(IPLString& name); virtual ~IdentifierExpression() {} virtual void Print(std::ostream& os) const override; protected: IPLString m_Name; - ExpressionPtr m_Value; + }; class ListExpression : public Expression @@ -95,9 +95,11 @@ protected: class VariableDefinitionExpression : public IdentifierExpression { public: - VariableDefinitionExpression(IPLString& name, ExpressionPtr value) : IdentifierExpression(name, value){} + VariableDefinitionExpression(IPLString& name, ExpressionPtr value) : IdentifierExpression(name), m_Value(value){} virtual ~VariableDefinitionExpression() {} virtual void Print(std::ostream& os) const override; +protected: + ExpressionPtr m_Value; }; class BlockStatement : public ListExpression @@ -174,3 +176,30 @@ private: ExpressionPtr m_Body; }; +class FunctionDeclaration : public Expression +{ +public: + FunctionDeclaration(IPLString& functionName, IPLVector<IPLString>& argumentsIdentifiers, ExpressionPtr body); + virtual ~FunctionDeclaration() {} + virtual void Print(std::ostream& os) const override; +private: + IPLString m_Name; + IPLVector<IPLString> m_ArgumentsIdentifiers; + ExpressionPtr m_Body; +}; + +class TopStatements : public ListExpression +{ +public: + TopStatements() {} + virtual ~TopStatements() {} + virtual void Print(std::ostream& os) const override; +}; + +class EmptyExpression : public Expression +{ +public: + EmptyExpression() {} + virtual ~EmptyExpression() {} + virtual void Print(std::ostream& os) const override; +}; diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp index dd81b72..f40fcc6 100644 --- a/JSImpl/src/Parser.cpp +++ b/JSImpl/src/Parser.cpp @@ -50,8 +50,10 @@ private: ExpressionPtr ReturnStatement(); ExpressionPtr TryStatement(); - ExpressionPtr FunctionDefinition(); + ExpressionPtr Program(); + ExpressionPtr TopStatements(); + ExpressionPtr TopStatement(); Token& Prev() { return m_Tokens[m_Current - 1]; } std::function<void()> OnError; @@ -148,37 +150,38 @@ ExpressionPtr Parser::ObjectLiteral() // LiteralField // | FieldList, LiteralField // LiteralField -> Identifier : AssignmentExpressionnormal, allowIn - if (Match(TokenType::LeftBrace)) - { - auto LiteralField = [=]() -> ExpressionPtr { - if (Match(TokenType::Identifier)) - { - auto ae = AssignmentExpression(); - return IPLMakeSharePtr<IdentifierExpression>(Prev().Lexeme, ae); - } - return nullptr; - }; + //if (Match(TokenType::LeftBrace)) + //{ + // auto LiteralField = [=]() -> ExpressionPtr { + // if (Match(TokenType::Identifier)) + // { + // auto id = Prev().Lexeme; + // auto ae = AssignmentExpression(); + // return IPLMakeSharePtr<IdentifierExpression>(id, ae); + // } + // return nullptr; + // }; - auto FieldList = [=]() -> ExpressionPtr { - auto result = IPLMakeSharePtr<ListExpression>(); - while (auto lf = LiteralField()) - { - result->Push(lf); - if (!Match(TokenType::Comma)) - { - break; - } - } - return result; - }; - auto fl = FieldList(); - if (Match(TokenType::RightBrace)) - { - return fl; - } - // TODO Add error loging - assert(false); - } + // auto FieldList = [=]() -> ExpressionPtr { + // auto result = IPLMakeSharePtr<ListExpression>(); + // while (auto lf = LiteralField()) + // { + // result->Push(lf); + // if (!Match(TokenType::Comma)) + // { + // break; + // } + // } + // return result; + // }; + // auto fl = FieldList(); + // if (Match(TokenType::RightBrace)) + // { + // return fl; + // } + // // TODO Add error loging + // assert(false); + //} return nullptr; } @@ -271,8 +274,7 @@ ExpressionPtr Parser::SimpleExpression() } else if (Match(TokenType::Identifier)) { - ExpressionPtr empty; - return IPLMakeSharePtr<IdentifierExpression>(Prev().Lexeme, empty); + return IPLMakeSharePtr<IdentifierExpression>(Prev().Lexeme); } else if (auto al = ArrayLiteral()) { @@ -648,7 +650,7 @@ ExpressionPtr Parser::Statement() else if(auto result = OptionalLabel()) return result; else if(auto result = ReturnStatement()) return result; else if(auto result = TryStatement()) return result; - assert(false); return nullptr; + return nullptr; } ExpressionPtr Parser::EmptyStatement() @@ -668,11 +670,12 @@ ExpressionPtr Parser::VariableDefinition() // VariableDeclaration -> Identifier VariableInitializer // VariableInitializer -> // «empty» - // | = AssignmentExpressionnormal, + // | = AssignmentExpressionnormal, if (Match(TokenType::Identifier)) { + auto id = Prev().Lexeme; auto ae = AssignmentExpression(); - return IPLMakeSharePtr<VariableDefinitionExpression>(Prev().Lexeme, ae); + return IPLMakeSharePtr<VariableDefinitionExpression>(id, ae); } return nullptr; }; @@ -795,7 +798,7 @@ ExpressionPtr Parser::SwitchStatement() ExpressionPtr Parser::DoStatement() { if(Match(TokenType::Do)) - { + { auto body = Statement(); if (Match(TokenType::While)) { @@ -840,32 +843,57 @@ ExpressionPtr Parser::ForStatement() ExpressionPtr Parser::WithStatement() { - assert(false); return nullptr; + return nullptr; } ExpressionPtr Parser::ContinueStatement() { - assert(false); return nullptr; + if (Match(TokenType::Continue)) + { + auto type = TokenType::Continue; + ExpressionPtr expr = OptionalLabel(); + bool suffix = true; + return IPLMakeSharePtr<UnaryExpression>(expr, type, suffix); + } + return nullptr; } ExpressionPtr Parser::BreakStatement() { - assert(false); return nullptr; + if (Match(TokenType::Break)) + { + auto type = TokenType::Break; + ExpressionPtr expr = OptionalLabel(); + bool suffix = true; + return IPLMakeSharePtr<UnaryExpression>(expr, type, suffix); + } + return nullptr; } ExpressionPtr Parser::OptionalLabel() { - assert(false); return nullptr; + if (Match(TokenType::Identifier)) + { + return IPLMakeSharePtr<IdentifierExpression>(Prev().Lexeme); + } + return nullptr; } ExpressionPtr Parser::ReturnStatement() { - assert(false); return nullptr; + if (Match(TokenType::Return)) + { + auto type = TokenType::Return; + ExpressionPtr expr = OptionalExpression(); + bool suffix = true; + return IPLMakeSharePtr<UnaryExpression>(expr, type, suffix); + } + return nullptr; } ExpressionPtr Parser::TryStatement() { - assert(false); return nullptr; + return nullptr; } ExpressionPtr Parser::OptionalExpression() @@ -878,10 +906,92 @@ ExpressionPtr Parser::OptionalExpression() ExpressionPtr Parser::Parse() { - // TODO implement full grammar - return Unary(); + return Parser::Program(); +} + +ExpressionPtr Parser::FunctionDefinition() +{ + auto FormalParameters = [=](IPLVector<IPLString> identifiers) -> bool { + if (Match(TokenType::LeftParen)) + { + while (Match(TokenType::Identifier)) + { + identifiers.push_back(Prev().Lexeme); + if (!Match(TokenType::Comma)) + { + break; + } + } + + if (Match(TokenType::RightParen)) + { + return true; + } + } + return false; + }; + + auto Body = [=]() -> ExpressionPtr { + + if (Match(TokenType::LeftBrace)) + { + auto ts = TopStatements(); + if (Match(TokenType::RightBrace)) + { + return ts; + } + } + return nullptr; + }; + + if (Match(TokenType::Function)) + { + if (Match(TokenType::Identifier)) + { + auto name = Prev().Lexeme; + IPLVector<IPLString> identifiers; + if (FormalParameters(identifiers)) + { + if (auto body = Body()) + { + return IPLMakeSharePtr<FunctionDeclaration>(name, identifiers, body); + } + else + { + // TODO log error + return nullptr; + } + } + } + } + return nullptr; +} + + +ExpressionPtr Parser::Program() +{ + return TopStatements(); } +ExpressionPtr Parser::TopStatements() +{ + auto statements = IPLMakeSharePtr<::TopStatements>(); + while (auto ts = TopStatement()) + { + statements->Push(ts); + } + return statements; +} + +ExpressionPtr Parser::TopStatement() +{ + auto result = FunctionDefinition(); + if (!result) + { + result = Statement(); + } + return result; +} ExpressionPtr Parse(IPLVector<Token>& tokens, const std::function<void()>& onError) { diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index d412050..e2fc448 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -77,7 +77,7 @@ void TestVariableDeclaration() void TestParseUnaryExpr() { // TODO make actual test :D - auto expr = Parse(Tokenize("--10")); + auto expr = Parse(Tokenize("function pesho() { var a = 0; return a; }")); expr->Print(std::cout); } |
