]> git.saurik.com Git - cycript.git/commitdiff
Added output generation.
authorJay Freeman (saurik) <saurik@saurik.com>
Wed, 30 Sep 2009 07:34:08 +0000 (07:34 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Wed, 30 Sep 2009 07:34:08 +0000 (07:34 +0000)
Cycript.l
Cycript.y
Library.mm
Output.cpp [new file with mode: 0644]
Parser.hpp
Pooling.hpp [new file with mode: 0644]
makefile

index 1424d1e7e91c3114a6bddbc9a8d9e78851ec7561..1fada80570aa6fc83d9b51f24daed8237e902f7f 100644 (file)
--- 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_);
 }
index b0397994e1c0264460a12243d31eef0cd730e868..c7084b5e2bd3a6764819dbc1467909941c83b371 100644 (file)
--- 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
index f3a18bb755c483127f26008f62398d1e5656cf14..81354299907f066aac1216b89f90faabd9800b4c 100644 (file)
@@ -45,8 +45,7 @@
 #include "sig/parse.hpp"
 #include "sig/ffi_type.hpp"
 
-#include <apr-1/apr_pools.h>
-#include <apr-1/apr_strings.h>
+#include "Pooling.hpp"
 
 #include <unistd.h>
 
     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<NSAutoreleasePool> _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("<stdin>");
+    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 (file)
index 0000000..b45703f
--- /dev/null
@@ -0,0 +1,373 @@
+#include "Parser.hpp"
+
+#include <iostream>
+#include <iomanip>
+
+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();
+}
index 3fb903aa43cc3ddb3a8f4a2e988cb44d795bc7f9..7469b943bfacd71feb8e3e414a5cc7c5ffa855a5 100644 (file)
@@ -2,38 +2,53 @@
 #define CYPARSER_HPP
 
 #include <cstdlib>
+#include <string>
 
-class CYParser {
-  public:
-    void *scanner_;
-
-  private:
-    void ScannerInit();
-    void ScannerDestroy();
+#include "Pooling.hpp"
 
-  public:
-    CYParser();
-    ~CYParser();
-};
+template <typename Type_>
+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<CYSource>,
+    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<CYExpression>,
     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<CYClause>
+{
     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 (file)
index 0000000..86f57ca
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef CYPOOLING_HPP
+#define CYPOOLING_HPP
+
+#include <apr-1/apr_pools.h>
+#include <apr-1/apr_strings.h>
+
+#include <minimal/stdlib.h>
+
+_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*/
index 45c3e1c27c9214f84844a5768ba0a82853818b89..0e768d578d64184139309b352bd537f6a881fed7 100644 (file)
--- 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 <Parser.dat >$@
 
-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