diff options
| Commit | 1df22a637e5c5ac090f7d90c5c666da1b22964d5 (patch) | |
|---|---|---|
| Author | 2018-09-11 09:38:31 +0300 | |
| Committer | 2018-09-11 09:38:31 +0300 | |
| Files | 69b7a527c7f6872c140f4b035929ad60f38cd017 /JSImpl/src | |
| IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.tar IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.tar.gz IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.zip | ||
| Parent | eeab42ab1d16b5e3cfafeeffbe6aa8045212134e (diff) | |
Implement parsing for flow control elements like if, for etc.
3 files changed, 501 insertions, 24 deletions
| -rw-r--r-- | JSImpl/src/Expression.cpp | 101 | ||||
| -rw-r--r-- | JSImpl/src/Expression.h | 111 | ||||
| -rw-r--r-- | JSImpl/src/Parser.cpp | 313 |
diff --git a/JSImpl/src/Expression.cpp b/JSImpl/src/Expression.cpp index 3bd6612..c96e550 100644 --- a/JSImpl/src/Expression.cpp +++ b/JSImpl/src/Expression.cpp @@ -7,13 +7,13 @@ BinaryExpression::BinaryExpression(IPLSharedPtr<Expression> exprLeft, IPLSharedP , m_Operator(op) {} -IPLString BinaryExpression::GetOperatorTypeAsString() +IPLString BinaryExpression::GetOperatorTypeAsString() const { // TODO: Implement return "Binary"; } -void BinaryExpression::Print(std::ostream& os) +void BinaryExpression::Print(std::ostream& os) const { os << "{ \n"; os << " Expression Type: Binary" << std::endl; @@ -34,7 +34,7 @@ UnaryExpression::UnaryExpression(IPLSharedPtr<Expression> expr, TokenType op, bo { } -void UnaryExpression::Print(std::ostream& os) +void UnaryExpression::Print(std::ostream& os) const { os << "{ \n"; os << " Expression Type: Unary" << std::endl; @@ -46,7 +46,7 @@ void UnaryExpression::Print(std::ostream& os) os << "\n}\n"; } -IPLString UnaryExpression::GetOperatorTypeAsString() +IPLString UnaryExpression::GetOperatorTypeAsString() const { switch (m_Operator) { @@ -97,7 +97,7 @@ LiteralExpression::LiteralExpression(TokenType type) } } -void LiteralExpression::Print(std::ostream& os) +void LiteralExpression::Print(std::ostream& os) const { os << "{ \n"; os << " Expression Type: Unary" << std::endl; @@ -129,13 +129,13 @@ void LiteralExpression::Print(std::ostream& os) os << "\n}\n"; } -IdentifierExpression::IdentifierExpression(IPLString name, ExpressionPtr value) +IdentifierExpression::IdentifierExpression(IPLString& name, ExpressionPtr value) : m_Name(name) , m_Value(value) { } -void IdentifierExpression::Print(std::ostream& os) +void IdentifierExpression::Print(std::ostream& os) const { os << "{ \n"; os << " Expression Type: Identifier" << std::endl; @@ -144,7 +144,7 @@ void IdentifierExpression::Print(std::ostream& os) os << "\n}\n"; } -void ListExpression::Print(std::ostream& os) +void ListExpression::Print(std::ostream& os) const { os << "{ \n"; os << " Expression Type: List" << std::endl; @@ -153,4 +153,87 @@ void ListExpression::Print(std::ostream& os) e->Print(os); } os << "\n}\n"; -}
\ No newline at end of file +} + +void VariableDefinitionExpression::Print(std::ostream& os) const +{ + os << "{ \n"; + os << " Expression Type: VariableDefinition" << std::endl; + os << "Identifier name: " << m_Name << std::endl; + m_Value->Print(os); + os << "\n}\n"; +} + +void BlockStatement::Print(std::ostream& os) const +{ + os << "{ \n"; + os << " Expression Type: BlockStatement" << std::endl; + for (auto& e : m_Values) + { + e->Print(os); + } + os << "\n}\n"; +} + +LabeledStatement::LabeledStatement(IPLString& identifier, ExpressionPtr statement) + : m_Identifier(identifier) + , m_Statement(statement) +{ +} + +void LabeledStatement::Print(std::ostream& os) const +{ + os << "{ Not implemented yet !!}"; +} + +IfStatement::IfStatement(ExpressionPtr cond, ExpressionPtr ifStatement, ExpressionPtr elseStatement) + : m_Condition(cond) + , m_IfStatement(ifStatement) + , m_ElseStatement(elseStatement) +{ +} + +void IfStatement::Print(std::ostream& os) const +{ + os << "{ Not implemented yet !!}"; +} + +SwitchStatement::SwitchStatement(ExpressionPtr cond, IPLVector<Case>& cases, ExpressionPtr defaultCase) + : m_Condition(cond) + , m_Cases(cases) + , m_DefaultCase(defaultCase) +{ +} + +void SwitchStatement::Print(std::ostream& os) const +{ + os << "{ Not implemented yet !!}"; +} + +WhileStatement::WhileStatement(ExpressionPtr cond, ExpressionPtr body, bool doWhile) + : m_Condition(cond) + , m_Body(body) + , m_DoWhile(doWhile) +{ +} + + +void WhileStatement::Print(std::ostream& os) const +{ + os << "{ Not implemented yet !!}"; +} + +ForStatement::ForStatement(ExpressionPtr initialization, ExpressionPtr cond, ExpressionPtr iteration, ExpressionPtr body) + : m_Initialization(initialization) + , m_Condition(cond) + , m_Iteration(iteration) + , m_Body(body) +{ +} + +void ForStatement::Print(std::ostream& os) const +{ + os << "{ Not implemented yet !!}"; +} + + diff --git a/JSImpl/src/Expression.h b/JSImpl/src/Expression.h index 3b68522..51cdd21 100644 --- a/JSImpl/src/Expression.h +++ b/JSImpl/src/Expression.h @@ -8,7 +8,7 @@ class Expression : public IPLEnableShared<Expression> public: virtual ~Expression() {} - virtual void Print(std::ostream& os) {}; + virtual void Print(std::ostream& os) const {}; }; using ExpressionPtr = IPLSharedPtr<Expression>; @@ -18,13 +18,13 @@ class BinaryExpression : public Expression { public: virtual ~BinaryExpression() {} - BinaryExpression(IPLSharedPtr<Expression> exprLeft, IPLSharedPtr<Expression> exprRight, TokenType op); - virtual void Print(std::ostream& os); + BinaryExpression(ExpressionPtr exprLeft, ExpressionPtr exprRight, TokenType op); + virtual void Print(std::ostream& os) const override; private: - IPLString GetOperatorTypeAsString(); + IPLString GetOperatorTypeAsString() const; private: - IPLSharedPtr<Expression> m_Left; - IPLSharedPtr<Expression> m_Right; + ExpressionPtr m_Left; + ExpressionPtr m_Right; TokenType m_Operator; }; @@ -35,9 +35,9 @@ class UnaryExpression : public Expression public: virtual ~UnaryExpression() {} UnaryExpression(IPLSharedPtr<Expression> expr, TokenType op, bool suffix); - virtual void Print(std::ostream& os); + virtual void Print(std::ostream& os) const override; private: - IPLString GetOperatorTypeAsString(); + IPLString GetOperatorTypeAsString() const; private: IPLSharedPtr<Expression> m_Expr; TokenType m_Operator; @@ -61,7 +61,7 @@ public: LiteralExpression(IPLString&); LiteralExpression(bool); LiteralExpression(TokenType type); - virtual void Print(std::ostream& os); + virtual void Print(std::ostream& os) const override; private: double m_NumValue; IPLString m_StringValue; @@ -73,10 +73,10 @@ private: class IdentifierExpression : public Expression { public: - IdentifierExpression(IPLString name, ExpressionPtr value); + IdentifierExpression(IPLString& name, ExpressionPtr value); virtual ~IdentifierExpression() {} - virtual void Print(std::ostream& os); -private: + virtual void Print(std::ostream& os) const override; +protected: IPLString m_Name; ExpressionPtr m_Value; }; @@ -87,7 +87,90 @@ public: ListExpression() {}; void Push(ExpressionPtr value) { m_Values.push_back(value); }; virtual ~ListExpression() {} - virtual void Print(std::ostream& os); -private: + virtual void Print(std::ostream& os) const override; +protected: IPLVector<ExpressionPtr> m_Values; }; + +class VariableDefinitionExpression : public IdentifierExpression +{ +public: + VariableDefinitionExpression(IPLString& name, ExpressionPtr value) : IdentifierExpression(name, value){} + virtual ~VariableDefinitionExpression() {} + virtual void Print(std::ostream& os) const override; +}; + +class BlockStatement : public ListExpression +{ +public: + BlockStatement() {}; + virtual ~BlockStatement() {} + virtual void Print(std::ostream& os) const override; +private: +}; + +class LabeledStatement : public Expression +{ +public: + LabeledStatement(IPLString& identifier, ExpressionPtr statements); + virtual ~LabeledStatement() {} + virtual void Print(std::ostream& os) const override; +private: + IPLString m_Identifier; + ExpressionPtr m_Statement; +}; + +class IfStatement : public Expression +{ +public: + IfStatement(ExpressionPtr cond, ExpressionPtr ifStatement, ExpressionPtr elseStatement); + virtual ~IfStatement() {} + virtual void Print(std::ostream& os) const override; +private: + ExpressionPtr m_Condition; + ExpressionPtr m_IfStatement; + ExpressionPtr m_ElseStatement; +}; + +class SwitchStatement : public Expression +{ +public: + struct Case + { + ExpressionPtr Condition; + ExpressionPtr Body; + }; + SwitchStatement(ExpressionPtr cond, IPLVector<Case>& cases, ExpressionPtr defaultCase); + virtual ~SwitchStatement() {} + virtual void Print(std::ostream& os) const override; +private: + ExpressionPtr m_Condition; + IPLVector<Case> m_Cases; + ExpressionPtr m_DefaultCase; +}; + +class WhileStatement : public Expression +{ +public: + WhileStatement(ExpressionPtr cond, ExpressionPtr body, bool doWhile); + virtual ~WhileStatement() {} + virtual void Print(std::ostream& os) const override; +private: + ExpressionPtr m_Condition; + ExpressionPtr m_Body; + bool m_DoWhile; +}; + +class ForStatement : public Expression +{ +public: + ForStatement(ExpressionPtr initialization, ExpressionPtr cond, ExpressionPtr iteration, ExpressionPtr body); + virtual ~ForStatement() {} + virtual void Print(std::ostream& os) const override; +private: + ExpressionPtr m_Initialization; + ExpressionPtr m_Condition; + ExpressionPtr m_Iteration; + ExpressionPtr m_Body; +}; + diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp index 4243520..dd81b72 100644 --- a/JSImpl/src/Parser.cpp +++ b/JSImpl/src/Parser.cpp @@ -9,6 +9,8 @@ public: private: bool MatchOneOf(IPLVector<TokenType> types); bool Match(TokenType type); + ExpressionPtr RegularExpression(); + ExpressionPtr ParenthesizedExpression(); ExpressionPtr PrimaryExpression(); ExpressionPtr FunctionExpression(); ExpressionPtr ObjectLiteral(); @@ -28,6 +30,29 @@ private: ExpressionPtr ConditionalExpression(); ExpressionPtr AssignmentExpression(); ExpressionPtr Expression(); + ExpressionPtr OptionalExpression(); + + //Statements + ExpressionPtr Statement(); + ExpressionPtr EmptyStatement(); + ExpressionPtr VariableDefinition(); + ExpressionPtr Block(); + ExpressionPtr LabeledStatement(); + ExpressionPtr IfStatementfull(); + ExpressionPtr SwitchStatement(); + ExpressionPtr DoStatement(); + ExpressionPtr WhileStatement(); + ExpressionPtr ForStatement(); + ExpressionPtr WithStatement(); + ExpressionPtr ContinueStatement(); + ExpressionPtr BreakStatement(); + ExpressionPtr OptionalLabel(); + ExpressionPtr ReturnStatement(); + ExpressionPtr TryStatement(); + + + ExpressionPtr FunctionDefinition(); + Token& Prev() { return m_Tokens[m_Current - 1]; } std::function<void()> OnError; unsigned m_Current; @@ -64,6 +89,11 @@ bool Parser::Match(TokenType type) return false; } +ExpressionPtr Parser::RegularExpression() +{ + return nullptr; +} + ExpressionPtr Parser::PrimaryExpression() { if (auto simple = SimpleExpression()) @@ -81,6 +111,21 @@ ExpressionPtr Parser::PrimaryExpression() return nullptr; } +ExpressionPtr Parser::ParenthesizedExpression() +{ + if (Match(TokenType::LeftParen)) + { + auto ex = Parser::Expression(); + if (Match(TokenType::RightParen)) + { + return ex; + } + // TODO log error + assert(false); + } + return nullptr; +} + ExpressionPtr Parser::FunctionExpression() { if (auto aFunc = AnonymousFunction()) @@ -233,6 +278,10 @@ ExpressionPtr Parser::SimpleExpression() { return al; } + else if (auto p = ParenthesizedExpression()) + { + return p; + } else { // TODO implement @@ -561,10 +610,272 @@ ExpressionPtr Parser::AssignmentExpression() ExpressionPtr Parser::Expression() { - assert(false); + //Expression -> + // AssignmentExpression + // | Expression , AssignmentExpression normal + auto ae = AssignmentExpression(); + while (Match(TokenType::Comma)) + { + auto next = AssignmentExpression(); + if (next) + { + ae = IPLMakeSharePtr<BinaryExpression>(ae, next, Prev().Type); + } + else + { + // TODO log + assert(false); + } + } + return ae; +} + + +ExpressionPtr Parser::Statement() +{ + if (auto result = EmptyStatement()) return result; + else if(auto result = VariableDefinition()) return result; + else if(auto result = Block()) return result; + else if(auto result = LabeledStatement()) return result; + else if(auto result = IfStatementfull()) return result; + else if(auto result = SwitchStatement()) return result; + else if(auto result = DoStatement()) return result; + else if(auto result = WhileStatement()) return result; + else if(auto result = ForStatement()) return result; + else if(auto result = WithStatement()) return result; + else if(auto result = ContinueStatement()) return result; + else if(auto result = BreakStatement()) return result; + 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; +} + +ExpressionPtr Parser::EmptyStatement() +{ + if (Match(TokenType::Semicolon)) + { + // Not sure what to do here; + // This just will consume ; + return nullptr; + } return nullptr; } +ExpressionPtr Parser::VariableDefinition() +{ + auto VariableDeclaration = [=]() -> ExpressionPtr { + // VariableDeclaration -> Identifier VariableInitializer + // VariableInitializer -> + // «empty» + // | = AssignmentExpressionnormal, + if (Match(TokenType::Identifier)) + { + auto ae = AssignmentExpression(); + return IPLMakeSharePtr<VariableDefinitionExpression>(Prev().Lexeme, ae); + } + return nullptr; + }; + + auto VariableDeclarationList = [=]() -> ExpressionPtr { + // VariableDeclarationList -> + // VariableDeclaration + // | VariableDeclarationList, VariableDeclaration + auto vdList = IPLMakeSharePtr<ListExpression>(); + vdList->Push(VariableDeclaration()); + while (Match(TokenType::Comma)) + { + vdList->Push(VariableDeclaration()); + } + return vdList; + }; + + //VariableDefinition -> var VariableDeclarationListallowIn + if (Match(TokenType::Var)) + { + return VariableDeclarationList(); + } + + return nullptr; +} + +ExpressionPtr Parser::Block() +{ + auto BlockStatementsPrefix = [=]() -> ExpressionPtr { + // BlockStatementsPrefix -> + // Statement full + // | BlockStatementsPrefix Statement full + + //return Statement; + auto StatementsList = IPLMakeSharePtr<BlockStatement>(); + while (auto s = Statement()) + { + StatementsList->Push(s); + } + return StatementsList; + }; + + if (Match(TokenType::LeftBrace)) + { + if (Match(TokenType::RightBrace)) + { + return BlockStatementsPrefix(); + } + else + { + // TODO log error + assert(false); + return nullptr; + } + } + return nullptr; +} + +ExpressionPtr Parser::LabeledStatement() +{ + if (Match(TokenType::Identifier)) + { + auto identifier = Prev().Lexeme; + auto stament = Statement(); + return IPLMakeSharePtr<::LabeledStatement>(identifier, stament); + } + return nullptr; +} + +ExpressionPtr Parser::IfStatementfull() +{ + if (Match(TokenType::If)) + { + auto cond = ParenthesizedExpression(); + auto ifBody = Statement(); + ExpressionPtr elseBody = nullptr; + if (Match(TokenType::Else)) + { + elseBody = Statement(); + } + return IPLMakeSharePtr<::IfStatement>(cond, ifBody, elseBody); + } + return nullptr; +} + +ExpressionPtr Parser::SwitchStatement() +{ + if (Match(TokenType::Switch)) + { + auto cond = ParenthesizedExpression(); + IPLVector<SwitchStatement::Case> cases; + ExpressionPtr defaultCase = nullptr; + if (Match(TokenType::LeftBrace)) + { + + while (!Match(TokenType::RightBrace)) + { + if (Match(TokenType::Case)) + { + auto expr = Expression(); + if (Match(TokenType::Colon)) + { + cases.push_back({ expr, Statement() }); + } + } + else if (Match(TokenType::Default)) + { + if (Match(TokenType::Colon)) + { + defaultCase = Statement(); + } + } + } + return IPLMakeSharePtr<::SwitchStatement>(cond, cases, defaultCase); + } + } + return nullptr; +} + +ExpressionPtr Parser::DoStatement() +{ + if(Match(TokenType::Do)) + { + auto body = Statement(); + if (Match(TokenType::While)) + { + auto cond = ParenthesizedExpression(); + auto isDoWhile = true; + return IPLMakeSharePtr<::WhileStatement>(cond, body, isDoWhile); + } + // TODO log error + } + return nullptr; +} + +ExpressionPtr Parser::WhileStatement() +{ + if (Match(TokenType::While)) + { + auto cond = ParenthesizedExpression(); + auto body = Statement(); + auto isDoWhile = false; + return IPLMakeSharePtr<::WhileStatement>(cond, body, isDoWhile); + } + return nullptr; +} + +ExpressionPtr Parser::ForStatement() +{ + if (Match(TokenType::For)) + { + auto initializer = Expression(); + if (!initializer) + { + initializer = VariableDefinition(); + } + + auto cond = Expression(); + auto iteration = Expression(); + auto body = Statement(); + return IPLMakeSharePtr<::ForStatement>(initializer, cond, iteration, body); + } + return nullptr; +} + +ExpressionPtr Parser::WithStatement() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::ContinueStatement() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::BreakStatement() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::OptionalLabel() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::ReturnStatement() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::TryStatement() +{ + assert(false); return nullptr; +} + +ExpressionPtr Parser::OptionalExpression() +{ + //OptionalExpression -> + // Expressionnormal, allowIn + // | «empty» + return Parser::Expression(); +} + ExpressionPtr Parser::Parse() { // TODO implement full grammar |
