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