Website Summary Files Commits Branches @commit @diff @stats
path: root / JSImpl
diff options
context:
space:
mode:
Commit2621d30da58795a19fa2c90978f766e173a8ca2f (patch)
Author
 martin dobrev <martindobrev0@gmail.com>
2018-10-14 15:11:59 +0300
Committer
 martin dobrev <martindobrev0@gmail.com>
2018-10-14 15:11:59 +0300
Filesb85eefde3ea7b5a39a355e7ff13e38debeadb31d /JSImpl
IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.tar
IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.tar.gz
IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.zip
Parentab6cd5aaa4e1ceb12ade89a4a0c5376092fa8dfb (diff)
Parent47a7a68e2b7ce0b0c1e2bd1097927a91623fbcc5 (diff)
Merge branch 'expressions-rework'
9 files changed, 381 insertions, 509 deletions
-rw-r--r--JSImpl/src/ASTPrinter.cpp261
-rw-r--r--JSImpl/src/ASTPrinter.h35
-rw-r--r--JSImpl/src/Expression.cpp277
-rw-r--r--JSImpl/src/Expression.h290
-rw-r--r--JSImpl/src/ExpressionVisitor.h1
-rw-r--r--JSImpl/src/ExpressionsFwd.h2
-rw-r--r--JSImpl/src/Lexer.h1
-rw-r--r--JSImpl/src/Parser.cpp17
-rw-r--r--JSImpl/src/main.cpp6
diff --git a/JSImpl/src/ASTPrinter.cpp b/JSImpl/src/ASTPrinter.cpp
index dfb3447..d8f5ff8 100644
--- a/JSImpl/src/ASTPrinter.cpp
+++ b/JSImpl/src/ASTPrinter.cpp
@@ -1,34 +1,233 @@
#include "ASTPrinter.h"
+#include "Expression.h"
-ASTPrinter::ASTPrinter(std::ostream&)
-{}
-void ASTPrinter::Visit(BinaryExpression*)
-{}
-void ASTPrinter::Visit(UnaryExpression*)
-{}
-void ASTPrinter::Visit(LiteralExpression*)
-{}
-void ASTPrinter::Visit(IdentifierExpression*)
-{}
-void ASTPrinter::Visit(ListExpression*)
-{}
-void ASTPrinter::Visit(VariableDefinitionExpression*)
-{}
-void ASTPrinter::Visit(BlockStatement*)
-{}
-void ASTPrinter::Visit(LabeledStatement*)
-{}
-void ASTPrinter::Visit(IfStatement*)
-{}
-void ASTPrinter::Visit(SwitchStatement*)
-{}
-void ASTPrinter::Visit(WhileStatement*)
-{}
-void ASTPrinter::Visit(ForStatement*)
-{}
-void ASTPrinter::Visit(FunctionDeclaration*)
-{}
-void ASTPrinter::Visit(TopStatements*)
-{}
-void ASTPrinter::Visit(EmptyExpression*)
+ASTPrinter::ASTPrinter(std::ostream& os)
+ : os(os)
{}
+
+void Print(std::ostream& os, ASTPrinter &printer, const char* name, const ExpressionPtr& expr, bool isLast)
+{
+ os << "\"" << name << "\" : ";
+ expr->Accept(printer);
+ if (!isLast)
+ {
+ os << ",";
+ }
+}
+
+void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector<ExpressionPtr>& list, bool isLast)
+{
+ os << "\"" << name << "\" : [ \n";
+ for (auto i = 0; i < list.size(); ++i)
+ {
+ list[i]->Accept(printer);
+ if (i + 1 != list.size())
+ {
+ os << ",";
+ }
+ }
+ os << "]";
+ if (!isLast)
+ {
+ os << ",";
+ }
+ os << "\n";
+}
+
+void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector<IPLString>& list, bool isLast)
+{
+ os << "\"" << name << "\" : [ \n";
+ for (auto i = 0; i < list.size(); ++i)
+ {
+ if (i + 1 != list.size())
+ {
+ os << list[i] << ",";
+ }
+ }
+ os << "]";
+ if (!isLast)
+ {
+ os << ",";
+ }
+ os << "\n";
+}
+
+template<typename T>
+void Print(std::ostream& os, ASTPrinter &printer, const char* name, T member, bool isLast)
+{
+ os << "\"" << name << "\" :" << member;
+ if (!isLast)
+ {
+ os << ",";
+ }
+ os << "\n";
+}
+
+template<>
+void Print<IPLString>(std::ostream& os, ASTPrinter &printer, const char* name, IPLString member, bool isLast)
+{
+ os << "\"" << name << "\" : \"" << member << "\"";
+ if (!isLast)
+ {
+ os << ",";
+ }
+ os << "\n";
+}
+
+template<>
+void Print<const IPLString&>(std::ostream& os, ASTPrinter &printer, const char* name, const IPLString& member, bool isLast)
+{
+ os << "\"" << name << "\" : \"" << member << "\"";
+ if (!isLast)
+ {
+ os << ",";
+ }
+ os << "\n";
+}
+
+IPLString AsString(LiteralType type)
+{
+ switch (type)
+ {
+ case LiteralType::Number:
+ return "Number";
+ case LiteralType::String:
+ return "String";
+ case LiteralType::Boolean:
+ return "Boolean";
+ case LiteralType::Null:
+ return "Null";
+ case LiteralType::Undefined:
+ return "Undefined";
+ default:
+ break;
+ }
+ return "Undefined";
+}
+
+std::ostream& operator<<(std::ostream& os, const TokenType& t)
+{
+ switch (t)
+ {
+ case TokenType::LeftParen: os << "\"LeftParen\""; return os;
+ case TokenType::RightParen: os << "\"RightParen\""; return os;
+ case TokenType::LeftBrace: os << "\"LeftBrace\""; return os;
+ case TokenType::RightBrace: os << "\"RightBrace\""; return os;
+ case TokenType::Comma: os << "\"Comma\""; return os;
+ case TokenType::Dot: os << "\"Dot\""; return os;
+ case TokenType::Minus: os << "\"Minus\""; return os;
+ case TokenType::Plus: os << "\"Plus\""; return os;
+ case TokenType::Semicolon: os << "\"Semicolon\""; return os;
+ case TokenType::Star: os << "\"Star\""; return os;
+ case TokenType::Division: os << "\"Division\""; return os;
+ case TokenType::Modulo: os << "\"Modulo\""; return os;
+ case TokenType::BitwiseNot: os << "\"BitwiseNot\""; return os;
+ case TokenType::BitwiseAnd: os << "\"BitwiseAnd\""; return os;
+ case TokenType::BitwiseXor: os << "\"BitwiseXor\""; return os;
+ case TokenType::BitwiseOr: os << "\"BitwiseOr\""; return os;
+ case TokenType::QuestionMark: os << "\"QuestionMark\""; return os;
+ case TokenType::Colon: os << "\"Colon\""; return os;
+ case TokenType::LeftSquareBracket: os << "\"LeftSquareBracket\""; return os;
+ case TokenType::RightSquareBracket: os << "\"RightSquareBracket\""; return os;
+ case TokenType::Bang: os << "\"Bang\""; return os;
+ case TokenType::BangEqual: os << "\"BangEqual\""; return os;
+ case TokenType::Equal: os << "\"Equal\""; return os;
+ case TokenType::EqualEqual: os << "\"EqualEqual\""; return os;
+ case TokenType::StrictEqual: os << "\"StrictEqual\""; return os;
+ case TokenType::StrictNotEqual: os << "\"StrictNotEqual\""; return os;
+ case TokenType::Greater: os << "\"Greater\""; return os;
+ case TokenType::GreaterEqual: os << "\"GreaterEqual\""; return os;
+ case TokenType::Less: os << "\"Less\""; return os;
+ case TokenType::LessEqual: os << "\"LessEqual\""; return os;
+ case TokenType::MinusMinus: os << "\"MinusMinus\""; return os;
+ case TokenType::PlusPlus: os << "\"PlusPlus\""; return os;
+ case TokenType::LeftShift: os << "\"LeftShift\""; return os;
+ case TokenType::RightShift: os << "\"RightShift\""; return os;
+ case TokenType::LogicalAnd: os << "\"LogicalAnd\""; return os;
+ case TokenType::LogicalOr: os << "\"LogicalOr\""; return os;
+ case TokenType::StarEqual: os << "\"StarEqual\""; return os;
+ case TokenType::DivideEqual: os << "\"DivideEqual\""; return os;
+ case TokenType::ModuloEqual: os << "\"ModuloEqual\""; return os;
+ case TokenType::PlusEqual: os << "\"PlusEqual\""; return os;
+ case TokenType::MinusEqual: os << "\"MinusEqual\""; return os;
+ case TokenType::LeftShiftEqual: os << "\"LeftShiftEqual\""; return os;
+ case TokenType::RightShiftEqual: os << "\"RightShiftEqual\""; return os;
+ case TokenType::BitwiseAndEqual: os << "\"BitwiseAndEqual\""; return os;
+ case TokenType::BitwiseXorEqual: os << "\"BitwiseXorEqual\""; return os;
+ case TokenType::BitwiseOrEqual: os << "\"BitwiseOrEqual\""; return os;
+ case TokenType::Identifier: os << "\"Identifier\""; return os;
+ case TokenType::String: os << "\"String\""; return os;
+ case TokenType::Number: os << "\"Number\""; return os;
+ case TokenType::Break: os << "\"Break\""; return os;
+ case TokenType::Case: os << "\"Case\""; return os;
+ case TokenType::Catch: os << "\"Catch\""; return os;
+ case TokenType::Class: os << "\"Class\""; return os;
+ case TokenType::Const: os << "\"Const\""; return os;
+ case TokenType::Continue: os << "\"Continue\""; return os;
+ case TokenType::Debugger: os << "\"Debugger\""; return os;
+ case TokenType::Default: os << "\"Default\""; return os;
+ case TokenType::Delete: os << "\"Delete\""; return os;
+ case TokenType::Do: os << "\"Do\""; return os;
+ case TokenType::Else: os << "\"Else\""; return os;
+ case TokenType::Export: os << "\"Export\""; return os;
+ case TokenType::Extends: os << "\"Extends\""; return os;
+ case TokenType::Finally: os << "\"Finally\""; return os;
+ case TokenType::For: os << "\"For\""; return os;
+ case TokenType::Function: os << "\"Function\""; return os;
+ case TokenType::If: os << "\"If\""; return os;
+ case TokenType::Import: os << "\"Import\""; return os;
+ case TokenType::In: os << "\"In\""; return os;
+ case TokenType::Instanceof: os << "\"Instanceof\""; return os;
+ case TokenType::New: os << "\"New\""; return os;
+ case TokenType::Return: os << "\"Return\""; return os;
+ case TokenType::Super: os << "\"Super\""; return os;
+ case TokenType::Switch: os << "\"Switch\""; return os;
+ case TokenType::This: os << "\"This\""; return os;
+ case TokenType::Throw: os << "\"Throw\""; return os;
+ case TokenType::Try: os << "\"Try\""; return os;
+ case TokenType::Typeof: os << "\"Typeof\""; return os;
+ case TokenType::Var: os << "\"Var\""; return os;
+ case TokenType::Void: os << "\"Void\""; return os;
+ case TokenType::While: os << "\"While\""; return os;
+ case TokenType::With: os << "\"With\""; return os;
+ case TokenType::Yield: os << "\"Yield\""; return os;
+ case TokenType::Null: os << "\"Null\""; return os;
+ case TokenType::Undefined: os << "\"Undefined\""; return os;
+ case TokenType::True: os << "\"True\""; return os;
+ case TokenType::False: os << "\"False\""; return os;
+ case TokenType::Eof: os << "\"Eof\""; return os;
+ case TokenType::Invalid: os << "\"Invalid\""; return os;
+ default:
+ break;
+ }
+ return os;
+}
+
+void ASTPrinter::Visit(LiteralExpression* e)
+{
+ os << "{\n" << "\"ExpresionType\": \"LiteralExpression\"," << '\n';
+ Print(os, *this, "BooleanValue", e->GetBooleanValue(), false);
+ Print(os, *this, "LiteralType", AsString(e->GetLiteralType()), false);
+ Print(os, *this, "NumValue", e->GetNumValue(), false);
+ Print(os, *this, "StringValue", e->GetStringValue(), true);
+ os << "}\n";
+}
+
+#define MEMBERS_COUNT(type, name, def) ++membersCount;
+#define VISIT_MEMBER(type, name, def) ++currentVisitCount; Print(os, *this, #name, e->Get##name(), currentVisitCount == membersCount);;
+
+#define GENERATE_AST_PRINTER_FUNCTION(ClassName, Base, MEMBERS_ITERATOR)\
+ void ASTPrinter::Visit(ClassName* e) \
+ { \
+ int membersCount = 0, currentVisitCount = 0; \
+ MEMBERS_ITERATOR(MEMBERS_COUNT); \
+ if(membersCount) \
+ os << "{\n \"ExpresionType\": \"" << #ClassName "\","<< '\n'; \
+ else \
+ os << "{\n \"ExpresionType\": \"" << #ClassName "\"" << '\n'; \
+ MEMBERS_ITERATOR(VISIT_MEMBER); \
+ os << "}\n"; \
+ }
+
+
+EXPRESSION_DEFINITION_ITERATOR(GENERATE_AST_PRINTER_FUNCTION); \ No newline at end of file
diff --git a/JSImpl/src/ASTPrinter.h b/JSImpl/src/ASTPrinter.h
index f96f880..54a9090 100644
--- a/JSImpl/src/ASTPrinter.h
+++ b/JSImpl/src/ASTPrinter.h
@@ -3,25 +3,28 @@
#include "ExpressionVisitor.h"
#include <iosfwd>
-
class ASTPrinter : public ExpressionVisitor
{
public:
ASTPrinter(std::ostream& os);
~ASTPrinter() {}
- virtual void Visit(BinaryExpression* e) = 0;
- virtual void Visit(UnaryExpression* e) = 0;
- virtual void Visit(LiteralExpression* e) = 0;
- virtual void Visit(IdentifierExpression* e) = 0;
- virtual void Visit(ListExpression* e) = 0;
- virtual void Visit(VariableDefinitionExpression* e) = 0;
- virtual void Visit(BlockStatement* e) = 0;
- virtual void Visit(LabeledStatement* e) = 0;
- virtual void Visit(IfStatement* e) = 0;
- virtual void Visit(SwitchStatement* e) = 0;
- virtual void Visit(WhileStatement* e) = 0;
- virtual void Visit(ForStatement* e) = 0;
- virtual void Visit(FunctionDeclaration* e) = 0;
- virtual void Visit(TopStatements* e) = 0;
- virtual void Visit(EmptyExpression* e) = 0;
+ virtual void Visit(BinaryExpression* e) override;
+ virtual void Visit(UnaryExpression* e) override;
+ virtual void Visit(LiteralExpression* e) override;
+ virtual void Visit(IdentifierExpression* e) override;
+ virtual void Visit(ListExpression* e) override;
+ virtual void Visit(VariableDefinitionExpression* e) override;
+ virtual void Visit(BlockStatement* e) override;
+ virtual void Visit(LabeledStatement* e) override;
+ virtual void Visit(IfStatement* e) override;
+ virtual void Visit(SwitchStatement* e) override;
+ virtual void Visit(CaseStatement *) override;
+ virtual void Visit(WhileStatement* e) override;
+ virtual void Visit(ForStatement* e) override;
+ virtual void Visit(FunctionDeclaration* e) override;
+ virtual void Visit(TopStatements* e) override;
+ virtual void Visit(EmptyExpression* e) override;
+private:
+ std::ostream& os;
+
};
diff --git a/JSImpl/src/Expression.cpp b/JSImpl/src/Expression.cpp
index 22e3da3..b8044e1 100644
--- a/JSImpl/src/Expression.cpp
+++ b/JSImpl/src/Expression.cpp
@@ -1,92 +1,6 @@
#include "Expression.h"
#include <assert.h>
-#include <iostream>
-
-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)
-, m_Operator(op)
-{}
-
-IPLString BinaryExpression::GetOperatorTypeAsString() const
-{
- // TODO: Implement
- (void)m_Operator;
- return "Binary";
-}
-
-void BinaryExpression::Print(std::ostream& os) const
-{
- os << "{ \n";
- os << " Expression Type: Binary" << std::endl;
- os << " Left expr: ";
- m_Left->Print(os);
-
- os << " Right expr:";
- m_Right->Print(os);
-
- os << " Operator Type: " << GetOperatorTypeAsString();
- os << "\n}\n";
-}
-
-UnaryExpression::UnaryExpression(IPLSharedPtr<Expression> expr, TokenType op, bool suffix)
- : m_Expr(expr)
- , m_Operator(op)
- , m_Suffix(suffix)
-{
-}
-
-void UnaryExpression::Print(std::ostream& os) const
-{
- os << "{ \n";
- os << " Expression Type: Unary" << std::endl;
- os << " Expression: ";
- m_Expr->Print(os);
-
- os << " Operator Type: " << GetOperatorTypeAsString() << std::endl;
- os << " Suffix Type: " << (m_Suffix ? "true" : "false") << std::endl;
- os << "\n}\n";
-}
-
-IPLString UnaryExpression::GetOperatorTypeAsString() const
-{
- switch (m_Operator)
- {
- case TokenType::Delete: return "delete";
- case TokenType::MinusMinus: return "--";
- case TokenType::PlusPlus: return "++";
- case TokenType::Void: return "void";
- case TokenType::Typeof: return "void";
- case TokenType::Plus: return "+";
- case TokenType::Minus: return "-";
- case TokenType::BitwiseNot: return "~";
- case TokenType::Bang: return "!";
- default:
- break;
- }
- // TODO: Implement
- return "Unary";
-}
-
LiteralExpression::LiteralExpression(double v)
:m_Type(LiteralType::Number)
, m_NumValue(v)
@@ -117,194 +31,3 @@ LiteralExpression::LiteralExpression(TokenType type)
assert(false);
}
}
-
-void LiteralExpression::Print(std::ostream& os) const
-{
- os << "{ \n";
- os << " Expression Type: Unary" << std::endl;
- switch (m_Type)
- {
- case LiteralType::Number:
- os << " Literal Type: Number" << std::endl;
- os << " Literal value: " << m_NumValue << std::endl;
- break;
- case LiteralType::String:
- os << " Literal Type: String" << std::endl;
- os << " Literal value: " << m_StringValue << std::endl;
- break;
- case LiteralType::Boolean:
- os << " Literal Type: Boolean" << std::endl;
- os << " Literal value: " << m_BooleanValue << std::endl;
- break;
- case LiteralType::Null:
- os << " Literal Type: Null" << std::endl;
- os << " Literal value: null" << std::endl;
- case LiteralType::Undefined:
- os << " Literal Type: Undefined" << std::endl;
- os << " Literal value: undefined" << std::endl;
- break;
- default:
- break;
- }
-
- os << "\n}\n";
-}
-
-IdentifierExpression::IdentifierExpression(IPLString& name)
- : m_Name(name)
-{
-}
-
-void IdentifierExpression::Print(std::ostream& os) const
-{
- os << "{ \n";
- os << " Expression Type: Identifier" << std::endl;
- os << "Identifier name: " << m_Name << std::endl;
- os << "\n}\n";
-}
-
-void ListExpression::Print(std::ostream& os) const
-{
- os << "{ \n";
- os << " Expression Type: List" << std::endl;
- for (auto& e : m_Values)
- {
- e->Print(os);
- }
- os << "\n}\n";
-}
-
-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 << "{ LabeledStatement 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 << "{ IfStatement 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 << "{ SwitchStatement 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
-{
- (void)(m_DoWhile);
- os << "{ WhileStatement 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 << "{ 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 dc37753..df8c00b 100644
--- a/JSImpl/src/Expression.h
+++ b/JSImpl/src/Expression.h
@@ -8,62 +8,32 @@ class Expression : public IPLEnableShared<Expression>
{
public:
virtual ~Expression() {}
- virtual void Print(std::ostream&) const {};
virtual void Accept(ExpressionVisitor& v) = 0;
};
-// binary:= expression operator expression
-class BinaryExpression : public Expression
+enum class LiteralType
{
-public:
- virtual ~BinaryExpression() {}
- BinaryExpression(ExpressionPtr exprLeft, ExpressionPtr exprRight, TokenType op);
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- IPLString GetOperatorTypeAsString() const;
-private:
- ExpressionPtr m_Left;
- ExpressionPtr m_Right;
- TokenType m_Operator;
-};
-
-// binary:= expression operator |
-// operator expression
-class UnaryExpression : public Expression
-{
-public:
- virtual ~UnaryExpression() {}
- UnaryExpression(IPLSharedPtr<Expression> expr, TokenType op, bool suffix);
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- IPLString GetOperatorTypeAsString() const;
-private:
- IPLSharedPtr<Expression> m_Expr;
- TokenType m_Operator;
- bool m_Suffix;
+ Number,
+ String,
+ Boolean,
+ Null,
+ Undefined
};
-// literal:= number | string | true | false | null | undefined
class LiteralExpression : public Expression
{
public:
- enum LiteralType
- {
- Number,
- String,
- Boolean,
- Null,
- Undefined,
- };
+
virtual ~LiteralExpression() {}
LiteralExpression(double);
LiteralExpression(IPLString&);
LiteralExpression(bool);
LiteralExpression(TokenType type);
- virtual void Print(std::ostream& os) const override;
virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
+ double GetNumValue() const { return m_NumValue; }
+ const IPLString& GetStringValue() const { return m_StringValue; }
+ bool GetBooleanValue() const { return m_BooleanValue; }
+ LiteralType GetLiteralType() const { return m_Type; }
private:
LiteralType m_Type;
bool m_BooleanValue;
@@ -72,150 +42,122 @@ private:
};
-class IdentifierExpression : public Expression
-{
-public:
- IdentifierExpression(IPLString& name);
- virtual ~IdentifierExpression() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-protected:
- IPLString m_Name;
+#define EXPAND_ARGUMENT(type, name, def)\
+ type name = def,
-};
+#define EXPAND_INITIALIZER_LIST(type, name, def)\
+ m_##name(name),
-class ListExpression : public Expression
-{
-public:
- ListExpression() {};
- void Push(ExpressionPtr value) { m_Values.push_back(value); };
- virtual ~ListExpression() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-protected:
- IPLVector<ExpressionPtr> m_Values;
-};
+#define GENERATE_GETTERS(type, name, def)\
+ const type& Get##name() const { return m_##name; }\
+ type& Get##name##ByRef() { return m_##name; }
-class VariableDefinitionExpression : public IdentifierExpression
-{
-public:
- VariableDefinitionExpression(IPLString& name, ExpressionPtr value) : IdentifierExpression(name), m_Value(value){}
- virtual ~VariableDefinitionExpression() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-protected:
- ExpressionPtr m_Value;
-};
+#define GENERATE_MEMBER_DEFINITIONS(type, name, def)\
+ type m_##name;
-class BlockStatement : public ListExpression
-{
-public:
- BlockStatement() {};
- virtual ~BlockStatement() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
-};
+#define GENERATE_EXPRESSION(ClassName, Base, MEMBERS_ITERATOR) \
+ class ClassName : public Base \
+ { \
+ public: \
+ ClassName(MEMBERS_ITERATOR(EXPAND_ARGUMENT) bool __dummy = 0) \
+ : \
+ MEMBERS_ITERATOR(EXPAND_INITIALIZER_LIST) m_dummy(__dummy) {} \
+ virtual ~ClassName() {} \
+ virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); } \
+ \
+ MEMBERS_ITERATOR(GENERATE_GETTERS) \
+ private: \
+ MEMBERS_ITERATOR(GENERATE_MEMBER_DEFINITIONS) \
+ bool m_dummy; \
+ };
-class LabeledStatement : public Expression
-{
-public:
- LabeledStatement(IPLString& identifier, ExpressionPtr statements);
- virtual ~LabeledStatement() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-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;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- ExpressionPtr m_Condition;
- ExpressionPtr m_IfStatement;
- ExpressionPtr m_ElseStatement;
-};
+#define BINARY_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Left, nullptr)\
+ MACRO(ExpressionPtr, Right, nullptr)\
+ MACRO(TokenType, Operator, TokenType::Invalid)
-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;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- ExpressionPtr m_Condition;
- IPLVector<Case> m_Cases;
- ExpressionPtr m_DefaultCase;
-};
+#define UNARY_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLSharedPtr<Expression>, Expr, nullptr)\
+ MACRO(TokenType, Operator, TokenType::Invalid)\
+ MACRO(bool, Suffix, false)
-class WhileStatement : public Expression
-{
-public:
- WhileStatement(ExpressionPtr cond, ExpressionPtr body, bool doWhile);
- virtual ~WhileStatement() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- ExpressionPtr m_Condition;
- ExpressionPtr m_Body;
- bool m_DoWhile;
-};
+#define LITERAL_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(double, NumValue, 0.)\
+ MACRO(IPLString, StringValue, "")\
+ MACRO(bool, BooleanValue, false)\
+ MACRO(LiteralType, Type, LiteralType::Undefined)
-class ForStatement : public Expression
-{
-public:
- ForStatement(ExpressionPtr initialization, ExpressionPtr cond, ExpressionPtr iteration, ExpressionPtr body);
- virtual ~ForStatement() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- ExpressionPtr m_Initialization;
- ExpressionPtr m_Condition;
- ExpressionPtr m_Iteration;
- ExpressionPtr m_Body;
-};
+#define IDENTIFIER_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLString, Name, "")
-class FunctionDeclaration : public Expression
-{
-public:
- FunctionDeclaration(IPLString& functionName, IPLVector<IPLString>& argumentsIdentifiers, ExpressionPtr body);
- virtual ~FunctionDeclaration() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-private:
- IPLString m_Name;
- IPLVector<IPLString> m_ArgumentsIdentifiers;
- ExpressionPtr m_Body;
-};
+#define VARIABLEDEFINITION_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLString, Name, "")\
+ MACRO(ExpressionPtr, Value, nullptr)
-class TopStatements : public ListExpression
-{
-public:
- TopStatements() {}
- virtual ~TopStatements() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-};
+#define LIST_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLVector<ExpressionPtr>, Values, IPLVector<ExpressionPtr>())
-class EmptyExpression : public Expression
-{
-public:
- EmptyExpression() {}
- virtual ~EmptyExpression() {}
- virtual void Print(std::ostream& os) const override;
- virtual void Accept(ExpressionVisitor& v) override { v.Visit(this); }
-};
+#define BLOCK_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLVector<ExpressionPtr>, Values, IPLVector<ExpressionPtr>())
+
+#define LABELED_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLString, Identifier, "")\
+ MACRO(ExpressionPtr, Statement, nullptr)
+
+#define IF_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Condition, nullptr)\
+ MACRO(ExpressionPtr, IfStatement, nullptr)\
+ MACRO(ExpressionPtr, ElseStatement, nullptr)
+
+#define CASE_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Condition, nullptr)\
+ MACRO(ExpressionPtr, Body, nullptr)
+
+#define SWITCH_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Condition, nullptr)\
+ MACRO(IPLVector<ExpressionPtr>, Cases, IPLVector<ExpressionPtr>())\
+ MACRO(ExpressionPtr, DefaultCase, nullptr)
+
+#define WHILE_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Condition, nullptr)\
+ MACRO(ExpressionPtr, Body, nullptr)\
+ MACRO(bool, DoWhile, false)
+
+#define FOR_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(ExpressionPtr, Initialization, nullptr)\
+ MACRO(ExpressionPtr, Condition, nullptr)\
+ MACRO(ExpressionPtr, Iteration, nullptr)\
+ MACRO(ExpressionPtr, Body, nullptr)
+
+#define FUNCTION_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLString, Name, "")\
+ MACRO(IPLVector<IPLString>, ArgumentsIdentifiers, IPLVector<IPLString>())\
+ MACRO(ExpressionPtr, Body, nullptr)
+
+#define TOP_EXPRESSION_MEMBERS(MACRO)\
+ MACRO(IPLVector<ExpressionPtr>, Values, IPLVector<ExpressionPtr>())
+
+#define EMPTY_EXPRESSION_MEMBERS(MACRO)
+
+#define EXPRESSION_DEFINITION_ITERATOR(MACRO)\
+ MACRO(BinaryExpression, Expression, BINARY_EXPRESSION_MEMBERS)\
+ MACRO(UnaryExpression, Expression, UNARY_EXPRESSION_MEMBERS)\
+ MACRO(IdentifierExpression, Expression, IDENTIFIER_EXPRESSION_MEMBERS)\
+ MACRO(VariableDefinitionExpression, Expression, VARIABLEDEFINITION_EXPRESSION_MEMBERS)\
+ MACRO(ListExpression, Expression, LIST_EXPRESSION_MEMBERS)\
+ MACRO(BlockStatement, Expression, BLOCK_EXPRESSION_MEMBERS)\
+ MACRO(LabeledStatement, Expression, LABELED_EXPRESSION_MEMBERS)\
+ MACRO(IfStatement, Expression, IF_EXPRESSION_MEMBERS)\
+ MACRO(SwitchStatement, Expression, SWITCH_EXPRESSION_MEMBERS)\
+ MACRO(CaseStatement, Expression, CASE_EXPRESSION_MEMBERS)\
+ MACRO(WhileStatement, Expression, WHILE_EXPRESSION_MEMBERS)\
+ MACRO(ForStatement, Expression, FOR_EXPRESSION_MEMBERS)\
+ MACRO(FunctionDeclaration, Expression, FUNCTION_EXPRESSION_MEMBERS)\
+ MACRO(TopStatements, Expression, TOP_EXPRESSION_MEMBERS)\
+ MACRO(EmptyExpression, Expression, EMPTY_EXPRESSION_MEMBERS)
+
+
+EXPRESSION_DEFINITION_ITERATOR(GENERATE_EXPRESSION);
inline ExpressionPtr CreateEmptyExpression() { return IPLMakeSharePtr<EmptyExpression>(); }
diff --git a/JSImpl/src/ExpressionVisitor.h b/JSImpl/src/ExpressionVisitor.h
index 7a893bb..044a38c 100644
--- a/JSImpl/src/ExpressionVisitor.h
+++ b/JSImpl/src/ExpressionVisitor.h
@@ -16,6 +16,7 @@ public:
virtual void Visit(LabeledStatement* e) = 0;
virtual void Visit(IfStatement* e) = 0;
virtual void Visit(SwitchStatement* e) = 0;
+ virtual void Visit(CaseStatement* e) = 0;
virtual void Visit(WhileStatement* e) = 0;
virtual void Visit(ForStatement* e) = 0;
virtual void Visit(FunctionDeclaration* e) = 0;
diff --git a/JSImpl/src/ExpressionsFwd.h b/JSImpl/src/ExpressionsFwd.h
index cbc08e0..4de5bfa 100644
--- a/JSImpl/src/ExpressionsFwd.h
+++ b/JSImpl/src/ExpressionsFwd.h
@@ -1,4 +1,5 @@
#pragma once
+#include "CommonTypes.h"
#include "CommonTypes.h"
@@ -13,6 +14,7 @@ class BlockStatement;
class LabeledStatement;
class IfStatement;
class SwitchStatement;
+class CaseStatement;
class WhileStatement;
class ForStatement;
class FunctionDeclaration;
diff --git a/JSImpl/src/Lexer.h b/JSImpl/src/Lexer.h
index fd3d244..914b6ed 100644
--- a/JSImpl/src/Lexer.h
+++ b/JSImpl/src/Lexer.h
@@ -100,6 +100,7 @@ enum TokenType
Eof,
+ Invalid
};
struct Token
diff --git a/JSImpl/src/Parser.cpp b/JSImpl/src/Parser.cpp
index bbde7f1..28fee72 100644
--- a/JSImpl/src/Parser.cpp
+++ b/JSImpl/src/Parser.cpp
@@ -204,7 +204,7 @@ ExpressionPtr Parser::ArrayLiteral()
auto result = IPLMakeSharePtr<ListExpression>();
while (auto lf = LiteralElement())
{
- result->Push(lf);
+ result->GetValuesByRef().push_back(lf);
if (!Match(TokenType::Comma))
{
break;
@@ -691,7 +691,7 @@ ExpressionPtr Parser::VariableDefinition()
auto ae = CreateEmptyExpression();
if (Match(TokenType::Equal))
{
- auto ae = AssignmentExpression();
+ ae = AssignmentExpression();
}
return IPLMakeSharePtr<VariableDefinitionExpression>(id, ae);
}
@@ -703,10 +703,10 @@ ExpressionPtr Parser::VariableDefinition()
// VariableDeclaration
// | VariableDeclarationList, VariableDeclaration
auto vdList = IPLMakeSharePtr<ListExpression>();
- vdList->Push(VariableDeclaration());
+ vdList->GetValuesByRef().push_back(VariableDeclaration());
while (Match(TokenType::Comma))
{
- vdList->Push(VariableDeclaration());
+ vdList->GetValuesByRef().push_back(VariableDeclaration());
}
return vdList;
};
@@ -731,7 +731,7 @@ ExpressionPtr Parser::Block()
auto StatementsList = IPLMakeSharePtr<BlockStatement>();
while (auto s = Statement())
{
- StatementsList->Push(s);
+ StatementsList->GetValuesByRef().push_back(s);
}
return StatementsList;
};
@@ -784,7 +784,7 @@ ExpressionPtr Parser::SwitchStatement()
if (Match(TokenType::Switch))
{
auto cond = ParenthesizedExpression();
- IPLVector<SwitchStatement::Case> cases;
+ IPLVector<ExpressionPtr> cases;
ExpressionPtr defaultCase = nullptr;
if (Match(TokenType::LeftBrace))
{
@@ -796,7 +796,8 @@ ExpressionPtr Parser::SwitchStatement()
auto expr = Expression();
if (Match(TokenType::Colon))
{
- cases.push_back({ expr, Statement() });
+ auto statement = Statement();
+ cases.push_back(IPLMakeSharePtr<CaseStatement>(expr, statement));
}
}
else if (Match(TokenType::Default))
@@ -996,7 +997,7 @@ ExpressionPtr Parser::TopStatements()
auto statements = IPLMakeSharePtr<::TopStatements>();
while (auto ts = TopStatement())
{
- statements->Push(ts);
+ statements->GetValuesByRef().push_back(ts);
}
return statements;
}
diff --git a/JSImpl/src/main.cpp b/JSImpl/src/main.cpp
index 221ec52..4263bfa 100644
--- a/JSImpl/src/main.cpp
+++ b/JSImpl/src/main.cpp
@@ -5,18 +5,19 @@
#define EXECUTE_TEST(test) std::cout << #test << " "; test();
#define CHECK(cond) if (cond) {LOG("PASS");} else {LOG(#cond " FAIL");}
+#define CHECK(cond) cond ? LOG("PASS") : LOG("FAIL")
+
// Lexer Tests
void TestLess()
{
auto tokens = Tokenize("<");
CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Less);
-
}
void TestNumber()
{
auto tokens = Tokenize("213434.24");
- CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 213434.24)
+ CHECK(tokens.size() == 2 && tokens[0].Type == TokenType::Number && tokens[0].Number == 213434.24);
}
void TestNumberStartWithNine()
@@ -73,7 +74,6 @@ void TestParseUnaryExpr()
{
// TODO make actual test :D
auto expr = Parse(Tokenize("function pesho() { var a = 0; return a; }"));
- expr->Print(std::cout);
}
int main()