From fb98ac0c3231f2685211b3120fd3dc315c056d37 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Tue, 20 Oct 2009 10:22:24 +0000 Subject: [PATCH] Made drastic changes to the serializer in order to support correctly serializing jQuery. --- Console.cpp | 4 +- Cycript.l | 2 + Cycript.y | 20 ++-- Library.mm | 2 +- Output.cpp | 308 ++++++++++++++++++++++++++++++++-------------------- Parser.hpp | 170 +++++++++++++++++++---------- 6 files changed, 319 insertions(+), 187 deletions(-) diff --git a/Console.cpp b/Console.cpp index 77ee9f9..e09ea01 100644 --- a/Console.cpp +++ b/Console.cpp @@ -280,7 +280,7 @@ static void Console(int socket) { else { std::ostringstream str; CYOutput out(str); - driver.program_->Show(out); + driver.program_->Multiple(out); code = str.str(); } } @@ -440,7 +440,7 @@ int main(int argc, char *argv[]) { else { std::ostringstream str; CYOutput out(str); - driver.program_->Show(out); + driver.program_->Multiple(out); std::string code(str.str()); if (compile) std::cout << code; diff --git a/Cycript.l b/Cycript.l index d62a14b..516c813 100644 --- a/Cycript.l +++ b/Cycript.l @@ -114,6 +114,8 @@ RegularExpressionStart_ {RegularExpressionBody}{RegularExpressionEnd_} yylloc->end.lines(lines); yylloc->end.columns(left); yylloc->step(); + + N } else L } diff --git a/Cycript.y b/Cycript.y index 42402f3..70022e7 100644 --- a/Cycript.y +++ b/Cycript.y @@ -59,7 +59,6 @@ typedef struct { CYBoolean *boolean_; CYClause *clause_; CYCatch *catch_; - CYClass *class_; CYClassName *className_; CYComprehension *comprehension_; CYCompound *compound_; @@ -296,11 +295,12 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner); %type CaseClausesOpt %type CatchOpt %type CategoryStatement -%type ClassDefinition +%type ClassExpression %type ClassMessageDeclaration %type ClassMessageDeclarationListOpt %type ClassName %type ClassNameOpt +%type ClassStatement %type ClassSuperOpt %type ClassFieldList %type ComprehensionList @@ -1268,11 +1268,11 @@ FinallyOpt /* 13 Function Definition {{{ */ FunctionDeclaration - : "function" Identifier "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunction($2, $4, $7); } + : "function" Identifier "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionStatement($2, $4, $7); } ; FunctionExpression - : "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYLambda($2, $4, $7); } + : "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($2, $4, $7); } ; FormalParameterList_ @@ -1362,8 +1362,12 @@ ClassNameOpt | { $$ = NULL; } ; -ClassDefinition - : "@class" ClassNameOpt ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClass($2, $3, $4, $5); } +ClassExpression + : "@class" ClassNameOpt ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassExpression($2, $3, $4, $5); } + ; + +ClassStatement + : "@class" ClassName ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassStatement($2, $3, $4, $5); } ; CategoryStatement @@ -1371,11 +1375,11 @@ CategoryStatement ; PrimaryExpression - : ClassDefinition { $$ = $1; } + : ClassExpression { $$ = $1; } ; Statement_ - : ClassDefinition { $$ = $1; } + : ClassStatement { $$ = $1; } | CategoryStatement { $$ = $1; } ; /* }}} */ diff --git a/Library.mm b/Library.mm index e4bf70b..faed79e 100644 --- a/Library.mm +++ b/Library.mm @@ -3469,7 +3469,7 @@ struct CYClient : } else { std::ostringstream str; CYOutput out(str); - driver.program_->Show(out); + driver.program_->Multiple(out); std::string code(str.str()); CYExecute_ execute = {pool, code.c_str()}; [client performSelectorOnMainThread:@selector(execute:) withObject:[NSValue valueWithPointer:&execute] waitUntilDone:YES]; diff --git a/Output.cpp b/Output.cpp index 09ee163..be38f05 100644 --- a/Output.cpp +++ b/Output.cpp @@ -31,7 +31,7 @@ _finline CYFlags CYCenter(CYFlags flags) { } _finline CYFlags CYRight(CYFlags flags) { - return flags & (CYNoIn | CYNoTrailer); + return flags & (CYNoIn | CYNoTrailer | CYNoTerminator); } bool CYFalse::Value() const { @@ -92,14 +92,13 @@ void CYArrayComprehension::Output(CYOutput &out, CYFlags flags) const { } void CYAssignment::Output(CYOutput &out, CYFlags flags) const { - lhs_->Output(out, Precedence() - 1, CYLeft(flags)); + lhs_->Output(out, Precedence() - 1, CYLeft(flags) | CYNoRightHand); out << Operator(); rhs_->Output(out, Precedence(), CYRight(flags)); } -void CYBlock::Output(CYOutput &out) const { - for (CYStatement *statement(statements_); statement != NULL; statement = statement->next_) - statement->Output(out); +void CYBlock::Output(CYOutput &out, CYFlags flags) const { + statements_->Single(out, flags); } void CYBoolean::Output(CYOutput &out, CYFlags flags) const { @@ -110,29 +109,39 @@ void CYBoolean::Output(CYOutput &out, CYFlags flags) const { out << ' '; } -void CYBreak::Output(CYOutput &out) const { +void CYBreak::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "break"; if (label_ != NULL) out << ' ' << *label_; - out << ';'; + if ((flags & CYNoTerminator) == 0) + out << ';'; + else if ((flags & CYNoTrailer) != 0) + out << ' '; } void CYCall::Output(CYOutput &out, CYFlags flags) const { - function_->Output(out, Precedence(), CYLeft(flags)); + bool protect((flags & CYNoCall) != 0); + if (protect) + out << '('; + function_->Output(out, Precedence(), protect ? CYNoFlags : flags); out << '('; if (arguments_ != NULL) arguments_->Output(out); out << ')'; + if (protect) + out << ')'; } void CYCatch::Output(CYOutput &out) const { out << "catch(" << *name_ << "){"; if (code_ != NULL) - code_->Show(out); + code_->Multiple(out); out << "}"; } -void CYCategory::Output(CYOutput &out) const { +void CYCategory::Output(CYOutput &out, CYFlags flags) const { out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; out << "$cyp=object_getClass($cys);"; out << "$cyc=$cys;"; @@ -140,12 +149,9 @@ void CYCategory::Output(CYOutput &out) const { messages_->Output(out, true); out << "})("; name_->ClassName(out, true); - out << ");"; -} - -void CYClass::Output(CYOutput &out) const { - Output(out, CYNoBF); - out << ";"; + out << ')'; + if ((flags & CYNoTerminator) == 0) + out << ';'; } void CYClass::Output(CYOutput &out, CYFlags flags) const { @@ -173,6 +179,14 @@ void CYClass::Output(CYOutput &out, CYFlags flags) const { out << "))"; } +void CYClassExpression::Output(CYOutput &out, CYFlags flags) const { + CYClass::Output(out, flags); +} + +void CYClassStatement::Output(CYOutput &out, CYFlags flags) const { + CYClass::Output(out, flags); +} + void CYCompound::Output(CYOutput &out, CYFlags flags) const { if (CYExpression *expression = expressions_) if (CYExpression *next = expression->next_) { @@ -204,11 +218,16 @@ void CYCondition::Output(CYOutput &out, CYFlags flags) const { false_->Output(out, CYPA, CYRight(flags)); } -void CYContinue::Output(CYOutput &out) const { +void CYContinue::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "continue"; if (label_ != NULL) out << ' ' << *label_; - out << ';'; + if ((flags & CYNoTerminator) == 0) + out << ';'; + else if ((flags & CYNoTrailer) != 0) + out << ' '; } void CYClause::Output(CYOutput &out) const { @@ -219,7 +238,7 @@ void CYClause::Output(CYOutput &out) const { out << "default"; out << ':'; if (code_ != NULL) - code_->Output(out, false); + code_->Multiple(out, next_ == NULL ? CYNoFlags : CYNoTrailer); if (next_ != NULL) out << *next_; } @@ -231,8 +250,8 @@ const char *CYDeclaration::ForEachIn() const { void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const { if ((flags & CYNoLeader) != 0) out << ' '; - out << "var "; - Output(out, CYRight(flags)); + out << "var"; + Output(out, CYRight(flags) | CYNoLeader); } void CYDeclaration::ForEachIn(CYOutput &out) const { @@ -240,6 +259,8 @@ void CYDeclaration::ForEachIn(CYOutput &out) const { } void CYDeclaration::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << *identifier_; if (initialiser_ != NULL) { out << '='; @@ -249,16 +270,18 @@ void CYDeclaration::Output(CYOutput &out, CYFlags flags) const { } void CYDeclarations::For(CYOutput &out) const { - out << "var "; - Output(out, CYNoIn); + out << "var"; + Output(out, CYNoIn | CYNoLeader); } void CYDeclarations::Output(CYOutput &out, CYFlags flags) const { const CYDeclarations *declaration(this); + bool first(true); output: CYDeclarations *next(declaration->next_); - CYFlags right(next == NULL ? CYRight(flags) : CYCenter(flags)); - declaration->declaration_->Output(out, right); + CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags)); + first = false; + declaration->declaration_->Output(out, jacks); if (next != NULL) { out << ','; @@ -278,10 +301,11 @@ void CYDirectMember::Output(CYOutput &out, CYFlags flags) const { } } -void CYDoWhile::Output(CYOutput &out) const { - // XXX: extra space character! - out << "do "; - code_->Output(out, false); +void CYDoWhile::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; + out << "do"; + code_->Single(out, CYNoLeader | CYNoTrailer); out << "while("; test_->Output(out, CYNoFlags); out << ')'; @@ -296,20 +320,15 @@ void CYElement::Output(CYOutput &out) const { next_->Output(out); } -void CYEmpty::Output(CYOutput &out) const { +void CYEmpty::Output(CYOutput &out, CYFlags flags) const { out << ';'; } -void CYEmpty::Output(CYOutput &out, bool block) const { - if (next_ != NULL) - CYStatement::Output(out, block); - else - out << "{}"; -} - -void CYExpress::Output(CYOutput &out) const { - expression_->Output(out, CYNoBF); - out << ';'; +void CYExpress::Output(CYOutput &out, CYFlags flags) const { + bool terminator((flags & CYNoTerminator) == 0); + expression_->Output(out, (terminator ? CYLeft(flags) : flags) | CYNoBF); + if (terminator) + out << ';'; } void CYExpression::ClassName(CYOutput &out, bool object) const { @@ -325,17 +344,15 @@ void CYExpression::For(CYOutput &out) const { } void CYExpression::ForEachIn(CYOutput &out) const { - // XXX: this should handle LeftHandSideExpression - Output(out, CYPA, CYNoFlags); + Output(out, CYPA, CYNoRightHand); } void CYExpression::ForIn(CYOutput &out, CYFlags flags) const { - // XXX: this should handle LeftHandSideExpression - Output(out, flags); + Output(out, flags | CYNoRightHand); } void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const { - if (precedence < Precedence()) { + if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand()) { out << '('; Output(out, CYNoFlags); out << ')'; @@ -350,11 +367,13 @@ void CYField::Output(CYOutput &out) const { void CYFinally::Output(CYOutput &out) const { out << "finally{"; if (code_ != NULL) - code_->Show(out); + code_->Multiple(out); out << "}"; } -void CYFor::Output(CYOutput &out) const { +void CYFor::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "for("; if (initialiser_ != NULL) initialiser_->For(out); @@ -365,10 +384,13 @@ void CYFor::Output(CYOutput &out) const { if (increment_ != NULL) increment_->Output(out, CYNoFlags); out << ')'; - code_->Output(out, false); + code_->Single(out, CYNoFlags); } -void CYForEachIn::Output(CYOutput &out) const { +void CYForEachIn::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; + out << "with({$cys:0,$cyt:0}){"; out << "$cys="; @@ -380,7 +402,7 @@ void CYForEachIn::Output(CYOutput &out) const { initialiser_->ForEachIn(out); out << "=$cys[$cyt];"; - code_->Show(out); + code_->Multiple(out); out << '}'; @@ -401,13 +423,15 @@ void CYForEachInComprehension::End_(CYOutput &out) const { out << "}}());"; } -void CYForIn::Output(CYOutput &out) const { +void CYForIn::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "for("; initialiser_->ForIn(out, CYNoIn | CYNoTrailer); out << "in"; set_->Output(out, CYNoLeader); out << ')'; - code_->Output(out, false); + code_->Single(out, CYRight(flags)); } void CYForInComprehension::Begin_(CYOutput &out) const { @@ -416,8 +440,32 @@ void CYForInComprehension::Begin_(CYOutput &out) const { out << ')'; } -void CYFunction::Output(CYOutput &out) const { - CYLambda::Output(out, CYNoFlags); +void CYFunction::Output(CYOutput &out, CYFlags flags) const { + bool protect((flags & CYNoFunction) != 0); + if (protect) + out << '('; + else if ((flags & CYNoLeader) != 0) + out << ' '; + out << "function"; + if (name_ != NULL) + out << ' ' << *name_; + out << '('; + if (parameters_ != NULL) + out << *parameters_; + out << "){"; + if (body_ != NULL) + body_->Multiple(out); + out << '}'; + if (protect) + out << ')'; +} + +void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const { + CYFunction::Output(out, flags); +} + +void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const { + CYFunction::Output(out, flags); } void CYFunctionParameter::Output(CYOutput &out) const { @@ -428,15 +476,28 @@ void CYFunctionParameter::Output(CYOutput &out) const { } } -void CYIf::Output(CYOutput &out) const { +void CYIf::Output(CYOutput &out, CYFlags flags) const { + bool protect(false); + if (false_ == NULL && (flags & CYNoDangle) != 0) { + protect = true; + out << '{'; + } else if ((flags & CYNoLeader) != 0) + out << ' '; out << "if("; test_->Output(out, CYNoFlags); out << ')'; - true_->Output(out, true); + CYFlags right(protect ? CYNoFlags : CYRight(flags)); + CYFlags jacks(CYNoDangle); + jacks |= false_ == NULL ? right : CYNoTrailer; + true_->Single(out, jacks); if (false_ != NULL) { - out << "else "; - false_->Output(out, false); + out << "else"; + if (protect) + right |= CYNoTerminator; + false_->Single(out, CYNoLeader | right); } + if (protect) + out << '}'; } void CYIfComprehension::Begin_(CYOutput &out) const { @@ -448,6 +509,8 @@ void CYIfComprehension::Begin_(CYOutput &out) const { void CYIndirect::Output(CYOutput &out, CYFlags flags) const { rhs_->Output(out, 1, CYLeft(flags)); out << ".$cyi"; + if ((flags & CYNoTrailer) != 0) + out << ' '; } void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const { @@ -483,32 +546,14 @@ void CYInfix::Output(CYOutput &out, CYFlags flags) const { out << ')'; } -void CYLambda::Output(CYOutput &out, CYFlags flags) const { - bool protect((flags & CYNoFunction) != 0); - if (protect) - out << '('; - else if ((flags & CYNoLeader) != 0) +void CYLet::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) out << ' '; - out << "function"; - if (name_ != NULL) - out << ' ' << *name_; - out << '('; - if (parameters_ != NULL) - out << *parameters_; - out << "){"; - if (body_ != NULL) - body_->Show(out); - out << '}'; - if (protect) - out << ')'; -} - -void CYLet::Output(CYOutput &out) const { out << "let("; declarations_->Output(out, CYNoFlags); out << "){"; if (statements_ != NULL) - statements_->Show(out); + statements_->Multiple(out); out << "}"; } @@ -531,7 +576,7 @@ void CYMessage::Output(CYOutput &out, bool replace) const { out << ',' << *parameter->name_; out << "){return function(){"; if (body_ != NULL) - body_->Show(out); + body_->Multiple(out); out << "}.call(self);},$cyt),$cyt);"; } @@ -539,11 +584,12 @@ void CYNew::Output(CYOutput &out, CYFlags flags) const { if ((flags & CYNoLeader) != 0) out << ' '; out << "new"; - constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader); - out << '('; - if (arguments_ != NULL) + constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader | CYNoCall); + if (arguments_ != NULL) { + out << '('; arguments_->Output(out); - out << ')'; + out << ')'; + } } void CYNull::Output(CYOutput &out, CYFlags flags) const { @@ -565,7 +611,7 @@ void CYNumber::Output(CYOutput &out, CYFlags flags) const { } void CYNumber::PropertyName(CYOutput &out) const { - Output(out); + Output(out, CYNoFlags); } void CYObject::Output(CYOutput &out, CYFlags flags) const { @@ -613,11 +659,15 @@ void CYRegEx::Output(CYOutput &out, CYFlags flags) const { out << ' '; } -void CYReturn::Output(CYOutput &out) const { +void CYReturn::Output(CYOutput &out, CYFlags flags) const { + bool terminator((flags & CYNoTerminator) == 0); + if ((flags & CYNoLeader) != 0) + out << ' '; out << "return"; if (value_ != NULL) - value_->Output(out, CYNoLeader); - out << ';'; + value_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader); + if (terminator) + out << ';'; } void CYSelector::Output(CYOutput &out, CYFlags flags) const { @@ -660,27 +710,35 @@ void CYSend::Output(CYOutput &out, CYFlags flags) const { out << ')'; } -void CYStatement::Show(CYOutput &out) const { - for (const CYStatement *next(this); next != NULL; next = next->next_) - next->Output_(out); +void CYStatement::Multiple(CYOutput &out, CYFlags flags) const { + bool first(true); + for (const CYStatement *next(this); next != NULL; next = next->next_) { + bool last(next->next_ == NULL); + CYFlags jacks(first ? last ? flags : CYLeft(flags) : last ? CYCenter(flags) : CYRight(flags)); + if (last) + jacks |= CYNoTerminator; + first = false; + next->Output(out, jacks); + } } -void CYStatement::Output(CYOutput &out, bool block) const { - if (!block && !IsBlock()) - Output(out); - else { +void CYStatement::Single(CYOutput &out, CYFlags flags) const { + if (next_ != NULL) { out << '{'; - Show(out); + Multiple(out); out << '}'; + } else { + bool protect(false); + if (labels_ != NULL && (flags & CYNoLeader) != 0) + protect = true; + if (protect) + out << ' '; + for (CYLabel *label(labels_); label != NULL; label = label->next_) + out << *label->name_ << ':'; + Output(out, protect ? CYRight(flags) : flags); } } -void CYStatement::Output_(CYOutput &out) const { - for (CYLabel *label(labels_); label != NULL; label = label->next_) - out << *label->name_ << ':'; - Output(out); -} - void CYString::Output(CYOutput &out, CYFlags flags) const { unsigned quot(0), apos(0); for (const char *value(value_), *end(value_ + size_); value != end; ++value) @@ -727,10 +785,12 @@ void CYString::PropertyName(CYOutput &out) const { if (const char *word = Word()) out << word; else - Output(out); + Output(out, CYNoFlags); } -void CYSwitch::Output(CYOutput &out) const { +void CYSwitch::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "switch("; value_->Output(out, CYNoFlags); out << "){"; @@ -747,17 +807,23 @@ void CYThis::Output(CYOutput &out, CYFlags flags) const { out << ' '; } -void CYThrow::Output(CYOutput &out) const { +void CYThrow::Output(CYOutput &out, CYFlags flags) const { + bool terminator((flags & CYNoTerminator) == 0); + if ((flags & CYNoLeader) != 0) + out << ' '; out << "throw"; if (value_ != NULL) - value_->Output(out, CYNoLeader); - out << ';'; + value_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader); + if (terminator) + out << ';'; } -void CYTry::Output(CYOutput &out) const { +void CYTry::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "try{"; if (code_ != NULL) - code_->Show(out); + code_->Multiple(out); out << "}"; if (catch_ != NULL) catch_->Output(out); @@ -765,10 +831,14 @@ void CYTry::Output(CYOutput &out) const { finally_->Output(out); } -void CYVar::Output(CYOutput &out) const { - out << "var "; - declarations_->Output(out, CYNoFlags); - out << ';'; +void CYVar::Output(CYOutput &out, CYFlags flags) const { + bool terminator((flags & CYNoTerminator) == 0); + if ((flags & CYNoLeader) != 0) + out << ' '; + out << "var"; + declarations_->Output(out, (terminator ? CYCenter(flags) : flags) | CYNoLeader); + if (terminator) + out << ';'; } void CYVariable::Output(CYOutput &out, CYFlags flags) const { @@ -779,18 +849,22 @@ void CYVariable::Output(CYOutput &out, CYFlags flags) const { out << ' '; } -void CYWhile::Output(CYOutput &out) const { +void CYWhile::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "while("; test_->Output(out, CYNoFlags); out << ')'; - code_->Output(out, false); + code_->Single(out, CYRight(flags)); } -void CYWith::Output(CYOutput &out) const { +void CYWith::Output(CYOutput &out, CYFlags flags) const { + if ((flags & CYNoLeader) != 0) + out << ' '; out << "with("; scope_->Output(out, CYNoFlags); out << ')'; - code_->Output(out, false); + code_->Single(out, CYRight(flags)); } void CYWord::ClassName(CYOutput &out, bool object) const { diff --git a/Parser.hpp b/Parser.hpp index 6fde458..bf73389 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -149,6 +149,27 @@ struct CYLabel : } }; +enum CYNeeded { + CYNever = -1, + CYSometimes = 0, + CYAlways = 1, +}; + +enum CYFlags { + CYNoFlags = 0, + CYNoBrace = (1 << 0), + CYNoFunction = (1 << 1), + CYNoLeader = (1 << 2), + CYNoTrailer = (1 << 3), + CYNoIn = (1 << 4), + CYNoHyphen = (1 << 5), + CYNoCall = (1 << 6), + CYNoRightHand = (1 << 7), + CYNoDangle = (1 << 8), + CYNoTerminator = (1 << 9), + CYNoBF = (CYNoBrace | CYNoFunction), +}; + struct CYStatement : CYNext { @@ -167,10 +188,11 @@ struct CYStatement : return next_ != NULL; } - virtual void Show(CYOutput &out) const; - virtual void Output(CYOutput &out) const = 0; - virtual void Output(CYOutput &out, bool block) const; - virtual void Output_(CYOutput &out) const; + virtual void Single(CYOutput &out, CYFlags flags) const; + virtual void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const; + + private: + virtual void Output(CYOutput &out, CYFlags flags) const = 0; }; struct CYBlock : @@ -187,7 +209,7 @@ struct CYBlock : return true; } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; enum CYState { @@ -240,17 +262,6 @@ class CYDriver { void Warning(const cy::location &location, const char *message); }; -enum CYFlags { - CYNoFlags = 0, - CYNoBrace = (1 << 0), - CYNoFunction = (1 << 1), - CYNoLeader = (1 << 2), - CYNoTrailer = (1 << 3), - CYNoIn = (1 << 4), - CYNoHyphen = (1 << 5), - CYNoBF = (CYNoBrace | CYNoFunction), -}; - struct CYForInitialiser { virtual void For(CYOutput &out) const = 0; }; @@ -269,6 +280,10 @@ struct CYExpression : { virtual unsigned Precedence() const = 0; + virtual bool RightHand() const { + return true; + } + virtual void For(CYOutput &out) const; virtual void ForIn(CYOutput &out, CYFlags flags) const; @@ -295,6 +310,11 @@ struct CYExpression : return value; \ } +#define CYRightHand(value) \ + virtual bool RightHand() const { \ + return value; \ + } + struct CYCompound : CYExpression { @@ -407,12 +427,14 @@ struct CYLiteral : CYExpression { CYPrecedence(0) + CYRightHand(false) }; struct CYMagic : CYExpression { CYPrecedence(0) + CYRightHand(false) }; struct CYSelectorPart : @@ -502,10 +524,6 @@ struct CYString : return Value(); } - virtual void Output(CYOutput &out) const { - return Output(out, CYNoFlags); - } - virtual void Output(CYOutput &out, CYFlags flags) const; virtual void PropertyName(CYOutput &out) const; }; @@ -525,10 +543,6 @@ struct CYNumber : return value_; } - virtual void Output(CYOutput &out) const { - return Output(out, CYNoFlags); - } - virtual void Output(CYOutput &out, CYFlags flags) const; virtual void PropertyName(CYOutput &out) const; }; @@ -616,6 +630,7 @@ struct CYVariable : } CYPrecedence(0) + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -808,7 +823,7 @@ struct CYVar : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYLet : @@ -823,7 +838,7 @@ struct CYLet : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYField : @@ -866,10 +881,7 @@ struct CYMessage : virtual void Output(CYOutput &out, bool replace) const; }; -struct CYClass : - CYExpression, - CYStatement -{ +struct CYClass { CYClassName *name_; CYExpression *super_; CYField *fields_; @@ -883,9 +895,32 @@ struct CYClass : { } + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYClassExpression : + CYClass, + CYExpression +{ + CYClassExpression(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) : + CYClass(name, super, fields, messages) + { + } + CYPrecedence(0) - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYClassStatement : + CYClass, + CYStatement +{ + CYClassStatement(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) : + CYClass(name, super, fields, messages) + { + } + virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -901,7 +936,7 @@ struct CYCategory : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYFunctionParameter : @@ -935,7 +970,7 @@ struct CYFor : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYForIn : @@ -952,7 +987,7 @@ struct CYForIn : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYForEachIn : @@ -969,7 +1004,7 @@ struct CYForEachIn : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYProperty : @@ -1059,6 +1094,7 @@ struct CYDirectMember : } CYPrecedence(1) + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1072,6 +1108,7 @@ struct CYIndirectMember : } CYPrecedence(1) + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1088,7 +1125,11 @@ struct CYNew : { } - CYPrecedence(1) + virtual unsigned Precedence() const { + return arguments_ == NULL ? 2 : 1; + } + + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1105,7 +1146,8 @@ struct CYCall : { } - CYPrecedence(2) + CYPrecedence(1) + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1124,7 +1166,7 @@ struct CYIf : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYDoWhile : @@ -1139,7 +1181,7 @@ struct CYDoWhile : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYWhile : @@ -1154,38 +1196,49 @@ struct CYWhile : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYLambda : - CYExpression -{ +struct CYFunction { CYIdentifier *name_; CYFunctionParameter *parameters_; CYStatement *body_; - CYLambda(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) : + CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) : name_(name), parameters_(parameters), body_(body) { } + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYFunctionExpression : + CYFunction, + CYExpression +{ + CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) : + CYFunction(name, parameters, body) + { + } + CYPrecedence(0) + CYRightHand(false) virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYFunction : - CYLambda, +struct CYFunctionStatement : + CYFunction, CYStatement { - CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) : - CYLambda(name, parameters, body) + CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *body) : + CYFunction(name, parameters, body) { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYExpress : @@ -1198,7 +1251,7 @@ struct CYExpress : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYContinue : @@ -1211,7 +1264,7 @@ struct CYContinue : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYBreak : @@ -1224,7 +1277,7 @@ struct CYBreak : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYReturn : @@ -1237,14 +1290,13 @@ struct CYReturn : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYEmpty : CYStatement { - virtual void Output(CYOutput &out) const; - virtual void Output(CYOutput &out, bool block) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYFinally { @@ -1272,7 +1324,7 @@ struct CYTry : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYThrow : @@ -1285,7 +1337,7 @@ struct CYThrow : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYWith : @@ -1300,7 +1352,7 @@ struct CYWith : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYSwitch : @@ -1315,7 +1367,7 @@ struct CYSwitch : { } - virtual void Output(CYOutput &out) const; + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYCondition : -- 2.47.2