diff options
| Commit | d51e7e38448e24123af13f0fa2682b861a64f964 (patch) | |
|---|---|---|
| Author | 2018-11-02 00:12:31 +0200 | |
| Committer | 2018-11-02 00:12:31 +0200 | |
| Files | ff687e7a9aba1f8d53af110afe3e1e079e7b2614 /JSImpl/src | |
| IPL-d51e7e38448e24123af13f0fa2682b861a64f964.tar IPL-d51e7e38448e24123af13f0fa2682b861a64f964.tar.gz IPL-d51e7e38448e24123af13f0fa2682b861a64f964.zip | ||
| Parent | 8f90af904002a028d37cbf25a07d81f7984577d1 (diff) | |
Add many fixes to parser.
Introduce Object Literal and Call expression.
Add more test for parser.
Little enhance around interpreter.
9 files changed, 322 insertions, 215 deletions
| -rw-r--r-- | JSImpl/src/ASTInterpreter.cpp | 24 | ||||
| -rw-r--r-- | JSImpl/src/ASTInterpreter.h | 3 | ||||
| -rw-r--r-- | JSImpl/src/ASTPrinter.h | 2 | ||||
| -rw-r--r-- | JSImpl/src/CommonTypes.h | 5 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionDefinitions.h | 17 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionVisitor.h | 2 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionsFwd.h | 2 | ||||
| -rw-r--r-- | JSImpl/src/Parser.cpp | 478 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 4 |
diff --git a/JSImpl/src/ASTInterpreter.cpp b/JSImpl/src/ASTInterpreter.cpp index edfdc9c..f92fc37 100644 --- a/JSImpl/src/ASTInterpreter.cpp +++ b/JSImpl/src/ASTInterpreter.cpp @@ -1,12 +1,10 @@ #include "ASTInterpreter.h" #include "Expression.h" -#include <cassert> #include <iostream> - +#undef NOT_IMPLEMENTED #define NOT_IMPLEMENTED (void)e; assert(0 && "not-implemented") - struct LValueExtractor : public ExpressionVisitor { public: @@ -27,6 +25,7 @@ public: virtual void Visit(LiteralString* e) override { NOT_IMPLEMENTED; } virtual void Visit(LiteralNumber* e) override { NOT_IMPLEMENTED; } virtual void Visit(LiteralBoolean* e) override { NOT_IMPLEMENTED; } + virtual void Visit(LiteralObject* e) override { NOT_IMPLEMENTED; } virtual void Visit(BinaryExpression* e) override { NOT_IMPLEMENTED; } virtual void Visit(UnaryExpression* e) override { NOT_IMPLEMENTED; } virtual void Visit(IdentifierExpression* e) override { m_LValue = &m_Interpreter->ModifyVariable(e->GetName()); } @@ -42,6 +41,7 @@ public: virtual void Visit(FunctionDeclaration* e) override { NOT_IMPLEMENTED; } virtual void Visit(TopStatements* e) override { NOT_IMPLEMENTED; } virtual void Visit(EmptyExpression* e) override { NOT_IMPLEMENTED; } + virtual void Visit(CallExpression* e) override { NOT_IMPLEMENTED; } ASTInterpreter* m_Interpreter; ASTInterpreter::value_type* m_LValue; @@ -152,6 +152,11 @@ ASTInterpreter::value_type& ASTInterpreter::ModifyVariable(const IPLString& name return undefined; } +bool ASTInterpreter::HasVariable(const IPLString& name) +{ + return m_Variables.find(name) != m_Variables.end(); +} + void ASTInterpreter::Visit(LiteralNull* e) { NOT_IMPLEMENTED; } @@ -163,6 +168,11 @@ void ASTInterpreter::Visit(LiteralString* e) { NOT_IMPLEMENTED; } +void ASTInterpreter::Visit(LiteralObject* e) +{ + NOT_IMPLEMENTED; +} + void ASTInterpreter::Visit(LiteralNumber* e) { m_Evaluation.push_back(e->GetValue()); } @@ -198,6 +208,9 @@ void ASTInterpreter::Visit(BinaryExpression* e) { case TokenType::Comma: m_Evaluation.push_back(right); break; + case TokenType::EqualEqual: + m_Evaluation.push_back(fabs(left - right) < 0.0001); + break; default: NOT_IMPLEMENTED; } @@ -311,3 +324,8 @@ void ASTInterpreter::Visit(TopStatements* e) { void ASTInterpreter::Visit(EmptyExpression* e) { NOT_IMPLEMENTED; } + +void ASTInterpreter::Visit(CallExpression* e) +{ + NOT_IMPLEMENTED; +} diff --git a/JSImpl/src/ASTInterpreter.h b/JSImpl/src/ASTInterpreter.h index 7dc58de..4683d63 100644 --- a/JSImpl/src/ASTInterpreter.h +++ b/JSImpl/src/ASTInterpreter.h @@ -21,6 +21,7 @@ public: virtual void Visit(LiteralString* e) override; virtual void Visit(LiteralNumber* e) override; virtual void Visit(LiteralBoolean* e) override; + virtual void Visit(LiteralObject* e) override; virtual void Visit(BinaryExpression* e) override; virtual void Visit(UnaryExpression* e) override; virtual void Visit(IdentifierExpression* e) override; @@ -36,8 +37,10 @@ public: virtual void Visit(FunctionDeclaration* e) override; virtual void Visit(TopStatements* e) override; virtual void Visit(EmptyExpression* e) override; + virtual void Visit(CallExpression* e) override; value_type& ModifyVariable(const IPLString& name); + bool HasVariable(const IPLString& name); private: void RunExpression(const ExpressionPtr& e); bool EvalToBool(const ExpressionPtr& e); diff --git a/JSImpl/src/ASTPrinter.h b/JSImpl/src/ASTPrinter.h index cdc0743..e314bcf 100644 --- a/JSImpl/src/ASTPrinter.h +++ b/JSImpl/src/ASTPrinter.h @@ -13,6 +13,7 @@ public: virtual void Visit(LiteralString* e) override; virtual void Visit(LiteralNumber* e) override; virtual void Visit(LiteralBoolean* e) override; + virtual void Visit(LiteralObject* e) override; virtual void Visit(BinaryExpression* e) override; virtual void Visit(UnaryExpression* e) override; virtual void Visit(IdentifierExpression* e) override; @@ -28,6 +29,7 @@ public: virtual void Visit(FunctionDeclaration* e) override; virtual void Visit(TopStatements* e) override; virtual void Visit(EmptyExpression* e) override; + virtual void Visit(CallExpression* e) override; inline void Enter(); inline void Exit(); diff --git a/JSImpl/src/CommonTypes.h b/JSImpl/src/CommonTypes.h index 41e15d3..0e8d420 100644 --- a/JSImpl/src/CommonTypes.h +++ b/JSImpl/src/CommonTypes.h @@ -4,6 +4,7 @@ #include <unordered_map> #include <memory> #include <stack> +#include <cassert> template<typename T> using IPLVector = std::vector<T>; @@ -32,4 +33,6 @@ struct IPLError unsigned Column; IPLString File; IPLString What; -};
\ No newline at end of file +}; + +#define NOT_IMPLEMENTED assert(0 && "not-implemented") diff --git a/JSImpl/src/ExpressionDefinitions.h b/JSImpl/src/ExpressionDefinitions.h index b1b2595..edf344b 100644 --- a/JSImpl/src/ExpressionDefinitions.h +++ b/JSImpl/src/ExpressionDefinitions.h @@ -11,6 +11,9 @@ #define LITERAL_STRING_MEMBERS(MACRO)\ MACRO(IPLString, Value, "") +#define LITERAL_OBJECT_MEMBERS(MACRO)\ + MACRO(IPLVector<ExpressionPtr>, Values, IPLVector<ExpressionPtr>()) + #define BINARY_EXPRESSION_MEMBERS(MACRO)\ MACRO(ExpressionPtr, Left, nullptr)\ MACRO(ExpressionPtr, Right, nullptr)\ @@ -21,12 +24,6 @@ MACRO(TokenType, Operator, TokenType::Invalid)\ MACRO(bool, Suffix, false) -#define LITERAL_EXPRESSION_MEMBERS(MACRO)\ - MACRO(double, NumValue, 0.)\ - MACRO(IPLString, StringValue, "")\ - MACRO(bool, BooleanValue, false)\ - MACRO(LiteralType, Type, LiteralType::Undefined) - #define IDENTIFIER_EXPRESSION_MEMBERS(MACRO)\ MACRO(IPLString, Name, "") @@ -77,12 +74,17 @@ #define TOP_EXPRESSION_MEMBERS(MACRO)\ MACRO(IPLVector<ExpressionPtr>, Values, IPLVector<ExpressionPtr>()) +#define CALL_EXPRESSION_MEMBERS(MACRO)\ + MACRO(ExpressionPtr, Identifier, ExpressionPtr())\ + MACRO(ExpressionPtr, Arguments, ExpressionPtr()) + #define EXPRESSION_DEFINITION_ITERATOR(MACRO)\ MACRO(LiteralNull, Expression, NO_MEMBERS)\ MACRO(LiteralUndefined, Expression, NO_MEMBERS)\ MACRO(LiteralBoolean, Expression, LITERAL_BOOLEAN_MEMBERS)\ MACRO(LiteralNumber, Expression, LITERAL_NUMBER_MEMBERS)\ MACRO(LiteralString, Expression, LITERAL_STRING_MEMBERS)\ + MACRO(LiteralObject, Expression, LITERAL_OBJECT_MEMBERS)\ MACRO(BinaryExpression, Expression, BINARY_EXPRESSION_MEMBERS)\ MACRO(UnaryExpression, Expression, UNARY_EXPRESSION_MEMBERS)\ MACRO(IdentifierExpression, Expression, IDENTIFIER_EXPRESSION_MEMBERS)\ @@ -97,4 +99,5 @@ MACRO(ForStatement, Expression, FOR_EXPRESSION_MEMBERS)\ MACRO(FunctionDeclaration, Expression, FUNCTION_EXPRESSION_MEMBERS)\ MACRO(TopStatements, Expression, TOP_EXPRESSION_MEMBERS)\ - MACRO(EmptyExpression, Expression, NO_MEMBERS) + MACRO(EmptyExpression, Expression, NO_MEMBERS)\ + MACRO(CallExpression, Expression, CALL_EXPRESSION_MEMBERS) diff --git a/JSImpl/src/ExpressionVisitor.h b/JSImpl/src/ExpressionVisitor.h index f35c1cb..f86297f 100644 --- a/JSImpl/src/ExpressionVisitor.h +++ b/JSImpl/src/ExpressionVisitor.h @@ -11,6 +11,7 @@ public: virtual void Visit(LiteralString* e) = 0; virtual void Visit(LiteralNumber* e) = 0; virtual void Visit(LiteralBoolean* e) = 0; + virtual void Visit(LiteralObject* e) = 0; virtual void Visit(BinaryExpression* e) = 0; virtual void Visit(UnaryExpression* e) = 0; virtual void Visit(IdentifierExpression* e) = 0; @@ -26,4 +27,5 @@ public: virtual void Visit(FunctionDeclaration* e) = 0; virtual void Visit(TopStatements* e) = 0; virtual void Visit(EmptyExpression* e) = 0; + virtual void Visit(CallExpression* e) = 0; };
\ No newline at end of file diff --git a/JSImpl/src/ExpressionsFwd.h b/JSImpl/src/ExpressionsFwd.h index f8db609..13a3987 100644 --- a/JSImpl/src/ExpressionsFwd.h +++ b/JSImpl/src/ExpressionsFwd.h @@ -6,6 +6,7 @@ class LiteralUndefined; class LiteralNumber; class LiteralString; class LiteralBoolean; +class LiteralObject; class Expression; class BinaryExpression; class UnaryExpression; @@ -23,5 +24,6 @@ class ForStatement; class FunctionDeclaration; class TopStatements; class EmptyExpression; +class CallExpression; using ExpressionPtr = IPLSharedPtr<Expression>; diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp index 4e1fbca..b0d394b 100644 --- a/JSImpl/src/Parser.cpp +++ b/JSImpl/src/Parser.cpp @@ -1,5 +1,4 @@ #include "Parser.h" -#include <assert.h> class Parser { @@ -15,10 +14,14 @@ private: ExpressionPtr FunctionExpression(); ExpressionPtr ObjectLiteral(); ExpressionPtr ArrayLiteral(); - ExpressionPtr AnonymousFunction(); - ExpressionPtr NamedFunction(); ExpressionPtr Unary(); ExpressionPtr LeftSideExpression(); + ExpressionPtr CallExpression(); + ExpressionPtr CallExpressionHelper(); + ExpressionPtr ShortNewExpression(); + ExpressionPtr ShortNewSubexpression(); + ExpressionPtr FullNewExpression(); + ExpressionPtr FullNewSubexpression(); ExpressionPtr SimpleExpression(); ExpressionPtr MultiplicativeExpression(); ExpressionPtr AdditiveExpression(); @@ -31,6 +34,7 @@ private: ExpressionPtr AssignmentExpression(); ExpressionPtr Expression(); ExpressionPtr OptionalExpression(); + ExpressionPtr Arguments(); //Statements ExpressionPtr Statement(); @@ -55,6 +59,13 @@ private: ExpressionPtr TopStatements(); ExpressionPtr TopStatement(); + struct InternalState + { + unsigned Current; + }; + InternalState Snapshot(); + void Restore(const InternalState& state); + Token& Prev() { return m_Tokens[m_Current - 1]; } IPLVector<Token> m_Tokens; unsigned m_Current; @@ -113,7 +124,7 @@ ExpressionPtr Parser::PrimaryExpression() return nullptr; } -ExpressionPtr Parser::ParenthesizedExpression() +ExpressionPtr Parser::ParenthesizedExpression() { if (Match(TokenType::LeftParen)) { @@ -130,47 +141,99 @@ ExpressionPtr Parser::ParenthesizedExpression() ExpressionPtr Parser::FunctionExpression() { - if (auto aFunc = AnonymousFunction()) - { - return aFunc; - } - else if (auto nFunc = NamedFunction()) + 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)) { - return nFunc; + IPLString name; + if (Match(TokenType::Identifier)) + { + 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; + } + } + // TODO log error + return nullptr; } return nullptr; } ExpressionPtr Parser::ObjectLiteral() { - //ObjectLiteral -> - //{} - // | { FieldList } - //FieldList -> - // LiteralField - // | FieldList, LiteralField - // LiteralField -> Identifier : AssignmentExpressionnormal, allowIn //if (Match(TokenType::LeftBrace)) //{ - // auto LiteralField = [=]() -> ExpressionPtr { + // auto LiteralField = [&]() -> ExpressionPtr { // if (Match(TokenType::Identifier)) // { // auto id = Prev().Lexeme; - // auto ae = AssignmentExpression(); - // return IPLMakeSharePtr<IdentifierExpression>(id, ae); + // ExpressionPtr ae; + // if (Match(TokenType::Colon)) + // { + // ae = AssignmentExpression(); + // } + // return IPLMakeSharePtr<VariableDefinitionExpression>(id, ae); // } // return nullptr; // }; - // auto FieldList = [=]() -> ExpressionPtr { - // auto result = IPLMakeSharePtr<ListExpression>(); - // while (auto lf = LiteralField()) + // auto FieldList = [&]() -> ExpressionPtr { + // auto result = IPLMakeSharePtr<LiteralObject>(); + // auto lf = LiteralField(); + // while (lf) // { - // result->Push(lf); + // result->GetValuesByRef().push_back(lf); // if (!Match(TokenType::Comma)) // { // break; // } + // lf = LiteralField(); + // if (lf) + // { + // // TODO log error + // return nullptr; + // } // } // return result; // }; @@ -187,20 +250,13 @@ ExpressionPtr Parser::ObjectLiteral() ExpressionPtr Parser::ArrayLiteral() { - //ArrayLiteral -> - // [] - //| [ElementList] if (Match(TokenType::LeftSquareBracket)) { - // ElementList -> - // LiteralElement -> AssignmentExpressionnormal, allowIn - auto LiteralElement = [=]() -> ExpressionPtr { + auto LiteralElement = [&]() -> ExpressionPtr { return AssignmentExpression(); }; - auto ElementList = [=]() -> ExpressionPtr { - // LiteralElement - // | ElementList, LiteralElement + auto ElementList = [&]() -> ExpressionPtr { auto result = IPLMakeSharePtr<ListExpression>(); while (auto lf = LiteralElement()) { @@ -223,29 +279,8 @@ ExpressionPtr Parser::ArrayLiteral() return nullptr; } -ExpressionPtr Parser::AnonymousFunction() -{ - return nullptr; -} - -ExpressionPtr Parser::NamedFunction() -{ - return nullptr; -} - ExpressionPtr Parser::SimpleExpression() { - //SimpleExpression - // this - // | null - // | true - // | false - // | Number - // | String - // | Identifier - // | RegularExpression - // | ParenthesizedExpression - // | ArrayLiteral if (Match(TokenType::Number)) { return IPLMakeSharePtr<LiteralNumber>(Prev().Number); @@ -293,57 +328,128 @@ ExpressionPtr Parser::SimpleExpression() ExpressionPtr Parser::LeftSideExpression() { - //LeftSideExpression -> - // CallExpression - // | ShortNewExpression + ExpressionPtr result; + auto ss = Snapshot(); + if (result = CallExpression()) + { + return result; + } + Restore(ss); + if (result = ShortNewExpression()) + { + return result; + } + // TODO error + return nullptr; +} - // CallExpression -> - // PrimaryExpression - // | FullNewExpression - // | CallExpression MemberOperator - // | CallExpression Arguments +ExpressionPtr Parser::CallExpression() +{ + ExpressionPtr result; + auto ss = Snapshot(); + if (result = PrimaryExpression()) + { + return result; + } + Restore(ss); + if (result = FullNewExpression()) + { + return result; + } + + if (result = CallExpressionHelper()) + { + return result; + } + // TODO error + return nullptr; +} - // FullNewExpression -> new FullNewSubexpression Arguments +ExpressionPtr Parser::CallExpressionHelper() +{ + if (Match(TokenType::LeftSquareBracket)) + { + auto expr = Expression(); + if (Match(TokenType::RightSquareBracket)) + { + // return meaningfull expr + auto next = CallExpressionHelper(); + return nullptr; + } + // TODO error + return nullptr; + } + if (Match(TokenType::Dot)) + { + if (Match(TokenType::Identifier)) + { + auto next = CallExpressionHelper(); + // return meaningfull expr + return nullptr; + } + // TODO error + return nullptr; + } - // ShortNewExpression -> new ShortNewSubexpression + if (auto args = Arguments()) + { + // return meaningfull expr + auto next = CallExpressionHelper(); + return nullptr; + } - // FullNewSubexpression -> - // PrimaryExpressionnormal - // | FullNewExpression - // | FullNewSubexpression MemberOperator + return nullptr; +}; - // ShortNewSubexpression -> - // FullNewSubexpression - // | ShortNewExpression +ExpressionPtr Parser::ShortNewExpression() +{ + if (Match(TokenType::New)) + { + return ShortNewSubexpression(); + } + return nullptr; +} - // MemberOperator -> - // [Expressionnormal, allowIn] - //| .Identifier +ExpressionPtr Parser::ShortNewSubexpression() +{ + ExpressionPtr result; + auto ss = Snapshot(); + if (result = FullNewSubexpression()) + { + return result; + } + Restore(ss); + if (result = ShortNewExpression()) + { + return result; + } + // TODO error + return nullptr; +} - // Arguments -> - // () - // | (ArgumentList) +ExpressionPtr Parser::FullNewExpression() +{ + if (Match(TokenType::New)) + { + auto subExpr = FullNewSubexpression(); + auto arguments = Arguments(); + } + return nullptr; +} - // ArgumentList -> - // AssignmentExpressionnormal, allowIn - // | ArgumentList, AssignmentExpressionnormal, allowIn - return SimpleExpression(); +ExpressionPtr Parser::FullNewSubexpression() +{ + ExpressionPtr result; + if (result = PrimaryExpression()) + { + return result; + } + NOT_IMPLEMENTED; + return nullptr; } ExpressionPtr Parser::Unary() { - - //UnaryExpression - // PostfixExpression - // | delete LeftSideExpressionnormal - // | ++LeftSideExpressionnormal - // | --LeftSideExpressionnormal - // | void UnaryExpressionnormal - // | typeof UnaryExpressionnormal - // | +UnaryExpressionnormal - // | -UnaryExpressionnormal - // | ~UnaryExpressionnormal - // | !UnaryExpressionnormal if (MatchOneOf({ TokenType::Delete, TokenType::MinusMinus, @@ -370,10 +476,6 @@ ExpressionPtr Parser::Unary() } else { - //PostfixExpression - // LeftSideExpression - // | LeftSideExpression++ - // | LeftSideExpression-- auto leftSide = LeftSideExpression(); if (MatchOneOf({ TokenType::PlusPlus, TokenType::MinusMinus })) { @@ -386,11 +488,6 @@ ExpressionPtr Parser::Unary() ExpressionPtr Parser::MultiplicativeExpression() { - //MultiplicativeExpression - // UnaryExpression - // | MultiplicativeExpression * UnaryExpression normal - // | MultiplicativeExpression / UnaryExpression normal - // | MultiplicativeExpression % UnaryExpression normal auto left = Unary(); while(MatchOneOf({ TokenType::Star, TokenType::Division, TokenType::Modulo })) @@ -404,10 +501,6 @@ ExpressionPtr Parser::MultiplicativeExpression() ExpressionPtr Parser::AdditiveExpression() { - //AdditiveExpression - // MultiplicativeExpression - // | AdditiveExpression + MultiplicativeExpression normal - // | AdditiveExpression - MultiplicativeExpression normal auto left = MultiplicativeExpression(); while (MatchOneOf({ TokenType::Plus, TokenType::Minus})) { @@ -420,11 +513,6 @@ ExpressionPtr Parser::AdditiveExpression() ExpressionPtr Parser::ShiftExpression() { - //ShiftExpression - // AdditiveExpression - // | ShiftExpression << AdditiveExpression normal - // | ShiftExpression >> AdditiveExpression normal - // | ShiftExpression >> > AdditiveExpression normal auto left = AdditiveExpression(); while (MatchOneOf({ TokenType::LeftShift, TokenType::RightShift })) { @@ -437,21 +525,6 @@ ExpressionPtr Parser::ShiftExpression() ExpressionPtr Parser::RelationalExpression() { - //RelationalExpression, allowIn -> - // ShiftExpression - // | RelationalExpression, allowIn < ShiftExpression normal - // | RelationalExpression, allowIn > ShiftExpression normal - // | RelationalExpression, allowIn <= ShiftExpression normal - // | RelationalExpression, allowIn >= ShiftExpression normal - // | RelationalExpression, allowIn instanceof ShiftExpression normal - // | RelationalExpression, allowIn in ShiftExpression normal - // RelationalExpression, noIn -> - // ShiftExpression - // | RelationalExpression, noIn < ShiftExpression normal - // | RelationalExpression, noIn > ShiftExpression normal - // | RelationalExpression, noIn <= ShiftExpression normal - // | RelationalExpression, noIn >= ShiftExpression normal - // | RelationalExpression, noIn instanceof ShiftExpression normal auto left = ShiftExpression(); while (MatchOneOf({ TokenType::Less, TokenType::Greater, @@ -470,17 +543,12 @@ ExpressionPtr Parser::RelationalExpression() ExpressionPtr Parser::EqualityExpression() { - //EqualityExpression - // RelationalExpression - // | EqualityExpression == RelationalExpression normal - // | EqualityExpression != RelationalExpression normal - // | EqualityExpression == = RelationalExpression normal - // | EqualityExpression != = RelationalExpression normal auto left = RelationalExpression(); - while (MatchOneOf({ TokenType::Equal, + while (MatchOneOf({TokenType::EqualEqual, TokenType::BangEqual, TokenType::StrictEqual, TokenType::StrictNotEqual, + })) { auto type = Prev().Type; @@ -492,10 +560,7 @@ ExpressionPtr Parser::EqualityExpression() ExpressionPtr Parser::BitwiseExpression() { - auto BitwiseAndExpression = [=]() -> ExpressionPtr { - //BitwiseAndExpression -> - // EqualityExpression - // | BitwiseAndExpression & EqualityExpression normal + auto BitwiseAndExpression = [&]() -> ExpressionPtr { auto left = EqualityExpression(); while (Match(TokenType::BitwiseAnd)) { @@ -506,10 +571,7 @@ ExpressionPtr Parser::BitwiseExpression() return left; }; - auto BitwiseXorExpression = [=]() -> ExpressionPtr { - //BitwiseXorExpression -> - // BitwiseAndExpression - // | BitwiseXorExpression ^ BitwiseAndExpression normal + auto BitwiseXorExpression = [&]() -> ExpressionPtr { auto left = BitwiseAndExpression(); while (Match(TokenType::BitwiseXor)) { @@ -521,10 +583,7 @@ ExpressionPtr Parser::BitwiseExpression() }; std::function<ExpressionPtr()> BitwiseOrExpression; - BitwiseOrExpression = [=]() -> ExpressionPtr { - //BitwiseOrExpression -> - // BitwiseXorExpression - // | BitwiseOrExpression | BitwiseXorExpression normal + BitwiseOrExpression = [&]() -> ExpressionPtr { auto left = BitwiseXorExpression(); while (Match(TokenType::BitwiseOr)) { @@ -542,10 +601,7 @@ ExpressionPtr Parser::BitwiseExpression() ExpressionPtr Parser::LogicalExpression() { std::function<ExpressionPtr()> LogicalAndExpression; - LogicalAndExpression = [=]() -> ExpressionPtr { - //LogicalAndExpression -> - // BitwiseOrExpression - // | LogicalAndExpression && BitwiseOrExpression normal + LogicalAndExpression = [&]() -> ExpressionPtr { auto left = BitwiseExpression(); while (Match(TokenType::LogicalAnd)) { @@ -557,10 +613,7 @@ ExpressionPtr Parser::LogicalExpression() }; std::function<ExpressionPtr()> LogicalOrExpression; - LogicalOrExpression = [=]() -> ExpressionPtr { - //LogicalOrExpression - // LogicalAndExpression - // | LogicalOrExpression || LogicalAndExpression normal + LogicalOrExpression = [&]() -> ExpressionPtr { auto left = LogicalAndExpression(); while (Match(TokenType::LogicalAnd)) { @@ -576,9 +629,6 @@ ExpressionPtr Parser::LogicalExpression() ExpressionPtr Parser::ConditionalExpression() { - //ConditionalExpression -> - // LogicalOrExpression - // | LogicalOrExpression ? AssignmentExpression normal : AssignmentExpression normal auto condition = LogicalExpression(); if (Match(TokenType::QuestionMark)) { @@ -598,11 +648,6 @@ ExpressionPtr Parser::ConditionalExpression() ExpressionPtr Parser::AssignmentExpression() { - //AssignmentExpression -> - // ConditionalExpression - // | LeftSideExpression = AssignmentExpression normal - // | LeftSideExpression CompoundAssignment AssignmentExpression normal - auto snapShot = m_Current; auto left = LeftSideExpression(); if (MatchOneOf({ TokenType::Equal, @@ -627,9 +672,6 @@ ExpressionPtr Parser::AssignmentExpression() ExpressionPtr Parser::Expression() { - //Expression -> - // AssignmentExpression - // | Expression , AssignmentExpression normal auto ae = AssignmentExpression(); while (Match(TokenType::Comma)) { @@ -652,20 +694,21 @@ ExpressionPtr Parser::Statement() { ExpressionPtr result; if (result = EmptyStatement()) return result; - else if(result = VariableDefinition()) return result; - else if(result = Block()) return result; - else if(result = LabeledStatement()) return result; - else if(result = IfStatementfull()) return result; - else if(result = SwitchStatement()) return result; - else if(result = DoStatement()) return result; - else if(result = WhileStatement()) return result; - else if(result = ForStatement()) return result; - else if(result = WithStatement()) return result; - else if(result = ContinueStatement()) return result; - else if(result = BreakStatement()) return result; - else if(result = OptionalLabel()) return result; - else if(result = ReturnStatement()) return result; - else if(result = TryStatement()) return result; + if (result = Expression()) return result; + if (result = VariableDefinition()) return result; + if (result = Block()) return result; + if (result = LabeledStatement()) return result; + if (result = IfStatementfull()) return result; + if (result = SwitchStatement()) return result; + if (result = DoStatement()) return result; + if (result = WhileStatement()) return result; + if (result = ForStatement()) return result; + if (result = WithStatement()) return result; + if (result = ContinueStatement()) return result; + if (result = BreakStatement()) return result; + if (result = OptionalLabel()) return result; + if (result = ReturnStatement()) return result; + if (result = TryStatement()) return result; return result; } @@ -682,11 +725,7 @@ ExpressionPtr Parser::EmptyStatement() ExpressionPtr Parser::VariableDefinition() { - auto VariableDeclaration = [=]() -> ExpressionPtr { - // VariableDeclaration -> Identifier VariableInitializer - // VariableInitializer -> - // «empty» - // | = AssignmentExpressionnormal, + auto VariableDeclaration = [&]() -> ExpressionPtr { if (Match(TokenType::Identifier)) { auto id = Prev().Lexeme; @@ -700,10 +739,7 @@ ExpressionPtr Parser::VariableDefinition() return nullptr; }; - auto VariableDeclarationList = [=]() -> ExpressionPtr { - // VariableDeclarationList -> - // VariableDeclaration - // | VariableDeclarationList, VariableDeclaration + auto VariableDeclarationList = [&]() -> ExpressionPtr { auto vdList = IPLMakeSharePtr<ListExpression>(); vdList->GetValuesByRef().push_back(VariableDeclaration()); while (Match(TokenType::Comma)) @@ -713,7 +749,6 @@ ExpressionPtr Parser::VariableDefinition() return vdList; }; - //VariableDefinition -> var VariableDeclarationListallowIn if (Match(TokenType::Var)) { return VariableDeclarationList(); @@ -724,12 +759,7 @@ ExpressionPtr Parser::VariableDefinition() ExpressionPtr Parser::Block() { - auto BlockStatementsPrefix = [=]() -> ExpressionPtr { - // BlockStatementsPrefix -> - // Statement full - // | BlockStatementsPrefix Statement full - - //return Statement; + auto BlockStatementsPrefix = [&]() -> ExpressionPtr { auto StatementsList = IPLMakeSharePtr<BlockStatement>(); while (auto s = Statement()) { @@ -740,9 +770,10 @@ ExpressionPtr Parser::Block() if (Match(TokenType::LeftBrace)) { - if (!Match(TokenType::RightBrace)) + auto statements = BlockStatementsPrefix(); + if (Match(TokenType::RightBrace)) { - return BlockStatementsPrefix(); + return statements; } else { @@ -935,20 +966,53 @@ ExpressionPtr Parser::TryStatement() ExpressionPtr Parser::OptionalExpression() { - //OptionalExpression -> - // Expressionnormal, allowIn - // | «empty» return Parser::Expression(); } +ExpressionPtr Parser::Arguments() +{ + if (Match(TokenType::LeftParen)) + { + auto result = IPLMakeSharePtr<ListExpression>(); + auto current = AssignmentExpression(); + while (current) + { + result->GetValuesByRef().push_back(current); + if (Match(TokenType::Comma)) + { + current = AssignmentExpression(); + if (current) + { + // TODO error + return nullptr; + } + } + else + { + current = nullptr; + } + } + + if (Match(TokenType::RightParen)) + { + return result; + } + // TODO error + return nullptr; + } + return nullptr; +} + ExpressionPtr Parser::Parse() { - return Parser::Program(); + auto result = Parser::Program(); + assert(m_Current + 1 == m_Tokens.size()); + return result; } ExpressionPtr Parser::FunctionDefinition() { - auto FormalParameters = [=](IPLVector<IPLString>& identifiers) -> bool { + auto FormalParameters = [&](IPLVector<IPLString>& identifiers) -> bool { if (Match(TokenType::LeftParen)) { while (Match(TokenType::Identifier)) @@ -968,7 +1032,7 @@ ExpressionPtr Parser::FunctionDefinition() return false; }; - auto Body = [=]() -> ExpressionPtr { + auto Body = [&]() -> ExpressionPtr { if (Match(TokenType::LeftBrace)) { @@ -1035,3 +1099,13 @@ ExpressionPtr Parse(const IPLVector<Token>& tokens, const std::function<void()>& Parser p(tokens, onError); return p.Parse(); } + +Parser::InternalState Parser::Snapshot() +{ + return { m_Current }; +} + +void Parser::Restore(const InternalState& state) +{ + m_Current = state.Current; +} diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp index 3fe6f99..0d78a10 100644 --- a/JSImpl/src/main.cpp +++ b/JSImpl/src/main.cpp @@ -8,7 +8,7 @@ void RunParseCalc() { IPLVector<Token> tokens; //Tokenize("var a = 0; var b = a + 123;a+b;", tokens); - Tokenize("var s = 0; for (var i = 0; i < 10; ++i + --s) { s };", tokens); + Tokenize("var a = 5; if(a == 5){a++;}", tokens); // TODO make actual test :D auto expr = Parse(tokens); @@ -22,7 +22,7 @@ void RunParseCalc() std::cout << result.back() << std::endl; result.pop_back(); } - std::cout << "S = " << i.ModifyVariable("s") << std::endl; + std::cout << "S = " << i.ModifyVariable("a") << std::endl; } int main() |
