Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src
diff options
context:
space:
mode:
Commitd51e7e38448e24123af13f0fa2682b861a64f964 (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-11-02 00:12:31 +0200
Committer
 martin dobrev <martindobrev0@gmail.com>
2018-11-02 00:12:31 +0200
Filesff687e7a9aba1f8d53af110afe3e1e079e7b2614 /JSImpl/src
IPL-d51e7e38448e24123af13f0fa2682b861a64f964.tar
IPL-d51e7e38448e24123af13f0fa2682b861a64f964.tar.gz
IPL-d51e7e38448e24123af13f0fa2682b861a64f964.zip
Parent8f90af904002a028d37cbf25a07d81f7984577d1 (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.cpp24
-rw-r--r--JSImpl/src/ASTInterpreter.h3
-rw-r--r--JSImpl/src/ASTPrinter.h2
-rw-r--r--JSImpl/src/CommonTypes.h5
-rw-r--r--JSImpl/src/ExpressionDefinitions.h17
-rw-r--r--JSImpl/src/ExpressionVisitor.h2
-rw-r--r--JSImpl/src/ExpressionsFwd.h2
-rw-r--r--JSImpl/src/Parser.cpp478
-rw-r--r--JSImpl/src/main.cpp4
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()