From 5999c31517bb72b55257d25f482edc566adec045 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Wed, 30 Sep 2009 07:34:08 +0000 Subject: [PATCH] Added output generation. --- Cycript.l | 81 ++++++------ Cycript.y | 16 ++- Library.mm | 52 ++------ Output.cpp | 373 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Parser.hpp | 300 +++++++++++++++++++++++++++++++++++------- Pooling.hpp | 43 ++++++ makefile | 30 +++-- 7 files changed, 752 insertions(+), 143 deletions(-) create mode 100644 Output.cpp create mode 100644 Pooling.hpp diff --git a/Cycript.l b/Cycript.l index 1424d1e..1fada80 100644 --- a/Cycript.l +++ b/Cycript.l @@ -1,7 +1,7 @@ %{ #include "Cycript.tab.hh" typedef cy::parser::token tk; -#define YY_EXTRA_TYPE CYParser * +#define YY_EXTRA_TYPE CYDriver * %} %option prefix="cy" @@ -72,54 +72,55 @@ Escape \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} "[" return tk::OpenBracket; "]" return tk::CloseBracket; -"break" return tk::Break; -"case" return tk::Case; -"catch" return tk::Catch; -"continue" return tk::Continue; -"default" return tk::Default; -"delete" return tk::Delete; -"do" return tk::Do; -"else" return tk::Else; -"false" return tk::False; -"finally" return tk::Finally; -"for" return tk::For; -"function" return tk::Function; -"if" return tk::If; -"in" return tk::In; -"instanceof" return tk::InstanceOf; -"new" return tk::New; -"null" return tk::Null; -"return" return tk::Return; -"switch" return tk::Switch; -"this" return tk::This; -"throw" return tk::Throw; -"true" return tk::True; -"try" return tk::Try; -"typeof" return tk::TypeOf; -"var" return tk::Var; -"void" return tk::Void; -"while" return tk::While; -"with" return tk::With; - -[a-zA-Z$_][a-zA-Z$_0-9]* return tk::Identifier; - -(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? return tk::NumericLiteral; - -0[xX][0-9a-fA-F]+ return tk::NumericLiteral; -0[bB][0-1]+ return tk::NumericLiteral; +"break" yylval->word_ = new CYWord("break"); return tk::Break; +"case" yylval->word_ = new CYWord("case"); return tk::Case; +"catch" yylval->word_ = new CYWord("catch"); return tk::Catch; +"continue" yylval->word_ = new CYWord("continue"); return tk::Continue; +"default" yylval->word_ = new CYWord("default"); return tk::Default; +"delete" yylval->word_ = new CYWord("delete"); return tk::Delete; +"do" yylval->word_ = new CYWord("do"); return tk::Do; +"else" yylval->word_ = new CYWord("else"); return tk::Else; +"false" yylval->false_ = new CYFalse(); return tk::False; +"finally" yylval->word_ = new CYWord("finally"); return tk::Finally; +"for" yylval->word_ = new CYWord("for"); return tk::For; +"function" yylval->word_ = new CYWord("function"); return tk::Function; +"if" yylval->word_ = new CYWord("if"); return tk::If; +"in" yylval->word_ = new CYWord("in"); return tk::In; +"instanceof" yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf; +"new" yylval->word_ = new CYWord("new"); return tk::New; +"null" yylval->null_ = new CYNull(); return tk::Null; +"return" yylval->word_ = new CYWord("return"); return tk::Return; +"switch" yylval->word_ = new CYWord("switch"); return tk::Switch; +"this" yylval->this_ = new CYThis(); return tk::This; +"throw" yylval->word_ = new CYWord("throw"); return tk::Throw; +"true" yylval->true_ = new CYTrue(); return tk::True; +"try" yylval->word_ = new CYWord("try"); return tk::Try; +"typeof" yylval->word_ = new CYWord("typeof"); return tk::TypeOf; +"var" yylval->word_ = new CYWord("var"); return tk::Var; +"void" yylval->word_ = new CYWord("void"); return tk::Void; +"while" yylval->word_ = new CYWord("while"); return tk::While; +"with" yylval->word_ = new CYWord("with"); return tk::With; + +[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); return tk::Identifier; + +(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); return tk::NumericLiteral; + +0[xX][0-9a-fA-F]+ yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral; + +0[bB][0-1]+ yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral; \"([^"\\\n]|{Escape})*\" return tk::StringLiteral; -'([^'\\\n]|{Escape})*' return tk::StringLiteral; +'([^'\\\n]|{Escape})*' return tk::StringLiteral; -[ \t\n] ; +[ \t\n] ; %% -void CYParser::ScannerInit() { +void CYDriver::ScannerInit() { cylex_init(&scanner_); cyset_extra(this, scanner_); } -void CYParser::ScannerDestroy() { +void CYDriver::ScannerDestroy() { cylex_destroy(scanner_); } diff --git a/Cycript.y b/Cycript.y index b039799..c7084b5 100644 --- a/Cycript.y +++ b/Cycript.y @@ -1,7 +1,7 @@ %code top { #include "Cycript.tab.hh" int cylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); -#define scanner driver->scanner_ +#define scanner driver.scanner_ } %code requires { @@ -41,12 +41,16 @@ int cylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner); %locations %glr-parser +%initial-action { + @$.begin.filename = @$.end.filename = &driver.filename_; +}; + %defines %debug %error-verbose -%parse-param { CYParser *driver } +%parse-param { CYDriver &driver } %lex-param { void *scanner } %token Ampersand "&" @@ -409,6 +413,7 @@ Arguments LeftHandSideExpression : NewExpression { $$ = $1; } | CallExpression { $$ = $1; } + | "*" LeftHandSideExpression { $$ = new CYIndirect($2); } ; PostfixExpression @@ -428,7 +433,6 @@ UnaryExpression | "-" UnaryExpression { $$ = new CYNegate($2); } | "~" UnaryExpression { $$ = new CYBitwiseNot($2); } | "!" UnaryExpression { $$ = new CYLogicalNot($2); } - | "*" UnaryExpression { $$ = new CYIndirect($2); } | "&" UnaryExpression { $$ = new CYAddressOf($2); } ; @@ -527,7 +531,7 @@ ExpressionOpt ; Expression - : AssignmentExpression Expression_ { $1->SetNext($2); $$ = $1; } + : AssignmentExpression Expression_ { if ($1 == NULL) $$ = $2; else { $1->SetNext($2); $$ = $1; } } ; Statement @@ -587,7 +591,7 @@ EmptyStatement ; ExpressionStatement - : Expression ";" { $$ = $1; } + : Expression ";" { $$ = new CYExpress($1); } ; ElseStatementOpt @@ -715,7 +719,7 @@ FunctionBody ; Program - : SourceElements { $$ = $1; } + : SourceElements { driver.source_ = $1; $$ = $1; } ; SourceElements diff --git a/Library.mm b/Library.mm index f3a18bb..8135429 100644 --- a/Library.mm +++ b/Library.mm @@ -45,8 +45,7 @@ #include "sig/parse.hpp" #include "sig/ffi_type.hpp" -#include -#include +#include "Pooling.hpp" #include @@ -89,41 +88,6 @@ CFLog(kCFLogLevelNotice, CFSTR("_trace():%u"), __LINE__); \ } while (false) -/* APR Pool Helpers {{{ */ -void *operator new(size_t size, apr_pool_t *pool) { - return apr_palloc(pool, size); -} - -void *operator new [](size_t size, apr_pool_t *pool) { - return apr_palloc(pool, size); -} - -class CYPool { - private: - apr_pool_t *pool_; - - public: - CYPool() { - apr_pool_create(&pool_, NULL); - } - - ~CYPool() { - apr_pool_destroy(pool_); - } - - operator apr_pool_t *() const { - return pool_; - } - - char *operator ()(const char *data) const { - return apr_pstrdup(pool_, data); - } - - char *operator ()(const char *data, size_t size) const { - return apr_pstrndup(pool_, data, size); - } -}; -/* }}} */ #define _pooled _H _pool([[NSAutoreleasePool alloc] init], true); @@ -952,11 +916,14 @@ static JSStaticValue Pointer_staticValues[2] = { {NULL, NULL, NULL, 0} }; -CYParser::CYParser() { +CYDriver::CYDriver(const std::string &filename) : + filename_(filename), + source_(NULL) +{ ScannerInit(); } -CYParser::~CYParser() { +CYDriver::~CYDriver() { ScannerDestroy(); } @@ -968,9 +935,10 @@ void cy::parser::error(const cy::parser::location_type &loc, const std::string & void CYConsole(FILE *fin, FILE *fout, FILE *ferr) { cydebug = 1; - CYParser driver; - cy::parser parser(&driver); - parser.parse(); + CYDriver driver(""); + cy::parser parser(driver); + if (parser.parse() == 0) + driver.source_->Part(std::cout); } MSInitialize { _pooled diff --git a/Output.cpp b/Output.cpp new file mode 100644 index 0000000..b45703f --- /dev/null +++ b/Output.cpp @@ -0,0 +1,373 @@ +#include "Parser.hpp" + +#include +#include + +void CYAddressOf::Output(std::ostream &out) const { + out << *rhs_ << ".$()"; +} + +void CYArgument::Output(std::ostream &out, bool send) const { + if (!send && name_ != NULL) { + out << *name_; + if (value_ != NULL) + out << ":"; + } + if (value_ != NULL) { + if (send) + out << ','; + value_->Output(out, true); + } + if (next_ != NULL) { + if (!send) + if (next_->name_ != NULL) + out << ','; + else + out << ' '; + next_->Output(out, send); + } +} + +void CYBoolean::Output(std::ostream &out) const { + out << (Value() ? "true" : "false"); +} + +void CYBreak::Output(std::ostream &out) const { + out << "break"; + if (label_ != NULL) + out << ' ' << *label_; + out << ';'; +} + +void CYCall::Output(std::ostream &out) const { + out << *function_ << '('; + if (arguments_ != NULL) + arguments_->Output(out, false); + out << ')'; +} + +void CYCatch::Output(std::ostream &out) const { + out << "catch(" << *name_ << ')'; + code_->Output(out, true); +} + +void CYCondition::Output(std::ostream &out) const { + out << *test_ << '?'; + if (true_ != NULL) + out << *true_; + out << ':' << *false_; +} + +void CYContinue::Output(std::ostream &out) const { + out << "continue"; + if (label_ != NULL) + out << ' ' << *label_; + out << ';'; +} + +void CYClause::Output(std::ostream &out) const { + if (case_ != NULL) + out << "case" << *case_; + else + out << "default"; + out << ':'; + if (code_ != NULL) + code_->Output(out, false); + out << *next_; +} + +void CYDeclaration::Part(std::ostream &out) const { + out << "var "; + Output(out); +} + +void CYDeclaration::Output(std::ostream &out) const { + out << *identifier_; + if (initialiser_ != NULL) + out << '=' << *initialiser_; +} + +void CYDeclarations::Part(std::ostream &out) const { + out << "var "; + const CYDeclarations *declaration(this); + do { + out << *declaration->declaration_; + declaration = declaration->next_; + } while (declaration != NULL); +} + +void CYDeclarations::Output(std::ostream &out) const { + Part(out); + out << ';'; +} + +void CYDoWhile::Output(std::ostream &out) const { + out << "do "; + code_->Output(out, false); + out << "while" << *test_ << ';'; +} + +void CYElement::Output(std::ostream &out, bool raw) const { + if (!raw) + out << '['; + if (value_ != NULL) + value_->Output(out, true); + if (next_ != NULL) { + out << ','; + next_->Output(out, true); + } + if (!raw) + out << ']'; +} + +void CYElement::Output(std::ostream &out) const { + Output(out, false); +} + +void CYEmpty::Output(std::ostream &out) const { + out << ';'; +} + +void CYEmpty::Output(std::ostream &out, bool block) const { + if (next_ != NULL) + CYSource::Output(out, block); + else + out << "{}"; +} + +void CYExpress::Output(std::ostream &out) const { + expression_->Output(out, true); + out << ';'; +} + +void CYExpression::Part(std::ostream &out) const { + Output(out, true); +} + +void CYExpression::Output(std::ostream &out, bool raw) const { + if (!raw) + out << '('; + Output(out); + if (next_ != NULL) { + out << ','; + next_->Output(out, true); + } + if (!raw) + out << ')'; +} + +void CYFor::Output(std::ostream &out) const { + out << "for("; + if (initialiser_ != NULL) + initialiser_->Part(out); + out << ';'; + if (test_ != NULL) + test_->Output(out, true); + out << ';'; + if (increment_ != NULL) + increment_->Output(out, true); + out << ')'; + code_->Output(out, false); +} + +void CYForIn::Output(std::ostream &out) const { + out << "for("; + initialiser_->Part(out); + out << " in "; + set_->Output(out, true); + out << ')'; + code_->Output(out, false); +} + +void CYFunction::Output(std::ostream &out) const { + CYLambda::Output(out); +} + +void CYIf::Output(std::ostream &out) const { + out << "if" << *test_; + true_->Output(out, true); + if (false_ != NULL) { + out << "else "; + false_->Output(out, false); + } +} + +void CYIndirect::Output(std::ostream &out) const { + out << *rhs_ << "[0]"; +} + +void CYInfix::Output(std::ostream &out) const { + out << *lhs_ << Operator() << *rhs_; +} + +void CYLambda::Output(std::ostream &out) const { + out << "function"; + if (name_ != NULL) + out << ' ' << *name_; + out << '('; + if (parameters_ != NULL) + out << *parameters_; + out << ')'; + body_->Output(out, true); +} + +void CYMember::Output(std::ostream &out) const { + out << *object_ << '['; + property_->Output(out, true); + out << ']'; +} + +void CYMessage::Output(std::ostream &out) const { + out << "objc_msgSend("; + self_->Output(out, true); + out << ",\""; + for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) + if (argument->name_ != NULL) { + out << *argument->name_; + if (argument->value_ != NULL) + out << ':'; + } + out << "\""; + if (arguments_ != NULL) + arguments_->Output(out, true); + out << ')'; +} + +void CYNew::Output(std::ostream &out) const { + out << "new " << *constructor_ << '('; + if (arguments_ != NULL) + arguments_->Output(out, false); + out << ')'; +} + +void CYNull::Output(std::ostream &out) const { + CYWord::Output(out); +} + +void CYNumber::Output(std::ostream &out) const { + // XXX: this is not a useful formatting + out << Value(); +} + +void CYParameter::Output(std::ostream &out) const { + out << *name_; + if (next_ != NULL) { + out << ','; + out << *next_; + } +} + +void CYPostfix::Output(std::ostream &out) const { + out << *lhs_ << Operator(); +} + +void CYPrefix::Output(std::ostream &out) const { + out << Operator() << *rhs_; +} + +void CYProperty::Output(std::ostream &out, bool raw) const { + if (!raw) + out << '{'; + out << *name_ << ':' << *value_; + if (next_ != NULL) { + out << ','; + next_->Output(out, true); + } + if (!raw) + out << '}'; +} + +void CYProperty::Output(std::ostream &out) const { + Output(out, false); +} + +void CYReturn::Output(std::ostream &out) const { + out << "return"; + if (value_ != NULL) + out << ' ' << *value_; + out << ';'; +} + +void CYSource::Part(std::ostream &out) const { + for (const CYSource *next(this); next != NULL; next = next->next_) + next->Output(out); +} + +void CYSource::Output(std::ostream &out, bool block) const { + if (!block && next_ == NULL) + Output(out); + else { + out << '{'; + Part(out); + out << '}'; + } +} + +void CYString::Output(std::ostream &out) const { + out << '\"'; + for (const char *value(value_), *end(value_ + size_); value != end; ++value) + switch (*value) { + case '"': out << "\\\""; break; + case '\\': out << "\\\\"; break; + case '\b': out << "\\b"; break; + case '\f': out << "\\f"; break; + case '\n': out << "\\n"; break; + case '\r': out << "\\r"; break; + case '\t': out << "\\t"; break; + case '\v': out << "\\v"; break; + + default: + if (*value < 0x20 || *value >= 0x7f) + out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); + else + out << *value; + } + out << '\"'; +} + +void CYSwitch::Output(std::ostream &out) const { + out << "switch" << *value_ << '{'; + if (clauses_ != NULL) + out << *clauses_; + out << '}'; +} + +void CYThis::Output(std::ostream &out) const { + CYWord::Output(out); +} + +void CYThrow::Output(std::ostream &out) const { + out << "return"; + if (value_ != NULL) + out << ' ' << *value_; + out << ';'; +} + +void CYTry::Output(std::ostream &out) const { + out << "try"; + try_->Output(out, true); + if (catch_ != NULL) + out << catch_; + if (finally_ != NULL) { + out << "finally"; + finally_->Output(out, true); + } +} + +void CYVariable::Output(std::ostream &out) const { + out << *name_; +} + +void CYWhile::Output(std::ostream &out) const { + out << "while" << *test_; + code_->Output(out, false); +} + +void CYWith::Output(std::ostream &out) const { + out << "with" << *scope_; + code_->Output(out, false); +} + +void CYWord::Output(std::ostream &out) const { + out << Value(); +} diff --git a/Parser.hpp b/Parser.hpp index 3fb903a..7469b94 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -2,38 +2,53 @@ #define CYPARSER_HPP #include +#include -class CYParser { - public: - void *scanner_; - - private: - void ScannerInit(); - void ScannerDestroy(); +#include "Pooling.hpp" - public: - CYParser(); - ~CYParser(); -}; +template +struct CYNext { + Type_ *next_; -struct CYSource { - CYSource *next_; + CYNext() : + next_(NULL) + { + } - void SetNext(CYSource *next) { + void SetNext(Type_ *next) { next_ = next; } }; -struct CYName { - virtual const char *Name() const = 0; +struct CYThing { + virtual void Output(std::ostream &out) const = 0; +}; + +_finline std::ostream &operator <<(std::ostream &out, const CYThing &rhs) { + rhs.Output(out); + return out; +} + +struct CYPart { + virtual void Part(std::ostream &out) const = 0; }; -struct CYToken { - virtual const char *Text() const = 0; +struct CYSource : + CYNext, + CYPart +{ + virtual void Part(std::ostream &out) const; + virtual void Output(std::ostream &out) const = 0; + virtual void Output(std::ostream &out, bool block) const; +}; + +struct CYName : + CYThing +{ + virtual const char *Name() const = 0; }; struct CYWord : - virtual CYToken, CYName { const char *word_; @@ -43,22 +58,23 @@ struct CYWord : { } - virtual const char *Text() const { + const char *Value() const { return word_; } virtual const char *Name() const { - return Text(); + return Value(); } + + virtual void Output(std::ostream &out) const; }; struct CYIdentifier : CYWord { - const char *word_; - - virtual const char *Text() const { - return word_; + CYIdentifier(const char *word) : + CYWord(word) + { } }; @@ -83,19 +99,47 @@ struct CYStatement : } }; -struct CYForInitialiser { +class CYDriver { + public: + CYPool pool_; + std::string filename_; + CYSource *source_; + void *scanner_; + + private: + void ScannerInit(); + void ScannerDestroy(); + + public: + CYDriver(const std::string &filename); + ~CYDriver(); +}; + +struct CYForInitialiser : + CYPart +{ }; -struct CYForInInitialiser { +struct CYForInInitialiser : + CYPart +{ }; struct CYExpression : - CYStatement, + CYNext, CYForInitialiser, CYForInInitialiser { + virtual void Part(std::ostream &out) const; + virtual void Output(std::ostream &out) const = 0; + void Output(std::ostream &out, bool raw) const; }; +_finline std::ostream &operator <<(std::ostream &out, const CYExpression &rhs) { + rhs.Output(out, false); + return out; +} + struct CYLiteral : CYExpression { @@ -106,38 +150,51 @@ struct CYString : CYName { const char *value_; + size_t size_; - CYString(const char *value) : - value_(value) + CYString(const char *value, size_t size) : + value_(value), + size_(size) { } CYString(const CYIdentifier *identifier) : - value_(identifier->Text()) + value_(identifier->Value()), + size_(strlen(value_)) { } - const char *String() const { + const char *Value() const { return value_; } virtual const char *Name() const { - return String(); + return Value(); } + + virtual void Output(std::ostream &out) const; }; struct CYNumber : - virtual CYToken, CYLiteral, CYName { - double Number() const { - throw; + double value_; + + CYNumber(double value) : + value_(value) + { + } + + double Value() const { + return value_; } virtual const char *Name() const { throw; } + + virtual void Output(std::ostream &out) const; }; struct CYNull : @@ -148,6 +205,8 @@ struct CYNull : CYWord("null") { } + + virtual void Output(std::ostream &out) const; }; struct CYThis : @@ -158,11 +217,15 @@ struct CYThis : CYWord("this") { } + + virtual void Output(std::ostream &out) const; }; struct CYBoolean : CYLiteral { + virtual bool Value() const = 0; + virtual void Output(std::ostream &out) const; }; struct CYFalse : @@ -173,6 +236,10 @@ struct CYFalse : CYWord("false") { } + + virtual bool Value() const { + return false; + } }; struct CYTrue : @@ -183,6 +250,10 @@ struct CYTrue : CYWord("true") { } + + virtual bool Value() const { + return true; + } }; struct CYVariable : @@ -194,6 +265,8 @@ struct CYVariable : name_(name) { } + + virtual void Output(std::ostream &out) const; }; struct CYPrefix : @@ -205,6 +278,10 @@ struct CYPrefix : rhs_(rhs) { } + + virtual const char *Operator() const = 0; + + virtual void Output(std::ostream &out) const; }; struct CYInfix : @@ -218,6 +295,10 @@ struct CYInfix : rhs_(rhs) { } + + virtual const char *Operator() const = 0; + + virtual void Output(std::ostream &out) const; }; struct CYPostfix : @@ -229,6 +310,10 @@ struct CYPostfix : lhs_(lhs) { } + + virtual const char *Operator() const = 0; + + virtual void Output(std::ostream &out) const; }; struct CYAssignment : @@ -238,6 +323,8 @@ struct CYAssignment : CYInfix(lhs, rhs) { } + + virtual const char *Operator() const = 0; }; struct CYArgument { @@ -251,6 +338,8 @@ struct CYArgument { next_(next) { } + + void Output(std::ostream &out, bool send) const; }; struct CYBlank : @@ -262,10 +351,12 @@ struct CYBlank : } }; -struct CYClause { +struct CYClause : + CYThing, + CYNext +{ CYExpression *case_; CYStatement *code_; - CYClause *next_; CYClause(CYExpression *_case, CYStatement *code) : case_(_case), @@ -273,9 +364,7 @@ struct CYClause { { } - void SetNext(CYClause *next) { - next_ = next; - } + virtual void Output(std::ostream &out) const; }; struct CYElement : @@ -289,9 +378,13 @@ struct CYElement : next_(next) { } + + void Output(std::ostream &out, bool raw) const; + virtual void Output(std::ostream &out) const; }; struct CYDeclaration : + CYThing, CYForInInitialiser { CYIdentifier *identifier_; @@ -302,6 +395,9 @@ struct CYDeclaration : initialiser_(initialiser) { } + + virtual void Part(std::ostream &out) const; + virtual void Output(std::ostream &out) const; }; struct CYDeclarations : @@ -316,9 +412,14 @@ struct CYDeclarations : next_(next) { } + + virtual void Part(std::ostream &out) const; + virtual void Output(std::ostream &out) const; }; -struct CYParameter { +struct CYParameter : + CYThing +{ CYIdentifier *name_; CYParameter *next_; @@ -327,6 +428,8 @@ struct CYParameter { next_(next) { } + + virtual void Output(std::ostream &out) const; }; struct CYFor : @@ -344,6 +447,8 @@ struct CYFor : code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYForIn : @@ -359,6 +464,8 @@ struct CYForIn : code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYProperty : @@ -374,9 +481,14 @@ struct CYProperty : next_(next) { } + + void Output(std::ostream &out, bool raw) const; + virtual void Output(std::ostream &out) const; }; -struct CYCatch { +struct CYCatch : + CYThing +{ CYIdentifier *name_; CYStatement *code_; @@ -385,6 +497,8 @@ struct CYCatch { code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYMessage : @@ -398,6 +512,8 @@ struct CYMessage : arguments_(arguments) { } + + virtual void Output(std::ostream &out) const; }; struct CYMember : @@ -411,6 +527,8 @@ struct CYMember : property_(property) { } + + virtual void Output(std::ostream &out) const; }; struct CYNew : @@ -424,6 +542,8 @@ struct CYNew : arguments_(arguments) { } + + virtual void Output(std::ostream &out) const; }; struct CYCall : @@ -437,6 +557,8 @@ struct CYCall : arguments_(arguments) { } + + virtual void Output(std::ostream &out) const; }; struct CYIf : @@ -452,6 +574,8 @@ struct CYIf : false_(_false) { } + + virtual void Output(std::ostream &out) const; }; struct CYDoWhile : @@ -465,6 +589,8 @@ struct CYDoWhile : code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYWhile : @@ -478,6 +604,8 @@ struct CYWhile : code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYLambda : @@ -493,15 +621,33 @@ struct CYLambda : body_(body) { } + + virtual void Output(std::ostream &out) const; }; struct CYFunction : - CYLambda + CYLambda, + CYSource { CYFunction(CYIdentifier *name, CYParameter *parameters, CYSource *body) : CYLambda(name, parameters, body) { } + + virtual void Output(std::ostream &out) const; +}; + +struct CYExpress : + CYStatement +{ + CYExpression *expression_; + + CYExpress(CYExpression *expression) : + expression_(expression) + { + } + + virtual void Output(std::ostream &out) const; }; struct CYContinue : @@ -513,6 +659,8 @@ struct CYContinue : label_(label) { } + + virtual void Output(std::ostream &out) const; }; struct CYBreak : @@ -524,6 +672,8 @@ struct CYBreak : label_(label) { } + + virtual void Output(std::ostream &out) const; }; struct CYReturn : @@ -535,11 +685,15 @@ struct CYReturn : value_(value) { } + + virtual void Output(std::ostream &out) const; }; struct CYEmpty : CYStatement { + virtual void Output(std::ostream &out) const; + virtual void Output(std::ostream &out, bool block) const; }; struct CYTry : @@ -555,6 +709,8 @@ struct CYTry : finally_(finally) { } + + virtual void Output(std::ostream &out) const; }; struct CYThrow : @@ -566,6 +722,8 @@ struct CYThrow : value_(value) { } + + virtual void Output(std::ostream &out) const; }; struct CYWith : @@ -579,6 +737,8 @@ struct CYWith : code_(code) { } + + virtual void Output(std::ostream &out) const; }; struct CYSwitch : @@ -592,6 +752,8 @@ struct CYSwitch : clauses_(clauses) { } + + virtual void Output(std::ostream &out) const; }; struct CYCondition : @@ -606,6 +768,38 @@ struct CYCondition : false_(_false) { } + + virtual void Output(std::ostream &out) const; +}; + +struct CYAddressOf : + CYPrefix +{ + CYAddressOf(CYExpression *rhs) : + CYPrefix(rhs) + { + } + + virtual const char *Operator() const { + return "&"; + } + + virtual void Output(std::ostream &out) const; +}; + +struct CYIndirect : + CYPrefix +{ + CYIndirect(CYExpression *rhs) : + CYPrefix(rhs) + { + } + + virtual const char *Operator() const { + return "*"; + } + + virtual void Output(std::ostream &out) const; }; #define CYPostfix_(op, name) \ @@ -616,6 +810,10 @@ struct CYCondition : CYPostfix(lhs) \ { \ } \ + \ + virtual const char *Operator() const { \ + return op; \ + } \ }; #define CYPrefix_(op, name) \ @@ -626,6 +824,10 @@ struct CYCondition : CYPrefix(rhs) \ { \ } \ + \ + virtual const char *Operator() const { \ + return op; \ + } \ }; #define CYInfix_(op, name) \ @@ -636,6 +838,10 @@ struct CYCondition : CYInfix(lhs, rhs) \ { \ } \ + \ + virtual const char *Operator() const { \ + return op; \ + } \ }; #define CYAssignment_(op, name) \ @@ -646,6 +852,10 @@ struct CYCondition : CYAssignment(lhs, rhs) \ { \ } \ + \ + virtual const char *Operator() const { \ + return op; \ + } \ }; CYPostfix_("++", PostIncrement) @@ -659,8 +869,6 @@ CYPrefix_("--", PreDecrement) CYPrefix_("-", Negate) CYPrefix_("~", BitwiseNot) CYPrefix_("!", LogicalNot) -CYPrefix_("*", Indirect) -CYPrefix_("&", AddressOf) CYInfix_("*", Multiply) CYInfix_("/", Divide) diff --git a/Pooling.hpp b/Pooling.hpp new file mode 100644 index 0000000..86f57ca --- /dev/null +++ b/Pooling.hpp @@ -0,0 +1,43 @@ +#ifndef CYPOOLING_HPP +#define CYPOOLING_HPP + +#include +#include + +#include + +_finline void *operator new(size_t size, apr_pool_t *pool) { + return apr_palloc(pool, size); +} + +_finline void *operator new [](size_t size, apr_pool_t *pool) { + return apr_palloc(pool, size); +} + +class CYPool { + private: + apr_pool_t *pool_; + + public: + CYPool() { + apr_pool_create(&pool_, NULL); + } + + ~CYPool() { + apr_pool_destroy(pool_); + } + + operator apr_pool_t *() const { + return pool_; + } + + char *operator ()(const char *data) const { + return apr_pstrdup(pool_, data); + } + + char *operator ()(const char *data, size_t size) const { + return apr_pstrndup(pool_, data, size); + } +}; + +#endif/*CYPOOLING_HPP*/ diff --git a/makefile b/makefile index 45c3e1c..0e768d5 100644 --- a/makefile +++ b/makefile @@ -6,17 +6,14 @@ endif package: -flags := -framework CFNetwork -framework JavaScriptCore -framework WebCore -install_name /usr/lib/libcycript.dylib -I. -menes := $(shell cd ~; pwd)/menes - -link := -framework CoreFoundation -framework Foundation -F${PKG_ROOT}/System/Library/PrivateFrameworks -L$(menes)/mobilesubstrate -lsubstrate -lapr-1 -lffi +flags := -mthumb -g3 -O0 -Wall -Werror -I. all: cycript libcycript.dylib libcycript.plist clean: - rm -f libcycript.dylib cycript libcycript.plist Struct.hpp lex.cy.c Cycript.tab.cc Cycript.tab.hh location.hh position.hh + rm -f *.o libcycript.dylib cycript libcycript.plist Struct.hpp lex.cy.c Cycript.tab.cc Cycript.tab.hh location.hh position.hh -libcycript.plist: Bridge.def makefile +libcycript.plist: Bridge.def sed -e 's/^C/0/;s/^F/1/;s/^V/2/' Bridge.def | while read -r line; do \ if [[ $$line == '' ]]; then \ continue; \ @@ -28,7 +25,7 @@ libcycript.plist: Bridge.def makefile echo "$$2 = ($$1, \"$$3\");"; \ done >$@ -Cycript.tab.cc Cycript.tab.hh: Cycript.y makefile +Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.y bison -v $< lex.cy.c: Cycript.l @@ -40,8 +37,23 @@ Struct.hpp: #Parser.hpp: Parser.py Parser.dat # ./Parser.py $@ -libcycript.dylib: Library.mm makefile $(menes)/mobilesubstrate/substrate.h sig/*.[ch]pp Struct.hpp Parser.hpp lex.cy.c Cycript.tab.cc Cycript.tab.hh - $(target)g++ -dynamiclib -mthumb -g0 -O2 -Wall -Werror -o $@ $(filter %.cpp,$^) $(filter %.cc,$^) $(filter %.c,$^) $(filter %.mm,$^) -lobjc -I$(menes)/mobilesubstrate $(link) $(flags) #-DYYDEBUG=1 +%.o: sig/%.cpp + $(target)g++ -c -o $@ $< $(flags) + +Cycript.tab.o: Cycript.tab.cc Cycript.tab.hh Parser.hpp Pooling.hpp + $(target)g++ -c -o $@ $< $(flags) + +lex.cy.o: lex.cy.c Cycript.tab.hh Parser.hpp Pooling.hpp + $(target)g++ -c -o $@ $< $(flags) + +Output.o: Output.cpp Parser.hpp Pooling.hpp + $(target)g++ -c -o $@ $< $(flags) + +Library.o: Library.mm Cycript.tab.hh Parser.hpp Pooling.hpp Struct.hpp + $(target)g++ -c -o $@ $< $(flags) + +libcycript.dylib: ffi_type.o parse.o Output.o Cycript.tab.o lex.cy.o Library.o + $(target)g++ -I. -dynamiclib -mthumb -g3 -O0 -Wall -Werror -o $@ $(filter %.o,$^) -lobjc -framework CFNetwork -framework JavaScriptCore -framework WebCore -install_name /usr/lib/libcycript.dylib -framework CoreFoundation -framework Foundation -F${PKG_ROOT}/System/Library/PrivateFrameworks -L$(menes)/mobilesubstrate -lsubstrate -lapr-1 -lffi ldid -S $@ cycript: Application.mm libcycript.dylib -- 2.45.2