]> git.saurik.com Git - cycript.git/commitdiff
Support extern "C" syntax to FFI via C prototypes.
authorJay Freeman (saurik) <saurik@saurik.com>
Fri, 31 Oct 2014 09:50:48 +0000 (02:50 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Fri, 31 Oct 2014 09:50:48 +0000 (02:50 -0700)
Cycript.l.in
Cycript.yy.in
Output.cpp
Parser.hpp
Replace.cpp

index 7ee7d60ab6419032f2206b81c8109dcde3635a86..ab5d0b3882dbf02e8a208de2ad63a197005b554b 100644 (file)
@@ -272,6 +272,7 @@ XMLName {XMLNameStart}{XMLNamePart}*
 "typedef"         L C I(identifier, Identifier("typedef"), tk::Typedef, hi::Meta);
 "unsigned"        L C I(identifier, Identifier("unsigned"), tk::Unsigned, hi::Type);
 "signed"          L C I(identifier, Identifier("signed"), tk::Signed, hi::Type);
 "typedef"         L C I(identifier, Identifier("typedef"), tk::Typedef, hi::Meta);
 "unsigned"        L C I(identifier, Identifier("unsigned"), tk::Unsigned, hi::Type);
 "signed"          L C I(identifier, Identifier("signed"), tk::Signed, hi::Type);
+"extern"          L C I(identifier, Identifier("extern"), tk::Extern, hi::Type);
 @end
 
 @begin C
 @end
 
 @begin C
index 3ad89f82c74c37c9c50e97318083d10039ad94ba..b2f56299b09274dee2fae9221cb7cb3c6c31fffd 100644 (file)
@@ -245,6 +245,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %token <identifier_> Typedef "typedef"
 %token <identifier_> Unsigned "unsigned"
 %token <identifier_> Signed "signed"
 %token <identifier_> Typedef "typedef"
 %token <identifier_> Unsigned "unsigned"
 %token <identifier_> Signed "signed"
+%token <identifier_> Extern "extern"
 @end
 
 @begin C
 @end
 
 @begin C
@@ -718,6 +719,7 @@ Identifier
     | "typedef" { $$ = $1; }
     | "unsigned" { $$ = $1; }
     | "signed" { $$ = $1; }
     | "typedef" { $$ = $1; }
     | "unsigned" { $$ = $1; }
     | "signed" { $$ = $1; }
+    | "extern" { $$ = $1; }
 @end
 @begin ObjectiveC
     | "YES" { $$ = $1; }
 @end
 @begin ObjectiveC
     | "YES" { $$ = $1; }
@@ -1434,6 +1436,7 @@ SuffixedType
     : ArrayedType { $$ = $1; }
     | "(" LexPushInOff "^" TypeQualifierRight ")" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn { $$ = $4; $$->modifier_ = CYNew CYTypeBlockWith($9, $$->modifier_); }
     | TypeParenthetical FunctionedType { $$ = $1; CYSetLast($2) = $$->modifier_; $$->modifier_ = $2; }
     : ArrayedType { $$ = $1; }
     | "(" LexPushInOff "^" TypeQualifierRight ")" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn { $$ = $4; $$->modifier_ = CYNew CYTypeBlockWith($9, $$->modifier_); }
     | TypeParenthetical FunctionedType { $$ = $1; CYSetLast($2) = $$->modifier_; $$->modifier_ = $2; }
+    | IdentifierType FunctionedType { $$ = CYNew CYTypedIdentifier($1); CYSetLast($2) = $$->modifier_; $$->modifier_ = $2; }
     | FunctionedType { $$ = CYNew CYTypedIdentifier(); CYSetLast($1) = $$->modifier_; $$->modifier_ = $1; }
     ;
 
     | FunctionedType { $$ = CYNew CYTypedIdentifier(); CYSetLast($1) = $$->modifier_; $$->modifier_ = $1; }
     ;
 
@@ -1730,9 +1733,15 @@ PrimaryExpression
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
 Statement__
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
 Statement__
-    : "typedef" TypedIdentifier Terminator { $$ = CYNew CYTypeDefinition($2); }
+    : "typedef" TypedIdentifier { if ($2->identifier_ == NULL) YYABORT; } Terminator { $$ = CYNew CYTypeDefinition($2); }
     ;
 /* }}} */
     ;
 /* }}} */
+/* Cycript (C): extern "C" {{{ */
+Statement__
+    : "extern" StringLiteral { if (strcmp($2->Value(), "C") != 0) YYABORT; } TypedIdentifier Terminator { $$ = CYNew CYExternal($2, $4); }
+    ;
+/* }}} */
+
 @end
 
 /* YUI: Documentation Comments {{{ */
 @end
 
 /* YUI: Documentation Comments {{{ */
index 4c4376a7fd549f0d03281f7aa7235fb2b96b544c..467825cfdfeeaf5230cca96495752b45d3aea769 100644 (file)
@@ -329,6 +329,10 @@ void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
         Output(out, flags);
 }
 
         Output(out, flags);
 }
 
+void CYExternal::Output(CYOutput &out, CYFlags flags) const {
+    out << "extern" << abi_ << typed_ << ';';
+}
+
 void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
     out << '(' << parameters_ << ')' << ' ' << "=>" << ' ' << code_;
 }
 void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
     out << '(' << parameters_ << ')' << ' ' << "=>" << ' ' << code_;
 }
index 697fbeac73fbdf013e62032e896b8f23f6002d0e..63270a18a331fe897d44a4d6bd13409e63939120 100644 (file)
@@ -1881,6 +1881,22 @@ struct CYImport :
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
+struct CYExternal :
+    CYStatement
+{
+    CYString *abi_;
+    CYTypedIdentifier *typed_;
+
+    CYExternal(CYString *abi, CYTypedIdentifier *typed) :
+        abi_(abi),
+        typed_(typed)
+    {
+    }
+
+    virtual CYStatement *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 struct CYTypeDefinition :
     CYStatement
 {
 struct CYTypeDefinition :
     CYStatement
 {
index b3d1c828e972983caf9eceb549956a1008150d01..f6d904c199a378e6ee090235298090f962868a70 100644 (file)
@@ -327,6 +327,10 @@ CYAssignment *CYExpression::Assignment(CYContext &context) {
     return NULL;
 }
 
     return NULL;
 }
 
+CYStatement *CYExternal::Replace(CYContext &context) {
+    return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
+}
+
 CYNumber *CYFalse::Number(CYContext &context) {
     return $D(0);
 }
 CYNumber *CYFalse::Number(CYContext &context) {
     return $D(0);
 }