From 4233fbfb9229c2c1d334075b7eb32410450f7a3d Mon Sep 17 00:00:00 2001 From: martin dobrev Date: Fri, 5 Oct 2018 09:35:33 +0300 Subject: Now all expressions will be auto generated. --- JSImpl/src/ASTPrinter.cpp | 113 +++++++++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 31 deletions(-) (limited to 'JSImpl/src/ASTPrinter.cpp') diff --git a/JSImpl/src/ASTPrinter.cpp b/JSImpl/src/ASTPrinter.cpp index dfb3447..5717264 100644 --- a/JSImpl/src/ASTPrinter.cpp +++ b/JSImpl/src/ASTPrinter.cpp @@ -1,34 +1,85 @@ #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) +{ + os << name; + expr->Accept(printer); +} + +void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list) +{ + os << name << "[ \n"; + for (auto& expr : list) + { + expr->Accept(printer); + os << ","; + } + os << name << "] \n"; +} + +void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list) +{ + os << name << "[ \n"; + for (auto& name : list) + { + os << name << ","; + } + os << name << "] \n"; +} + + +template +void Print(std::ostream& os, ASTPrinter &printer, const char* name, T member) +{ + os << name << " " << member << "\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"; +} + +void ASTPrinter::Visit(LiteralExpression* e) +{ + os << "{\n" << "LiteralExpression" << '\n'; + Print(os, *this, "BooleanValue", e->GetBooleanValue()); + Print(os, *this, "LiteralType", AsString(e->GetLiteralType())); + Print(os, *this, "NumValue", e->GetNumValue()); + Print(os, *this, "StringValue", e->GetStringValue()); + os << "}\n"; +} + + + +#define VISIT_MEMBER(type, name, def) Print(os, *this, #name, e->Get##name()); + +#define GENERATE_AST_PRINTER_FUNCTION(ClassName, Base, MEMBERS_ITERATOR)\ + void ASTPrinter::Visit(ClassName* e) \ + { \ + os << "{\n" << #ClassName << '\n'; \ + MEMBERS_ITERATOR(VISIT_MEMBER); \ + os << "}\n"; \ + } + + +EXPRESSION_DEFINITION_ITERATOR(GENERATE_AST_PRINTER_FUNCTION); \ No newline at end of file -- cgit v1.3.1-23-gd82d From f28c02cb669a7f043ca1d9facc0f8bd29e6382cd Mon Sep 17 00:00:00 2001 From: martin dobrev Date: Sun, 14 Oct 2018 15:10:10 +0300 Subject: Now AstPrinter output valid jsons. --- JSImpl/src/ASTPrinter.cpp | 204 +++++++++++++++++++++++++++++----- JSImpl/src/Expression.cpp | 274 ---------------------------------------------- 2 files changed, 176 insertions(+), 302 deletions(-) (limited to 'JSImpl/src/ASTPrinter.cpp') diff --git a/JSImpl/src/ASTPrinter.cpp b/JSImpl/src/ASTPrinter.cpp index 5717264..d8f5ff8 100644 --- a/JSImpl/src/ASTPrinter.cpp +++ b/JSImpl/src/ASTPrinter.cpp @@ -5,38 +5,84 @@ ASTPrinter::ASTPrinter(std::ostream& os) : os(os) {} -void Print(std::ostream& os, ASTPrinter &printer, const char* name, const ExpressionPtr& expr) +void Print(std::ostream& os, ASTPrinter &printer, const char* name, const ExpressionPtr& expr, bool isLast) { - os << name; + os << "\"" << name << "\" : "; expr->Accept(printer); + if (!isLast) + { + os << ","; + } } -void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list) +void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list, bool isLast) { - os << name << "[ \n"; - for (auto& expr : list) + os << "\"" << name << "\" : [ \n"; + for (auto i = 0; i < list.size(); ++i) + { + list[i]->Accept(printer); + if (i + 1 != list.size()) + { + os << ","; + } + } + os << "]"; + if (!isLast) { - expr->Accept(printer); os << ","; } - os << name << "] \n"; + os << "\n"; } -void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list) +void Print(std::ostream& os, ASTPrinter &printer, const char* name, const IPLVector& list, bool isLast) { - os << name << "[ \n"; - for (auto& name : list) + os << "\"" << name << "\" : [ \n"; + for (auto i = 0; i < list.size(); ++i) { - os << name << ","; + if (i + 1 != list.size()) + { + os << list[i] << ","; + } } - os << name << "] \n"; + os << "]"; + if (!isLast) + { + os << ","; + } + os << "\n"; } - template -void Print(std::ostream& os, ASTPrinter &printer, const char* name, T member) +void Print(std::ostream& os, ASTPrinter &printer, const char* name, T member, bool isLast) { - os << name << " " << member << "\n"; + os << "\"" << name << "\" :" << member; + if (!isLast) + { + os << ","; + } + os << "\n"; +} + +template<> +void Print(std::ostream& os, ASTPrinter &printer, const char* name, IPLString member, bool isLast) +{ + os << "\"" << name << "\" : \"" << member << "\""; + if (!isLast) + { + os << ","; + } + os << "\n"; +} + +template<> +void Print(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) @@ -59,26 +105,128 @@ IPLString AsString(LiteralType type) 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" << "LiteralExpression" << '\n'; - Print(os, *this, "BooleanValue", e->GetBooleanValue()); - Print(os, *this, "LiteralType", AsString(e->GetLiteralType())); - Print(os, *this, "NumValue", e->GetNumValue()); - Print(os, *this, "StringValue", e->GetStringValue()); + 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 VISIT_MEMBER(type, name, def) Print(os, *this, #name, e->Get##name()); +#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) \ - { \ - os << "{\n" << #ClassName << '\n'; \ - MEMBERS_ITERATOR(VISIT_MEMBER); \ - os << "}\n"; \ + 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"; \ } diff --git a/JSImpl/src/Expression.cpp b/JSImpl/src/Expression.cpp index b043844..b8044e1 100644 --- a/JSImpl/src/Expression.cpp +++ b/JSImpl/src/Expression.cpp @@ -1,89 +1,6 @@ #include "Expression.h" #include -//void PrintExpressionMember(ExpressionPtr expr, const char* name, std::ostream& os) -//{ -// os << name << ": {" << std::endl; -// expr->Print(os); -// os << "}"; -//} -// -//void PrintExpressionMember(IPLVector exprs, const char* name, std::ostream& os) -//{ -// os << name << ": {" << std::endl; -// for (auto& it : exprs) -// { -// it->Print(os); -// os << ",\n"; -// } -// os << "}"; -//} -// -//BinaryExpression::BinaryExpression(IPLSharedPtr exprLeft, IPLSharedPtr exprRight, TokenType op) -//: m_Left(exprLeft) -//, m_Right(exprRight) -//, m_Operator(op) -//{} -// -//IPLString BinaryExpression::GetOperatorTypeAsString() const -//{ -// // TODO: Implement -// 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 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) @@ -114,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& 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 -//{ -// 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& 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 }"; -//} -// \ No newline at end of file -- cgit v1.3.1-23-gd82d