From 4de0686f54039cd5211daebcf5a51ad475594170 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 22 Oct 2009 07:24:24 +0000 Subject: [PATCH] Separated out Objective-C and C language extensions using a new Filter.sh shell script and moved related data structures to ObjectiveC.{hpp,mm}. --- Cycript.y => Cycript.y.in | 25 +++-- Darwin.mk | 6 +- Filter.sh | 21 ++++ ObjectiveC.hpp | 166 ++++++++++++++++++++++++++++ ObjectiveC.mm | 220 ++++++++++++++++++++++++++++++++++++++ Output.cpp | 110 ------------------- Parser.hpp | 172 ++--------------------------- Replace.cpp | 199 +--------------------------------- Replace.hpp | 91 ++++++++++++++++ makefile | 12 ++- 10 files changed, 541 insertions(+), 481 deletions(-) rename Cycript.y => Cycript.y.in (99%) create mode 100755 Filter.sh create mode 100644 ObjectiveC.hpp create mode 100644 ObjectiveC.mm create mode 100644 Replace.hpp diff --git a/Cycript.y b/Cycript.y.in similarity index 99% rename from Cycript.y rename to Cycript.y.in index 7fdc172..0823b7a 100644 --- a/Cycript.y +++ b/Cycript.y.in @@ -46,6 +46,10 @@ %code requires { #include "Parser.hpp" +@begin ObjC +#include "ObjectiveC.hpp" +@end + typedef struct { bool newline_; @@ -76,19 +80,22 @@ typedef struct { CYInfix *infix_; CYLiteral *literal_; CYMember *member_; - CYMessage *message_; - CYMessageParameter *messageParameter_; CYNull *null_; CYNumber *number_; CYProgram *program_; CYProperty *property_; CYPropertyName *propertyName_; - CYSelectorPart *selector_; CYStatement *statement_; CYString *string_; CYThis *this_; CYTrue *true_; CYWord *word_; + +@begin ObjC + CYMessage *message_; + CYMessageParameter *messageParameter_; + CYSelectorPart *selector_; +@end }; } YYSTYPE; @@ -1308,7 +1315,8 @@ SourceElement ; /* }}} */ -/* Cycript: @class Declaration {{{ */ +@begin ObjC +/* Cycript (Objective-C): @class Declaration {{{ */ ClassSuperOpt : ":" MemberExpressionNoBF { $$ = $2; } | { $$ = NULL; } @@ -1386,7 +1394,7 @@ Statement_ | CategoryStatement { $$ = $1; } ; /* }}} */ -/* Cycript: Send Message {{{ */ +/* Cycript (Objective-C): Send Message {{{ */ VariadicCall : "," AssignmentExpression VariadicCall { $$ = new(driver.pool_) CYArgument(NULL, $2, $3); } | { $$ = NULL; } @@ -1429,7 +1437,10 @@ PrimaryExpression_ | "@selector" "(" SelectorExpression ")" { $$ = new(driver.pool_) CYSelector($3); } ; /* }}} */ -/* Cycript: Pointer Indirection/Addressing {{{ */ +@end + +@begin C +/* Cycript (C): Pointer Indirection/Addressing {{{ */ AssigneeExpression_ : "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); } ; @@ -1443,6 +1454,8 @@ MemberAccess | "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); } ; /* }}} */ +@end + /* ECMAScript5: Object Literal Trailing Comma {{{ */ PropertyNameAndValueList_ : "," { $$ = NULL; } diff --git a/Darwin.mk b/Darwin.mk index 1a2a9db..7a63d7d 100644 --- a/Darwin.mk +++ b/Darwin.mk @@ -1,6 +1,10 @@ dll := dylib -header += Struct.hpp +# XXX: objective-c exists on non-Darwin + +header += Struct.hpp ObjectiveC.hpp +code += ObjectiveC.o +filters += ObjC Struct.hpp: $$($(target)gcc -print-prog-name=cc1obj) -print-objc-runtime-info $@ diff --git a/Filter.sh b/Filter.sh new file mode 100755 index 0000000..00dc10c --- /dev/null +++ b/Filter.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +filters=("$@") + +while IFS= read -r line; do + if [[ ${line} = @begin* ]]; then + set ${line}; shift + filter= + for name in "${filters[@]}"; do + for side in "$@"; do + if [[ ${name} == ${side} ]]; then + unset filter + fi + done + done + elif [[ ${line} = @end ]]; then + unset filter + elif [[ -z ${filter+@} ]]; then + echo "${line}" + fi +done diff --git a/ObjectiveC.hpp b/ObjectiveC.hpp new file mode 100644 index 0000000..b45146c --- /dev/null +++ b/ObjectiveC.hpp @@ -0,0 +1,166 @@ +#ifndef CYCRIPT_OBJECTIVEC_HPP +#define CYCRIPT_OBJECTIVEC_HPP + +#include "Parser.hpp" + +struct CYSelectorPart : + CYNext, + CYThing +{ + CYWord *name_; + bool value_; + + CYSelectorPart(CYWord *name, bool value, CYSelectorPart *next) : + CYNext(next), + name_(name), + value_(value) + { + } + + CYString *Replace(CYContext &context); + virtual void Output(CYOutput &out) const; +}; + +struct CYSelector : + CYLiteral +{ + CYSelectorPart *name_; + + CYSelector(CYSelectorPart *name) : + name_(name) + { + } + + CYPrecedence(1) + + virtual CYExpression *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYField : + CYNext +{ + CYStatement *Replace(CYContext &context) const; + void Output(CYOutput &out) const; +}; + +struct CYMessageParameter : + CYNext +{ + CYWord *tag_; + CYExpression *type_; + CYIdentifier *name_; + + CYMessageParameter(CYWord *tag, CYExpression *type, CYIdentifier *name) : + tag_(tag), + type_(type), + name_(name) + { + } + + CYFunctionParameter *Parameters(CYContext &context) const; + CYSelector *Selector(CYContext &context) const; + CYSelectorPart *SelectorPart(CYContext &context) const; +}; + +struct CYMessage : + CYNext +{ + bool instance_; + CYExpression *type_; + CYMessageParameter *parameters_; + CYStatement *statements_; + + CYMessage(bool instance, CYExpression *type, CYMessageParameter *parameter, CYStatement *statements) : + instance_(instance), + type_(type), + parameters_(parameter), + statements_(statements) + { + } + + CYStatement *Replace(CYContext &context, bool replace) const; + void Output(CYOutput &out, bool replace) const; +}; + +struct CYClass { + CYClassName *name_; + CYExpression *super_; + CYField *fields_; + CYMessage *messages_; + + CYClass(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) : + name_(name), + super_(super), + fields_(fields), + messages_(messages) + { + } + + CYExpression *Replace_(CYContext &context); + 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 CYExpression *Replace(CYContext &context); + 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 CYStatement *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYCategory : + CYStatement +{ + CYClassName *name_; + CYMessage *messages_; + + CYCategory(CYClassName *name, CYMessage *messages) : + name_(name), + messages_(messages) + { + } + + virtual CYStatement *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +struct CYSend : + CYExpression +{ + CYExpression *self_; + CYArgument *arguments_; + + CYSend(CYExpression *self, CYArgument *arguments) : + self_(self), + arguments_(arguments) + { + } + + CYPrecedence(0) + + virtual CYExpression *Replace(CYContext &context); + virtual void Output(CYOutput &out, CYFlags flags) const; +}; + +#endif/*CYCRIPT_OBJECTIVEC_HPP*/ diff --git a/ObjectiveC.mm b/ObjectiveC.mm new file mode 100644 index 0000000..1e4e30d --- /dev/null +++ b/ObjectiveC.mm @@ -0,0 +1,220 @@ +#include "Replace.hpp" +#include "ObjectiveC.hpp" + +#include +#include + +void CYCategory::Output(CYOutput &out, CYFlags flags) const { + out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; + out << "$cyp=object_getClass($cys);"; + out << "$cyc=$cys;"; + if (messages_ != NULL) + messages_->Output(out, true); + out << "})("; + name_->ClassName(out, true); + out << ')'; + out << ';'; +} + +void CYClass::Output(CYOutput &out, CYFlags flags) const { + // XXX: I don't necc. need the ()s + out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; + out << "$cyp=object_getClass($cys);"; + out << "$cyc=objc_allocateClassPair($cys,"; + if (name_ != NULL) + name_->ClassName(out, false); + else + out << "$cyq(\"CY$\")"; + out << ",0);"; + out << "$cym=object_getClass($cyc);"; + if (fields_ != NULL) + fields_->Output(out); + if (messages_ != NULL) + messages_->Output(out, false); + out << "objc_registerClassPair($cyc);"; + out << "return $cyc;"; + out << "}("; + if (super_ != NULL) + super_->Output(out, CYPA, CYNoFlags); + else + out << "null"; + 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 CYField::Output(CYOutput &out) const { + // XXX: implement! +} + +void CYMessage::Output(CYOutput &out, bool replace) const { + if (next_ != NULL) + next_->Output(out, replace); + out << "$cyn=new Selector(\""; + for (CYMessageParameter *parameter(parameters_); parameter != NULL; parameter = parameter->next_) + if (parameter->tag_ != NULL) { + out << *parameter->tag_; + if (parameter->name_ != NULL) + out << ':'; + } + out << "\");"; + out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ')' << ';'; + out << (replace ? "class_replaceMethod" : "class_addMethod") << '(' << (instance_ ? "$cyc" : "$cym") << ',' << "$cyn" << ','; + out << "new Functor(function(self,_cmd"; + for (CYMessageParameter *parameter(parameters_); parameter != NULL; parameter = parameter->next_) + if (parameter->name_ != NULL) + out << ',' << *parameter->name_; + out << "){return function(){"; + if (statements_ != NULL) + statements_->Multiple(out); + out << "}.call(self);},$cyt),$cyt);"; +} + +void CYSelector::Output(CYOutput &out, CYFlags flags) const { + out << "@selector" << '(' << name_ << ')'; +} + +void CYSelectorPart::Output(CYOutput &out) const { + out << name_; + if (value_) + out << ':'; + out << next_; +} + +void CYSend::Output(CYOutput &out, CYFlags flags) const { + out << '['; + self_->Output(out, CYPA, CYNoFlags); + out << ']'; + + std::ostringstream name; + for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) + if (argument->name_ != NULL) { + name << *argument->name_; + if (argument->value_ != NULL) + name << ':'; + } + + out.out_ << reinterpret_cast(sel_registerName(name.str().c_str())); + for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) + if (argument->value_ != NULL) { + out << ','; + argument->value_->Output(out, CYPA, CYNoFlags); + } + out << ')'; +} + +CYStatement *CYCategory::Replace(CYContext &context) { + CYVariable *cyc($V("$cyc")), *cys($V("$cys")); + + return $E($C1($F(NULL, $P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$->* + $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* + $E($ CYAssign(cyc, cys))->* + messages_->Replace(context, true) + ), name_->ClassName(context, true))); +} + +CYExpression *CYClass::Replace_(CYContext &context) { + CYVariable *cyc($V("$cyc")), *cys($V("$cys")); + + CYExpression *name(name_ != NULL ? name_->ClassName(context, false) : $C1($V("$cyq"), $S("CY$"))); + + return $C1($F(NULL, $P6("$cys", "$cyp", "$cyc", "$cyn", "$cyt", "$cym"), $$->* + $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* + $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->* + $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->* + fields_->Replace(context)->* + messages_->Replace(context, false)->* + $E($C1($V("objc_registerClassPair"), cyc))->* + $ CYReturn(cyc) + ), super_ == NULL ? $ CYNull() : super_); +} + +CYExpression *CYClassExpression::Replace(CYContext &context) { + return Replace_(context); +} + +CYStatement *CYClassStatement::Replace(CYContext &context) { + return $E(Replace_(context)); +} + +CYStatement *CYField::Replace(CYContext &context) const { + return NULL; +} + +CYStatement *CYMessage::Replace(CYContext &context, bool replace) const { $T(NULL) + CYVariable *cyn($V("$cyn")); + CYVariable *cyt($V("$cyt")); + + return $ CYBlock($$->* + next_->Replace(context, replace)->* + $E($ CYAssign(cyn, parameters_->Selector(context)))->* + $E($ CYAssign(cyt, $C1($M(cyn, $S("type")), $V(instance_ ? "$cys" : "$cyp"))))->* + $E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"), + $V(instance_ ? "$cyc" : "$cym"), + cyn, + $N2($V("Functor"), $F(NULL, $P2("self", "_cmd", parameters_->Parameters(context)), $$->* + $ CYReturn($C1($M($F(NULL, NULL, statements_), $S("call")), $V("self"))) + ), cyt), + cyt + )) + ); +} + +CYFunctionParameter *CYMessageParameter::Parameters(CYContext &context) const { $T(NULL) + CYFunctionParameter *next(next_->Parameters(context)); + return name_ == NULL ? next : $ CYFunctionParameter(name_, next); +} + +CYSelector *CYMessageParameter::Selector(CYContext &context) const { + return $ CYSelector(SelectorPart(context)); +} + +CYSelectorPart *CYMessageParameter::SelectorPart(CYContext &context) const { $T(NULL) + CYSelectorPart *next(next_->SelectorPart(context)); + return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next); +} + +CYExpression *CYSelector::Replace(CYContext &context) { + return $N1($V("Selector"), name_->Replace(context)); +} + +CYString *CYSelectorPart::Replace(CYContext &context) { + std::ostringstream str; + for (const CYSelectorPart *part(this); part != NULL; part = part->next_) { + if (part->name_ != NULL) + str << part->name_->Value(); + if (part->value_) + str << ':'; + } + return $S(apr_pstrdup(context.pool_, str.str().c_str())); +} + +CYExpression *CYSend::Replace(CYContext &context) { + std::ostringstream name; + CYArgument **argument(&arguments_); + + while (*argument != NULL) { + if ((*argument)->name_ != NULL) { + name << *(*argument)->name_; + (*argument)->name_ = NULL; + if ((*argument)->value_ != NULL) + name << ':'; + } + + if ((*argument)->value_ == NULL) + *argument = (*argument)->next_; + else + argument = &(*argument)->next_; + } + + SEL sel(sel_registerName(name.str().c_str())); + double address(static_cast(reinterpret_cast(sel))); + + return $C2($V("objc_msgSend"), self_, $D(address), arguments_); +} diff --git a/Output.cpp b/Output.cpp index efbf55b..dec2df5 100644 --- a/Output.cpp +++ b/Output.cpp @@ -1,9 +1,6 @@ #include "Parser.hpp" -#include #include - -#include #include _finline CYFlags operator ~(CYFlags rhs) { @@ -34,8 +31,6 @@ _finline CYFlags CYCenter(CYFlags flags) { return CYLeft(CYRight(flags)); } -#define CYPA 16 - void CYOutput::Terminate() { out_ << ';'; mode_ = NoMode; @@ -197,51 +192,6 @@ void CYCatch::Output(CYOutput &out) const { out << ' ' << "catch" << ' ' << '(' << *name_ << ')' << ' ' << code_; } -void CYCategory::Output(CYOutput &out, CYFlags flags) const { - out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; - out << "$cyp=object_getClass($cys);"; - out << "$cyc=$cys;"; - if (messages_ != NULL) - messages_->Output(out, true); - out << "})("; - name_->ClassName(out, true); - out << ')'; - out << ';'; -} - -void CYClass::Output(CYOutput &out, CYFlags flags) const { - // XXX: I don't necc. need the ()s - out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; - out << "$cyp=object_getClass($cys);"; - out << "$cyc=objc_allocateClassPair($cys,"; - if (name_ != NULL) - name_->ClassName(out, false); - else - out << "$cyq(\"CY$\")"; - out << ",0);"; - out << "$cym=object_getClass($cyc);"; - if (fields_ != NULL) - fields_->Output(out); - if (messages_ != NULL) - messages_->Output(out, false); - out << "objc_registerClassPair($cyc);"; - out << "return $cyc;"; - out << "}("; - if (super_ != NULL) - super_->Output(out, CYPA, CYNoFlags); - else - out << "null"; - 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_) { @@ -402,10 +352,6 @@ void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) con Output(out, flags); } -void CYField::Output(CYOutput &out) const { - // XXX: implement! -} - void CYFinally::Output(CYOutput &out) const { out << ' ' << "finally" << ' ' << code_; } @@ -557,29 +503,6 @@ void CYLet::Output(CYOutput &out, CYFlags flags) const { out << "let" << ' ' << '(' << *declarations_ << ')' << ' ' << code_; } -void CYMessage::Output(CYOutput &out, bool replace) const { - if (next_ != NULL) - next_->Output(out, replace); - out << "$cyn=new Selector(\""; - for (CYMessageParameter *parameter(parameters_); parameter != NULL; parameter = parameter->next_) - if (parameter->tag_ != NULL) { - out << *parameter->tag_; - if (parameter->name_ != NULL) - out << ':'; - } - out << "\");"; - out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ')' << ';'; - out << (replace ? "class_replaceMethod" : "class_addMethod") << '(' << (instance_ ? "$cyc" : "$cym") << ',' << "$cyn" << ','; - out << "new Functor(function(self,_cmd"; - for (CYMessageParameter *parameter(parameters_); parameter != NULL; parameter = parameter->next_) - if (parameter->name_ != NULL) - out << ',' << *parameter->name_; - out << "){return function(){"; - if (statements_ != NULL) - statements_->Multiple(out); - out << "}.call(self);},$cyt),$cyt);"; -} - void CYNew::Output(CYOutput &out, CYFlags flags) const { out << "new" << ' '; CYFlags jacks(CYNoCall | CYCenter(flags)); @@ -655,39 +578,6 @@ void CYReturn::Output(CYOutput &out, CYFlags flags) const { out << ';'; } -void CYSelector::Output(CYOutput &out, CYFlags flags) const { - out << "@selector" << '(' << name_ << ')'; -} - -void CYSelectorPart::Output(CYOutput &out) const { - out << name_; - if (value_) - out << ':'; - out << next_; -} - -void CYSend::Output(CYOutput &out, CYFlags flags) const { - out << '['; - self_->Output(out, CYPA, CYNoFlags); - out << ']'; - - std::ostringstream name; - for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) - if (argument->name_ != NULL) { - name << *argument->name_; - if (argument->value_ != NULL) - name << ':'; - } - - out.out_ << reinterpret_cast(sel_registerName(name.str().c_str())); - for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) - if (argument->value_ != NULL) { - out << ','; - argument->value_->Output(out, CYPA, CYNoFlags); - } - out << ')'; -} - void CYStatement::Multiple(CYOutput &out, CYFlags flags) const { bool first(true); for (const CYStatement *next(this); next != NULL; next = next->next_) { diff --git a/Parser.hpp b/Parser.hpp index e954748..4fe121e 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -40,10 +40,16 @@ #ifndef CYPARSER_HPP #define CYPARSER_HPP -#include +// XXX: wtf is this here?! +#define CYPA 16 + +#include + #include #include +#include + #include "location.hh" #include "Pooling.hpp" @@ -616,40 +622,6 @@ struct CYString : virtual void PropertyName(CYOutput &out) const; }; -struct CYSelectorPart : - CYNext, - CYThing -{ - CYWord *name_; - bool value_; - - CYSelectorPart(CYWord *name, bool value, CYSelectorPart *next) : - CYNext(next), - name_(name), - value_(value) - { - } - - CYString *Replace(CYContext &context); - virtual void Output(CYOutput &out) const; -}; - -struct CYSelector : - CYLiteral -{ - CYSelectorPart *name_; - - CYSelector(CYSelectorPart *name) : - name_(name) - { - } - - CYPrecedence(1) - - virtual CYExpression *Replace(CYContext &context); - virtual void Output(CYOutput &out, CYFlags flags) const; -}; - struct CYNumber : CYTrivial, CYPropertyName @@ -841,6 +813,8 @@ struct CYAssignment : virtual const char *Operator() const = 0; + CYPrecedence(16) + virtual CYExpression *Replace(CYContext &context); virtual void Output(CYOutput &out, CYFlags flags) const; }; @@ -1000,114 +974,6 @@ struct CYLet : virtual void Output(CYOutput &out, CYFlags flags) const; }; -struct CYField : - CYNext -{ - CYStatement *Replace(CYContext &context) const; - void Output(CYOutput &out) const; -}; - -struct CYMessageParameter : - CYNext -{ - CYWord *tag_; - CYExpression *type_; - CYIdentifier *name_; - - CYMessageParameter(CYWord *tag, CYExpression *type, CYIdentifier *name) : - tag_(tag), - type_(type), - name_(name) - { - } - - CYFunctionParameter *Parameters(CYContext &context) const; - CYSelector *Selector(CYContext &context) const; - CYSelectorPart *SelectorPart(CYContext &context) const; -}; - -struct CYMessage : - CYNext -{ - bool instance_; - CYExpression *type_; - CYMessageParameter *parameters_; - CYStatement *statements_; - - CYMessage(bool instance, CYExpression *type, CYMessageParameter *parameter, CYStatement *statements) : - instance_(instance), - type_(type), - parameters_(parameter), - statements_(statements) - { - } - - CYStatement *Replace(CYContext &context, bool replace) const; - void Output(CYOutput &out, bool replace) const; -}; - -struct CYClass { - CYClassName *name_; - CYExpression *super_; - CYField *fields_; - CYMessage *messages_; - - CYClass(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) : - name_(name), - super_(super), - fields_(fields), - messages_(messages) - { - } - - CYExpression *Replace_(CYContext &context); - 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 CYExpression *Replace(CYContext &context); - 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 CYStatement *Replace(CYContext &context); - virtual void Output(CYOutput &out, CYFlags flags) const; -}; - -struct CYCategory : - CYStatement -{ - CYClassName *name_; - CYMessage *messages_; - - CYCategory(CYClassName *name, CYMessage *messages) : - name_(name), - messages_(messages) - { - } - - virtual CYStatement *Replace(CYContext &context); - virtual void Output(CYOutput &out, CYFlags flags) const; -}; - struct CYFor : CYStatement { @@ -1212,24 +1078,6 @@ struct CYCatch : virtual void Output(CYOutput &out) const; }; -struct CYSend : - CYExpression -{ - CYExpression *self_; - CYArgument *arguments_; - - CYSend(CYExpression *self, CYArgument *arguments) : - self_(self), - arguments_(arguments) - { - } - - CYPrecedence(0) - - virtual CYExpression *Replace(CYContext &context); - virtual void Output(CYOutput &out, CYFlags flags) const; -}; - struct CYMember : CYExpression { @@ -1665,8 +1513,6 @@ struct CYIndirect : CYAssignment(lhs, rhs) \ { \ } \ - \ - CYPrecedence(16) \ \ virtual const char *Operator() const { \ return op; \ diff --git a/Replace.cpp b/Replace.cpp index 7d861c9..987122b 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -1,95 +1,8 @@ #include "Parser.hpp" -#include #include -#include -#include - -#define $ \ - new(context.pool_) - -#define $D(args...) \ - ($ CYNumber(args)) -#define $E(args...) \ - ($ CYExpress(args)) -#define $F(args...) \ - ($ CYFunctionExpression(args)) -#define $I(args...) \ - ($ CYIdentifier(args)) -#define $M(args...) \ - ($ CYDirectMember(args)) -#define $P(args...) \ - ($ CYFunctionParameter(args)) -#define $S(args...) \ - ($ CYString(args)) -#define $V(name) \ - ($ CYVariable($I(name))) - -#define $T(value) \ - if (this == NULL) \ - return value; -#define $$ \ - CYStatements() - -#define $P1(arg0, args...) \ - $P($I(arg0), ##args) -#define $P2(arg0, arg1, args...) \ - $P($I(arg0), $P1(arg1, ##args)) -#define $P3(arg0, arg1, arg2, args...) \ - $P($I(arg0), $P2(arg1, arg2, ##args)) -#define $P4(arg0, arg1, arg2, arg3, args...) \ - $P($I(arg0), $P3(arg1, arg2, arg3, ##args)) -#define $P5(arg0, arg1, arg2, arg3, arg4, args...) \ - $P($I(arg0), $P4(arg1, arg2, arg3, arg4, ##args)) -#define $P6(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ - $P($I(arg0), $P5(arg1, arg2, arg3, arg4, arg5, ##args)) - -#define $C(args...) \ - ($ CYCall(args)) -#define $C_(args...) \ - ($ CYArgument(args)) -#define $N(args...) \ - ($ CYNew(args)) - -#define $C1_(arg0, args...) \ - $C_(arg0, ##args) -#define $C2_(arg0, arg1, args...) \ - $C_(arg0, $C1_(arg1, ##args)) -#define $C3_(arg0, arg1, arg2, args...) \ - $C_(arg0, $C2_(arg1, arg2, ##args)) -#define $C4_(arg0, arg1, arg2, arg3, args...) \ - $C_(arg0, $C3_(arg1, arg2, arg3, ##args)) -#define $C5_(arg0, arg1, arg2, arg3, arg4, args...) \ - $C_(arg0, $C4_(arg1, arg2, arg3, arg4, ##args)) -#define $C6_(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ - $C_(arg0, $C5_(arg1, arg2, arg3, arg4, arg5, ##args)) - -#define $C0(func, args...) \ - $C(func, ##args) -#define $C1(func, args...) \ - $C(func, $C1_(args)) -#define $C2(func, args...) \ - $C(func, $C2_(args)) -#define $C3(func, args...) \ - $C(func, $C3_(args)) -#define $C4(func, args...) \ - $C(func, $C4_(args)) -#define $C5(func, args...) \ - $C(func, $C5_(args)) - -#define $N0(func, args...) \ - $N(func, ##args) -#define $N1(func, args...) \ - $N(func, $C1_(args)) -#define $N2(func, args...) \ - $N(func, $C2_(args)) -#define $N3(func, args...) \ - $N(func, $C3_(args)) -#define $N4(func, args...) \ - $N(func, $C4_(args)) -#define $N5(func, args...) \ - $N(func, $C5_(args)) +#include "Replace.hpp" CYExpression *CYAddressOf::Replace(CYContext &context) { CYPrefix::Replace(context); @@ -141,40 +54,6 @@ void CYCatch::Replace(CYContext &context) { $T() code_.Replace(context); } -CYStatement *CYCategory::Replace(CYContext &context) { - CYVariable *cyc($V("$cyc")), *cys($V("$cys")); - - return $E($C1($F(NULL, $P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$->* - $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* - $E($ CYAssign(cyc, cys))->* - messages_->Replace(context, true) - ), name_->ClassName(context, true))); -} - -CYExpression *CYClass::Replace_(CYContext &context) { - CYVariable *cyc($V("$cyc")), *cys($V("$cys")); - - CYExpression *name(name_ != NULL ? name_->ClassName(context, false) : $C1($V("$cyq"), $S("CY$"))); - - return $C1($F(NULL, $P6("$cys", "$cyp", "$cyc", "$cyn", "$cyt", "$cym"), $$->* - $E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->* - $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->* - $E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->* - fields_->Replace(context)->* - messages_->Replace(context, false)->* - $E($C1($V("objc_registerClassPair"), cyc))->* - $ CYReturn(cyc) - ), super_ == NULL ? $ CYNull() : super_); -} - -CYExpression *CYClassExpression::Replace(CYContext &context) { - return Replace_(context); -} - -CYStatement *CYClassStatement::Replace(CYContext &context) { - return $E(Replace_(context)); -} - void CYClause::Replace(CYContext &context) { $T() context.Replace(case_); statements_ = statements_->ReplaceAll(context); @@ -268,10 +147,6 @@ CYExpression *CYExpression::ReplaceAll(CYContext &context) { $T(NULL) return replace; } -CYStatement *CYField::Replace(CYContext &context) const { - return NULL; -} - void CYFinally::Replace(CYContext &context) { $T() code_.Replace(context); } @@ -382,39 +257,6 @@ void CYMember::Replace_(CYContext &context) { context.Replace(property_); } -CYStatement *CYMessage::Replace(CYContext &context, bool replace) const { $T(NULL) - CYVariable *cyn($V("$cyn")); - CYVariable *cyt($V("$cyt")); - - return $ CYBlock($$->* - next_->Replace(context, replace)->* - $E($ CYAssign(cyn, parameters_->Selector(context)))->* - $E($ CYAssign(cyt, $C1($M(cyn, $S("type")), $V(instance_ ? "$cys" : "$cyp"))))->* - $E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"), - $V(instance_ ? "$cyc" : "$cym"), - cyn, - $N2($V("Functor"), $F(NULL, $P2("self", "_cmd", parameters_->Parameters(context)), $$->* - $ CYReturn($C1($M($F(NULL, NULL, statements_), $S("call")), $V("self"))) - ), cyt), - cyt - )) - ); -} - -CYFunctionParameter *CYMessageParameter::Parameters(CYContext &context) const { $T(NULL) - CYFunctionParameter *next(next_->Parameters(context)); - return name_ == NULL ? next : $ CYFunctionParameter(name_, next); -} - -CYSelector *CYMessageParameter::Selector(CYContext &context) const { - return $ CYSelector(SelectorPart(context)); -} - -CYSelectorPart *CYMessageParameter::SelectorPart(CYContext &context) const { $T(NULL) - CYSelectorPart *next(next_->SelectorPart(context)); - return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next); -} - CYExpression *CYNew::Replace(CYContext &context) { context.Replace(constructor_); arguments_->Replace(context); @@ -450,45 +292,6 @@ CYStatement *CYReturn::Replace(CYContext &context) { return NULL; } -CYExpression *CYSelector::Replace(CYContext &context) { - return $N1($V("Selector"), name_->Replace(context)); -} - -CYExpression *CYSend::Replace(CYContext &context) { - std::ostringstream name; - CYArgument **argument(&arguments_); - - while (*argument != NULL) { - if ((*argument)->name_ != NULL) { - name << *(*argument)->name_; - (*argument)->name_ = NULL; - if ((*argument)->value_ != NULL) - name << ':'; - } - - if ((*argument)->value_ == NULL) - *argument = (*argument)->next_; - else - argument = &(*argument)->next_; - } - - SEL sel(sel_registerName(name.str().c_str())); - double address(static_cast(reinterpret_cast(sel))); - - return $C2($V("objc_msgSend"), self_, $D(address), arguments_); -} - -CYString *CYSelectorPart::Replace(CYContext &context) { - std::ostringstream str; - for (const CYSelectorPart *part(this); part != NULL; part = part->next_) { - if (part->name_ != NULL) - str << part->name_->Value(); - if (part->value_) - str << ':'; - } - return $S(apr_pstrdup(context.pool_, str.str().c_str())); -} - CYStatement *CYStatement::ReplaceAll(CYContext &context) { $T(NULL) CYStatement *replace(this); context.Replace(replace); diff --git a/Replace.hpp b/Replace.hpp new file mode 100644 index 0000000..de3c33a --- /dev/null +++ b/Replace.hpp @@ -0,0 +1,91 @@ +#ifndef REPLACE_HPP +#define REPLACE_HPP + +#include "Parser.hpp" + +#define $ \ + new(context.pool_) + +#define $D(args...) \ + ($ CYNumber(args)) +#define $E(args...) \ + ($ CYExpress(args)) +#define $F(args...) \ + ($ CYFunctionExpression(args)) +#define $I(args...) \ + ($ CYIdentifier(args)) +#define $M(args...) \ + ($ CYDirectMember(args)) +#define $P(args...) \ + ($ CYFunctionParameter(args)) +#define $S(args...) \ + ($ CYString(args)) +#define $V(name) \ + ($ CYVariable($I(name))) + +#define $T(value) \ + if (this == NULL) \ + return value; +#define $$ \ + CYStatements() + +#define $P1(arg0, args...) \ + $P($I(arg0), ##args) +#define $P2(arg0, arg1, args...) \ + $P($I(arg0), $P1(arg1, ##args)) +#define $P3(arg0, arg1, arg2, args...) \ + $P($I(arg0), $P2(arg1, arg2, ##args)) +#define $P4(arg0, arg1, arg2, arg3, args...) \ + $P($I(arg0), $P3(arg1, arg2, arg3, ##args)) +#define $P5(arg0, arg1, arg2, arg3, arg4, args...) \ + $P($I(arg0), $P4(arg1, arg2, arg3, arg4, ##args)) +#define $P6(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ + $P($I(arg0), $P5(arg1, arg2, arg3, arg4, arg5, ##args)) + +#define $C(args...) \ + ($ CYCall(args)) +#define $C_(args...) \ + ($ CYArgument(args)) +#define $N(args...) \ + ($ CYNew(args)) + +#define $C1_(arg0, args...) \ + $C_(arg0, ##args) +#define $C2_(arg0, arg1, args...) \ + $C_(arg0, $C1_(arg1, ##args)) +#define $C3_(arg0, arg1, arg2, args...) \ + $C_(arg0, $C2_(arg1, arg2, ##args)) +#define $C4_(arg0, arg1, arg2, arg3, args...) \ + $C_(arg0, $C3_(arg1, arg2, arg3, ##args)) +#define $C5_(arg0, arg1, arg2, arg3, arg4, args...) \ + $C_(arg0, $C4_(arg1, arg2, arg3, arg4, ##args)) +#define $C6_(arg0, arg1, arg2, arg3, arg4, arg5, args...) \ + $C_(arg0, $C5_(arg1, arg2, arg3, arg4, arg5, ##args)) + +#define $C0(func, args...) \ + $C(func, ##args) +#define $C1(func, args...) \ + $C(func, $C1_(args)) +#define $C2(func, args...) \ + $C(func, $C2_(args)) +#define $C3(func, args...) \ + $C(func, $C3_(args)) +#define $C4(func, args...) \ + $C(func, $C4_(args)) +#define $C5(func, args...) \ + $C(func, $C5_(args)) + +#define $N0(func, args...) \ + $N(func, ##args) +#define $N1(func, args...) \ + $N(func, $C1_(args)) +#define $N2(func, args...) \ + $N(func, $C2_(args)) +#define $N3(func, args...) \ + $N(func, $C3_(args)) +#define $N4(func, args...) \ + $N(func, $C4_(args)) +#define $N5(func, args...) \ + $N(func, $C5_(args)) + +#endif/*REPLACE_HPP*/ diff --git a/makefile b/makefile index a01b046..99ef08d 100644 --- a/makefile +++ b/makefile @@ -4,12 +4,14 @@ else target := $(PKG_TARG)- endif -#flags := -g3 -O0 -DYYDEBUG=1 -flags := -g0 -O3 +flags := -g3 -O0 -DYYDEBUG=1 +#flags := -g0 -O3 flags += -Wall -Werror -I. -fno-common svn := $(shell svnversion) +filters := C + all: all := libcycript.plist cycript @@ -19,6 +21,7 @@ arch := $(shell $(dpkg_architecture) -qDEB_HOST_ARCH 2>/dev/null) endif header := Cycript.tab.hh Parser.hpp Pooling.hpp cycript.hpp +code := ffi_type.o parse.o Replace.o Output.o Cycript.tab.o lex.cy.o Library.o dll := so @@ -72,6 +75,9 @@ libcycript.plist: Bridge.def echo '})'; \ } >$@ +Cycript.y: Cycript.y.in + ./Filter.sh <$< >$@ $(filters) + Cycript.tab.cc Cycript.tab.hh location.hh position.hh: Cycript.y bison -v --report=state $< @@ -102,7 +108,7 @@ cyrver: Server.o -framework CoreFoundation -framework CFNetwork ldid -S $@ -libcycript.$(dll): ffi_type.o parse.o Replace.o Output.o Cycript.tab.o lex.cy.o Library.o +libcycript.$(dll): $(code) $(target)g++ $(flags) -dynamiclib -o $@ $(filter %.o,$^) \ -install_name /usr/lib/libcycript.dylib \ -lobjc -lapr-1 -lffi -lsubstrate \ -- 2.45.2