diff options
| Commit | 2621d30da58795a19fa2c90978f766e173a8ca2f (patch) | |
|---|---|---|
| Author | 2018-10-14 15:11:59 +0300 | |
| Committer | 2018-10-14 15:11:59 +0300 | |
| Files | b85eefde3ea7b5a39a355e7ff13e38debeadb31d /JSImpl/src | |
| IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.tar IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.tar.gz IPL-2621d30da58795a19fa2c90978f766e173a8ca2f.zip | ||
| Parent | ab6cd5aaa4e1ceb12ade89a4a0c5376092fa8dfb (diff) | |
| Parent | 47a7a68e2b7ce0b0c1e2bd1097927a91623fbcc5 (diff) | |
Merge branch 'expressions-rework'
9 files changed, 381 insertions, 509 deletions
| -rw-r--r-- | JSImpl/src/ASTPrinter.cpp | 261 | ||||
| -rw-r--r-- | JSImpl/src/ASTPrinter.h | 35 | ||||
| -rw-r--r-- | JSImpl/src/Expression.cpp | 277 | ||||
| -rw-r--r-- | JSImpl/src/Expression.h | 290 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionVisitor.h | 1 | ||||
| -rw-r--r-- | JSImpl/src/ExpressionsFwd.h | 2 | ||||
| -rw-r--r-- | JSImpl/src/Lexer.h | 1 | ||||
| -rw-r--r-- | JSImpl/src/Parser.cpp | 17 | ||||
| -rw-r--r-- | JSImpl/src/main.cpp | 6 |
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() |
