X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/691e471776ef0b8ba0be2166ad7e5d9066d6cd62..577bfbfa3f039da39d0f0ac8b396a1ecfd4e5583:/Parser.hpp diff --git a/Parser.hpp b/Parser.hpp index 87dc682..8773619 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -1,4 +1,4 @@ -/* Cycript - Remote Execution Server and Disassembler +/* Cycript - Inlining/Optimizing JavaScript Compiler * Copyright (C) 2009 Jay Freeman (saurik) */ @@ -47,11 +47,17 @@ #include #include +#include +#include +#include #include #include "location.hh" #include "Pooling.hpp" +#include "Options.hpp" + +class CYContext; template struct CYNext { @@ -73,13 +79,18 @@ struct CYNext { }; struct CYThing { + virtual ~CYThing() { + } + virtual void Output(struct CYOutput &out) const = 0; }; struct CYOutput { std::ostream &out_; + CYOptions &options_; bool pretty_; unsigned indent_; + bool right_; enum { NoMode, @@ -89,10 +100,12 @@ struct CYOutput { Terminated } mode_; - CYOutput(std::ostream &out) : + CYOutput(std::ostream &out, CYOptions &options) : out_(out), + options_(options), pretty_(false), indent_(0), + right_(false), mode_(NoMode) { } @@ -117,6 +130,9 @@ struct CYOutput { struct CYPropertyName { virtual void PropertyName(CYOutput &out) const = 0; + + virtual ~CYPropertyName() { + } }; struct CYExpression; @@ -135,32 +151,21 @@ enum CYFlags { CYNoCall = (1 << 3), CYNoRightHand = (1 << 4), CYNoDangle = (1 << 5), + CYNoInteger = (1 << 6), CYNoBF = (CYNoBrace | CYNoFunction), }; -struct CYContext { - apr_pool_t *pool_; - - CYContext(apr_pool_t *pool) : - pool_(pool) - { - } - - template - void Replace(Type_ *&value) { - if (value != NULL) - while (Type_ *replace = value->Replace(*this)) - value = replace; - } -}; - struct CYStatement : CYNext { + virtual ~CYStatement() { + } + void Single(CYOutput &out, CYFlags flags) const; void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const; CYStatement *ReplaceAll(CYContext &context); + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context) = 0; @@ -198,6 +203,9 @@ struct CYStatements { }; struct CYClassName { + virtual ~CYClassName() { + } + virtual CYExpression *ClassName(CYContext &context, bool object) = 0; virtual void ClassName(CYOutput &out, bool object) const = 0; }; @@ -214,10 +222,11 @@ struct CYWord : { } - const char *Value() const { - return word_; + void Set(const char *value) { + word_ = value; } + virtual const char *Word() const; virtual void Output(CYOutput &out) const; virtual CYExpression *ClassName(CYContext &context, bool object); @@ -226,16 +235,42 @@ struct CYWord : }; _finline std::ostream &operator <<(std::ostream &lhs, const CYWord &rhs) { - return lhs << rhs.Value(); + lhs << &rhs << '='; + return lhs << rhs.Word(); } struct CYIdentifier : + CYNext, CYWord { + CYIdentifier *replace_; + size_t offset_; + size_t usage_; + CYIdentifier(const char *word) : - CYWord(word) + CYWord(word), + replace_(NULL), + offset_(0), + usage_(0) + { + } + + virtual const char *Word() const; + CYIdentifier *Replace(CYContext &context); +}; + +struct CYComment : + CYStatement +{ + const char *value_; + + CYComment(const char *value) : + value_(value) { } + + virtual CYStatement *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYLabel : @@ -254,6 +289,69 @@ struct CYLabel : virtual void Output(CYOutput &out, CYFlags flags) const; }; +struct CYCStringLess : + std::binary_function +{ + _finline bool operator ()(const char *lhs, const char *rhs) const { + return strcmp(lhs, rhs) < 0; + } +}; + +struct CYIdentifierValueLess : + std::binary_function +{ + _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const { + return CYCStringLess()(lhs->Word(), rhs->Word()); + } +}; + +enum CYIdentifierFlags { + CYIdentifierArgument, + CYIdentifierVariable, + CYIdentifierOther, + CYIdentifierMagic, + CYIdentifierCatch, +}; + +typedef std::set CYCStringSet; +typedef std::set CYIdentifierValueSet; +typedef std::map CYIdentifierAddressFlagsMap; + +struct CYIdentifierUsage { + CYIdentifier *identifier_; + size_t usage_; +}; + +typedef std::vector CYIdentifierUsageVector; + +// XXX: strategy pattern, maybe subclass +enum CYScopeType { + CYScopeCatch, + CYScopeFunction, + CYScopeProgram, +}; + +struct CYScope { + CYScopeType type_; + + CYContext &context_; + CYStatement *&statements_; + + CYScope *parent_; + + CYIdentifierAddressFlagsMap internal_; + CYIdentifierValueSet identifiers_; + + CYScope(CYScopeType type, CYContext &context, CYStatement *&statements); + + void Close(); + + void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags); + virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier); + void Merge(CYContext &context, CYIdentifier *identifier); + void Scope(CYContext &context, CYStatement *&statements); +}; + struct CYProgram : CYThing { @@ -265,10 +363,64 @@ struct CYProgram : } virtual void Replace(CYContext &context); - virtual void Output(CYOutput &out) const; }; +struct CYNonLocal; + +struct CYContext { + CYOptions &options_; + + CYScope *scope_; + CYIdentifierUsageVector rename_; + + CYNonLocal *nonlocal_; + CYNonLocal *nextlocal_; + unsigned unique_; + + CYContext(CYOptions &options) : + options_(options), + scope_(NULL), + nonlocal_(NULL), + nextlocal_(NULL), + unique_(0) + { + } + + virtual ~CYContext() { + } + + template + void Replace(Type_ *&value) { + for (;;) if (value == NULL) + break; + else { + Type_ *replace(value->Replace(*this)); + if (replace != value) + value = replace; + else break; + } + } + + void NonLocal(CYStatement *&statements); + CYIdentifier *Unique(); +}; + +struct CYNonLocal { + CYIdentifier *identifier_; + + CYNonLocal() : + identifier_(NULL) + { + } + + CYIdentifier *Target(CYContext &context) { + if (identifier_ == NULL) + identifier_ = context.Unique(); + return identifier_; + } +}; + struct CYBlock : CYStatement, CYThing @@ -284,6 +436,14 @@ struct CYBlock : return statements_; } + void AddPrev(CYStatement *statement) { + CYStatement *last(statement); + while (last->next_ != NULL) + last = last->next_; + last->SetNext(statements_); + statements_ = statement; + } + virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out) const; @@ -298,8 +458,6 @@ enum CYState { class CYDriver { public: - CYPool pool_; - CYState state_; void *scanner_; @@ -328,12 +486,39 @@ class CYDriver { CYProgram *program_; Errors errors_; + bool auto_; + + struct Context { + CYExpression *context_; + + Context(CYExpression *context) : + context_(context) + { + } + + typedef std::vector Words; + Words words_; + }; + + typedef std::vector Contexts; + Contexts contexts_; + + CYExpression *context_; + + enum Mode { + AutoNone, + AutoPrimary, + AutoDirect, + AutoIndirect, + AutoMessage + } mode_; + private: void ScannerInit(); void ScannerDestroy(); public: - CYDriver(const std::string &filename); + CYDriver(const std::string &filename = ""); ~CYDriver(); Condition GetCondition(); @@ -346,13 +531,21 @@ class CYDriver { }; struct CYForInitialiser { + virtual ~CYForInitialiser() { + } + virtual void For(CYOutput &out) const = 0; + virtual CYExpression *Replace(CYContext &context) = 0; }; struct CYForInInitialiser { + virtual ~CYForInInitialiser() { + } + virtual void ForIn(CYOutput &out, CYFlags flags) const = 0; virtual const char *ForEachIn() const = 0; virtual CYExpression *ForEachIn(CYContext &out) = 0; + virtual CYExpression *Replace(CYContext &context) = 0; }; struct CYNumber; @@ -377,6 +570,8 @@ struct CYExpression : virtual const char *ForEachIn() const; virtual CYExpression *ForEachIn(CYContext &out); + virtual CYExpression *AddArgument(CYContext &context, CYExpression *value); + virtual void Output(CYOutput &out) const; virtual void Output(CYOutput &out, CYFlags flags) const = 0; void Output(CYOutput &out, unsigned precedence, CYFlags flags) const; @@ -425,7 +620,7 @@ struct CYCompound : { CYExpression *expressions_; - CYCompound(CYExpression *expressions) : + CYCompound(CYExpression *expressions = NULL) : expressions_(expressions) { } @@ -456,6 +651,22 @@ struct CYFunctionParameter : { } + virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code); + virtual void Output(CYOutput &out) const; +}; + +struct CYOptionalFunctionParameter : + CYFunctionParameter +{ + CYExpression *initializer_; + + CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) : + CYFunctionParameter(name, next), + initializer_(initializer) + { + } + + virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code); virtual void Output(CYOutput &out) const; }; @@ -484,7 +695,7 @@ struct CYForInComprehension : } virtual const char *Name() const { - return name_->Value(); + return name_->Word(); } virtual CYFunctionParameter *Parameter(CYContext &context) const; @@ -505,7 +716,7 @@ struct CYForEachInComprehension : } virtual const char *Name() const { - return name_->Value(); + return name_->Word(); } virtual CYFunctionParameter *Parameter(CYContext &context) const; @@ -620,7 +831,7 @@ struct CYString : } CYString(const CYWord *word) : - value_(word->Value()), + value_(word->Word()), size_(strlen(value_)) { } @@ -634,7 +845,7 @@ struct CYString : virtual CYNumber *Number(CYContext &context); virtual CYString *String(CYContext &context); - virtual CYString *Concat(CYContext &out, CYString *rhs) const; + CYString *Concat(CYContext &out, CYString *rhs) const; virtual void Output(CYOutput &out, CYFlags flags) const; virtual void PropertyName(CYOutput &out) const; }; @@ -757,6 +968,11 @@ struct CYVariable : { } + CYVariable(const char *name) : + name_(new($pool) CYIdentifier(name)) + { + } + CYPrecedence(0) CYRightHand(false) @@ -929,13 +1145,31 @@ struct CYArray : virtual void Output(CYOutput &out, CYFlags flags) const; }; +struct CYProperty : + CYNext, + CYThing +{ + CYPropertyName *name_; + CYExpression *value_; + + CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) : + CYNext(next), + name_(name), + value_(value) + { + } + + void Replace(CYContext &context); + virtual void Output(CYOutput &out) const; +}; + struct CYDeclaration : CYForInInitialiser { CYIdentifier *identifier_; CYExpression *initialiser_; - CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser) : + CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) : identifier_(identifier), initialiser_(initialiser) { @@ -946,15 +1180,16 @@ struct CYDeclaration : virtual const char *ForEachIn() const; virtual CYExpression *ForEachIn(CYContext &out); - void Replace(CYContext &context); + virtual CYExpression *Replace(CYContext &context); + virtual CYAssignment *Assignment(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYDeclarations : CYNext, - CYForInitialiser, - CYThing + CYThing, + CYForInitialiser { CYDeclaration *declaration_; @@ -966,7 +1201,8 @@ struct CYDeclarations : virtual void For(CYOutput &out) const; - void Replace(CYContext &context); + virtual CYCompound *Replace(CYContext &context); + CYProperty *Property(CYContext &context); virtual void Output(CYOutput &out) const; virtual void Output(CYOutput &out, CYFlags flags) const; @@ -1058,30 +1294,12 @@ struct CYForEachIn : virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYProperty : - CYNext, - CYThing -{ - CYPropertyName *name_; - CYExpression *value_; - - CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) : - CYNext(next), - name_(name), - value_(value) - { - } - - void Replace(CYContext &context); - virtual void Output(CYOutput &out) const; -}; - struct CYObject : CYLiteral { CYProperty *properties_; - CYObject(CYProperty *properties) : + CYObject(CYProperty *properties = NULL) : properties_(properties) { } @@ -1090,22 +1308,6 @@ struct CYObject : void Output(CYOutput &out, CYFlags flags) const; }; -struct CYCatch : - CYThing -{ - CYIdentifier *name_; - CYBlock code_; - - CYCatch(CYIdentifier *name, CYStatement *statements) : - name_(name), - code_(statements) - { - } - - void Replace(CYContext &context); - virtual void Output(CYOutput &out) const; -}; - struct CYMember : CYExpression { @@ -1155,13 +1357,16 @@ struct CYIndirectMember : virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYNew : +namespace cy { +namespace Syntax { + +struct New : CYExpression { CYExpression *constructor_; CYArgument *arguments_; - CYNew(CYExpression *constructor, CYArgument *arguments) : + New(CYExpression *constructor, CYArgument *arguments) : constructor_(constructor), arguments_(arguments) { @@ -1175,8 +1380,12 @@ struct CYNew : virtual CYExpression *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; + + virtual CYExpression *AddArgument(CYContext &context, CYExpression *value); }; +} } + struct CYCall : CYExpression { @@ -1194,6 +1403,29 @@ struct CYCall : virtual CYExpression *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; + + virtual CYExpression *AddArgument(CYContext &context, CYExpression *value); +}; + +struct CYRubyProc; + +struct CYRubyBlock : + CYExpression +{ + CYExpression *call_; + CYRubyProc *proc_; + + CYRubyBlock(CYExpression *call, CYRubyProc *proc) : + call_(call), + proc_(proc) + { + } + + CYPrecedence(1) + CYRightHand(false) + + virtual CYExpression *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; }; struct CYIf : @@ -1246,22 +1478,30 @@ struct CYWhile : virtual void Output(CYOutput &out, CYFlags flags) const; }; +// XXX: this should be split up into CYAnonymousFunction and CYNamedFunction (subclass) struct CYFunction { CYIdentifier *name_; CYFunctionParameter *parameters_; CYBlock code_; + CYNonLocal *nonlocal_; CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *statements) : name_(name), parameters_(parameters), - code_(statements) + code_(statements), + nonlocal_(NULL) { } - virtual void Replace_(CYContext &context); + virtual ~CYFunction() { + } + + void Inject(CYContext &context); + virtual void Replace_(CYContext &context, bool outer); virtual void Output(CYOutput &out, CYFlags flags) const; }; +// XXX: this should be split up into CYAnonymousFunctionExpression and CYNamedFunctionExpression struct CYFunctionExpression : CYFunction, CYExpression @@ -1278,6 +1518,20 @@ struct CYFunctionExpression : virtual void Output(CYOutput &out, CYFlags flags) const; }; +// XXX: this should derive from CYAnonymousFunctionExpression +struct CYRubyProc : + CYFunctionExpression +{ + CYRubyProc(CYFunctionParameter *parameters, CYStatement *statements) : + CYFunctionExpression(NULL, parameters, statements) + { + } + + virtual CYExpression *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +// XXX: this should derive from CYNamedFunction struct CYFunctionStatement : CYFunction, CYStatement @@ -1299,8 +1553,11 @@ struct CYExpress : CYExpress(CYExpression *expression) : expression_(expression) { + if (expression == NULL) + throw; } + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1350,6 +1607,7 @@ struct CYReturn : struct CYEmpty : CYStatement { + virtual CYStatement *Collapse(CYContext &context); virtual CYStatement *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1368,14 +1626,33 @@ struct CYFinally : virtual void Output(CYOutput &out) const; }; -struct CYTry : +namespace cy { +namespace Syntax { + +struct Catch : + CYThing +{ + CYIdentifier *name_; + CYBlock code_; + + Catch(CYIdentifier *name, CYStatement *statements) : + name_(name), + code_(statements) + { + } + + void Replace(CYContext &context); + virtual void Output(CYOutput &out) const; +}; + +struct Try : CYStatement { CYBlock code_; - CYCatch *catch_; + Catch *catch_; CYFinally *finally_; - CYTry(CYStatement *statements, CYCatch *_catch, CYFinally *finally) : + Try(CYStatement *statements, Catch *_catch, CYFinally *finally) : code_(statements), catch_(_catch), finally_(finally) @@ -1386,12 +1663,12 @@ struct CYTry : virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYThrow : +struct Throw : CYStatement { CYExpression *value_; - CYThrow(CYExpression *value) : + Throw(CYExpression *value = NULL) : value_(value) { } @@ -1400,6 +1677,8 @@ struct CYThrow : virtual void Output(CYOutput &out, CYFlags flags) const; }; +} } + struct CYWith : CYStatement { @@ -1478,7 +1757,7 @@ struct CYIndirect : } virtual const char *Operator() const { - return "^"; + return "*"; } CYAlphabetic(false)