]> git.saurik.com Git - cycript.git/commitdiff
Allow extern "C" {} and limit semicolon insertion.
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 20 Dec 2015 12:21:23 +0000 (04:21 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 20 Dec 2015 12:21:23 +0000 (04:21 -0800)
Output.cpp
Parser.ypp.in

index 6610ff20ac4ddc9b8b6d98af3e946e30bf4eab88..d3da0e46fa0564f386acbd333b64451f23bd76ba 100644 (file)
@@ -364,7 +364,8 @@ void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
 }
 
 void CYExternal::Output(CYOutput &out, CYFlags flags) const {
-    out << "extern" << abi_ << typed_ << ';';
+    out << "extern" << abi_ << typed_;
+    out.Terminate();
 }
 
 void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
@@ -638,6 +639,7 @@ void CYLambda::Output(CYOutput &out, CYFlags flags) const {
 
 void CYTypeDefinition::Output(CYOutput &out, CYFlags flags) const {
     out << "typedef" << ' ' << *typed_;
+    out.Terminate();
 }
 
 void CYTypeExpression::Output(CYOutput &out, CYFlags flags) const {
index 88c01bfcd47392c0a31d74543c92ef0a1270ea3b..e1c23685d00e8cfd463583d89d33416e27d61cdd 100644 (file)
@@ -524,6 +524,9 @@ type; })
 %type <expression_> ExpressionOpt
 %type <for_> ExpressionStatement_
 %type <statement_> ExpressionStatement
+%type <statement_> ExternC
+%type <statement_> ExternCStatement
+%type <statement_> ExternCStatementListOpt
 %type <finally_> Finally
 %type <binding_> ForBinding
 %type <forin_> ForDeclaration
@@ -613,6 +616,7 @@ type; })
 %type <span_> TemplateSpans
 %type <statement_> ThrowStatement
 %type <statement_> TryStatement
+%type <statement_> TypeDefinition
 %type <expression_> UnaryExpression_
 %type <expression_> UnaryExpression
 %type <binding_> VariableDeclaration
@@ -865,6 +869,11 @@ TerminatorSoft
     | NewLineNot LexOf Terminator
     ;
 
+TerminatorHard
+    : ";"
+    | error { if (yyla.type_get() != yyeof_) CYERR(@error, "required semi-colon"); else CYEOK(); } StrictSemi
+    ;
+
 Terminator
     : ";"
     | error { if (yyla.type_get() != yyeof_ && yyla.type != yytranslate_(token::CloseBrace) && !driver.newline_) CYERR(@error, "required semi-colon"); else CYEOK(); } StrictSemi
@@ -1378,7 +1387,7 @@ Block
     ;
 
 StatementList
-    : StatementListItem[statement] StatementListOpt[next] { $statement->SetNext($next); $$ = $statement; }
+    : StatementListItem[statement] StatementListOpt[next] { $$ = $statement; CYSetLast($$) = $next; }
     ;
 
 StatementListOpt
@@ -2264,8 +2273,12 @@ IdentifierNoOf
     : "typedef" NewLineOpt { $$ = CYNew CYIdentifier("typedef"); }
     ;
 
+TypeDefinition
+    : "typedef" NewLineNot TypedIdentifierYes[typed] TerminatorHard { $$ = CYNew CYTypeDefinition($typed); }
+    ;
+
 Statement__
-    : "typedef" NewLineNot TypedIdentifierYes[typed] Terminator { $$ = CYNew CYTypeDefinition($typed); }
+    : TypeDefinition[pass] { $$ = $pass; }
     ;
 
 PrimaryExpression
@@ -2277,8 +2290,23 @@ IdentifierNoOf
     : "extern" NewLineOpt { $$ = CYNew CYIdentifier("extern"); }
     ;
 
+ExternCStatement
+    : TypedIdentifierYes[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
+    | TypeDefinition[pass] { $$ = $pass; }
+    ;
+
+ExternCStatementListOpt
+    : ExternCStatement[statement] ExternCStatementListOpt[next] { $$ = $statement; CYSetLast($$) = $next; }
+    | { $$ = NULL; }
+    ;
+
+ExternC
+    : "{" ExternCStatementListOpt[pass] "}" { $$ = $pass; }
+    | ExternCStatement[pass] { $$ = $pass; }
+    ;
+
 Statement__
-    : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } TypedIdentifierYes[typed] Terminator { $$ = CYNew CYExternal($abi, $typed); }
+    : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; }
     ;
 /* }}} */