Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl / src
diff options
context:
space:
mode:
Commit1df22a637e5c5ac090f7d90c5c666da1b22964d5 (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-09-11 09:38:31 +0300
Committer
 martin dobrev <martindobrev0@gmail.com>
2018-09-11 09:38:31 +0300
Files69b7a527c7f6872c140f4b035929ad60f38cd017 /JSImpl/src
IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.tar
IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.tar.gz
IPL-1df22a637e5c5ac090f7d90c5c666da1b22964d5.zip
Parenteeab42ab1d16b5e3cfafeeffbe6aa8045212134e (diff)
Implement parsing for flow control elements like if, for etc.
3 files changed, 501 insertions, 24 deletions
-rw-r--r--JSImpl/src/Expression.cpp101
-rw-r--r--JSImpl/src/Expression.h111
-rw-r--r--JSImpl/src/Parser.cpp313
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