]> git.saurik.com Git - cycript.git/blobdiff - Cycript.yy.in
Implemented initial support for Ruby Blocks.
[cycript.git] / Cycript.yy.in
index ece104fd8ce5a669491b900cb7eaecbc0718abfa..53a6336467debbc178d5c580e589ca95439a7c14 100644 (file)
 */
 /* }}} */
 
-%{
+@if Bison23 %{
+
+@if Bison24 %code top {
 #define cyscanner driver.scanner_
 #define YYSTACKEXPANDABLE 1
-#define yyerrok (yyerrstatus_ = 0)
-%}
+@if Bison23 #define yyerrok (yyerrstatus_ = 0)
+@if Bison24 }
 
-%{
+@if Bison24 %code requires {
 #include "Parser.hpp"
 
 @begin ObjectiveC
@@ -88,6 +90,7 @@ typedef struct {
         CYProgram *program_;
         CYProperty *property_;
         CYPropertyName *propertyName_;
+        CYRubyProc *rubyProc_;
         CYStatement *statement_;
         CYString *string_;
         CYThis *this_;
@@ -112,22 +115,24 @@ typedef struct {
 } YYSTYPE;
 
 #define YYSTYPE YYSTYPE
+@if Bison24 }
 
-%}
-
-%{
+@if Bison24 %code provides {
 int cylex(YYSTYPE *, cy::location *, void *);
-%}
+@if Bison24 }
+
+@if Bison23 %}
 
 %name-prefix="cy"
 
-%skeleton "lalr1.cc"
-%locations
+@if Bison23 %skeleton "lalr1.cc"
+@if Bison24 %language "C++"
 
 %initial-action {
     @$.begin.filename = @$.end.filename = &driver.filename_;
 };
 
+%locations
 %defines
 
 //%glr-parser
@@ -219,6 +224,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %token CloseParen ")"
 
 %token OpenBrace "{"
+%token OpenBrace_ "\n{"
 %token CloseBrace "}"
 
 %token OpenBracket "["
@@ -313,6 +319,8 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %token <identifier_> XML "xml"
 @end
 
+%token AutoComplete
+
 %token <identifier_> Identifier_
 %token <number_> NumericLiteral
 %token <string_> StringLiteral
@@ -438,6 +446,10 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <expression_> RelationalExpressionNoIn
 %type <infix_> RelationalExpressionNoIn_
 %type <statement_> ReturnStatement
+%type <rubyProc_> RubyProcExpression
+%type <functionParameter_> RubyProcParameterList
+%type <functionParameter_> RubyProcParameterList_
+%type <functionParameter_> RubyProcParametersOpt
 %type <expression_> ShiftExpression
 %type <expression_> ShiftExpressionNoBF
 %type <statement_> SourceElement
@@ -499,6 +511,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <selector_> SelectorExpression_
 %type <selector_> SelectorExpressionOpt
 %type <argument_> SelectorList
+%type <word_> SelectorWordOpt
 %type <expression_> TypeOpt
 %type <argument_> VariadicCall
 %type <word_> Word
@@ -557,6 +570,11 @@ LexSetRegExp
     ;
 /* }}} */
 
+Brace
+    : "{"
+    | "\n{"
+    ;
+
 StrictSemi
     : { driver.Warning(yylloc, "warning, automatic semi-colon insertion required"); }
     ;
@@ -715,6 +733,7 @@ PrimaryExpressionNoRE
 PrimaryExpressionNo
     : "this" { $$ = $1; }
     | Identifier { $$ = new(driver.pool_) CYVariable($1); }
+    | AutoComplete { driver.mode_ = CYDriver::AutoPrimary; YYACCEPT; }
     | Literal { $$ = $1; }
     | ArrayLiteral { $$ = $1; }
     | "(" Expression ")" { $$ = $2; }
@@ -750,7 +769,7 @@ ElementList
 /* }}} */
 /* 11.1.5 Object Initialiser {{{ */
 ObjectLiteral
-    : "{" PropertyNameAndValueListOpt "}" { $$ = new(driver.pool_) CYObject($2); }
+    : OpenBrace PropertyNameAndValueListOpt "}" { $$ = new(driver.pool_) CYObject($2); }
     ;
 
 PropertyNameAndValueList_
@@ -786,18 +805,19 @@ MemberExpression_
 MemberAccess
     : "[" Expression "]" { $$ = new(driver.pool_) CYDirectMember(NULL, $2); }
     | "." Identifier { $$ = new(driver.pool_) CYDirectMember(NULL, new(driver.pool_) CYString($2)); }
+    | "." AutoComplete { driver.mode_ = CYDriver::AutoDirect; YYACCEPT; }
     ;
 
 MemberExpression
     : PrimaryExpression { $$ = $1; }
     | LexSetRegExp FunctionExpression { $$ = $2; }
-    | MemberExpression MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | MemberExpression { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     | LexSetRegExp MemberExpression_ { $$ = $2; }
     ;
 
 MemberExpressionNoBF
     : PrimaryExpressionNoBF { $$ = $1; }
-    | MemberExpressionNoBF MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | MemberExpressionNoBF { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     | MemberExpression_ { $$ = $1; }
     ;
 
@@ -805,7 +825,7 @@ MemberExpressionNoBF
 MemberExpressionNoRE
     : PrimaryExpressionNoRE { $$ = $1; }
     | FunctionExpression { $$ = $1; }
-    | MemberExpressionNoRE MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | MemberExpressionNoRE { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     | MemberExpression_ { $$ = $1; }
     ;
 @end
@@ -834,20 +854,20 @@ NewExpressionNoRE
 CallExpression
     : MemberExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
     | CallExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpression MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | CallExpression { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 
 CallExpressionNoBF
     : MemberExpressionNoBF Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
     | CallExpressionNoBF Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpressionNoBF MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | CallExpressionNoBF { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 
 @begin C
 CallExpressionNoRE
     : MemberExpressionNoRE Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
     | CallExpressionNoRE Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
-    | CallExpressionNoRE MemberAccess { $2->SetLeft($1); $$ = $2; }
+    | CallExpressionNoRE { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
     ;
 @end
 
@@ -1250,7 +1270,7 @@ Statement
 /* }}} */
 /* 12.1 Block {{{ */
 Block_
-    : "{" StatementListOpt "}" { $$ = $2; }
+    : Brace StatementListOpt "}" { $$ = $2; }
     ;
 
 Block
@@ -1402,7 +1422,7 @@ SwitchStatement
     ;
 
 CaseBlock
-    : "{" CaseClausesOpt "}" { $$ = $2; }
+    : Brace CaseClausesOpt "}" { $$ = $2; }
     ;
 
 CaseClausesOpt
@@ -1447,11 +1467,11 @@ FinallyOpt
 
 /* 13 Function Definition {{{ */
 FunctionDeclaration
-    : "function" Identifier "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionStatement($2, $4, $7); }
+    : "function" Identifier "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = new(driver.pool_) CYFunctionStatement($2, $4, $7); }
     ;
 
 FunctionExpression
-    : "function" IdentifierOpt "(" FormalParameterList ")" "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($2, $4, $7); }
+    : "function" IdentifierOpt "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = new(driver.pool_) CYFunctionExpression($2, $4, $7); }
     ;
 
 FormalParameterList_
@@ -1497,7 +1517,7 @@ ClassSuperOpt
     ;
 
 ClassFieldList
-    : "{" "}" { $$ = NULL; }
+    : Brace "}" { $$ = NULL; }
     ;
 
 MessageScope
@@ -1529,7 +1549,7 @@ MessageParameters
     ;
 
 ClassMessageDeclaration
-    : MessageScope TypeOpt MessageParameters "{" FunctionBody "}" { $$ = new(driver.pool_) CYMessage($1, $2, $3, $5); }
+    : MessageScope TypeOpt MessageParameters Brace FunctionBody "}" { $$ = new(driver.pool_) CYMessage($1, $2, $3, $5); }
     ;
 
 ClassMessageDeclarationListOpt
@@ -1594,8 +1614,13 @@ SelectorCall_
     | VariadicCall { $$ = $1; }
     ;
 
+SelectorWordOpt
+    : WordOpt { driver.contexts_.back().words_.push_back($1); } { $$ = $1; }
+    | AutoComplete { driver.mode_ = CYDriver::AutoMessage; YYACCEPT; }
+    ;
+
 SelectorCall
-    : WordOpt ":" AssignmentExpression SelectorCall_ { $$ = new(driver.pool_) CYArgument($1 ?: new(driver.pool_) CYBlank(), $3, $4); }
+    : SelectorWordOpt ":" AssignmentExpression SelectorCall_ { $$ = new(driver.pool_) CYArgument($1 ?: new(driver.pool_) CYBlank(), $3, $4); }
     ;
 
 SelectorList
@@ -1604,8 +1629,8 @@ SelectorList
     ;
 
 MessageExpression
-    : "[" AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYSendDirect($2, $3); }
-    | "[" LexSetRegExp "super" SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($4); }
+    : "[" AssignmentExpression { driver.contexts_.push_back($2); } SelectorList "]" { driver.contexts_.pop_back(); } { $$ = new(driver.pool_) CYSendDirect($2, $4); }
+    | "[" LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" { $$ = new(driver.pool_) CYSendSuper($5); }
     ;
 
 SelectorExpressionOpt
@@ -1642,6 +1667,7 @@ UnaryExpression_
 MemberAccess
     : "->" "[" Expression "]" { $$ = new(driver.pool_) CYIndirectMember(NULL, $3); }
     | "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); }
+    | "->" AutoComplete { driver.mode_ = CYDriver::AutoIndirect; YYACCEPT; }
     ;
 /* }}} */
 @end
@@ -1756,7 +1782,7 @@ XMLTagContent
     ;
 
 XMLExpression
-    : "{" LexPushRegExp Expression "}" LexPop
+    : Brace LexPushRegExp Expression "}" LexPop
     ;
 
 XMLTagName
@@ -1828,6 +1854,7 @@ PropertyNameAndValueList_
     : "," { $$ = NULL; }
     ;
 /* }}} */
+
 /* JavaScript 1.7: Array Comprehensions {{{ */
 IfComprehension
     : "if" "(" Expression ")" { $$ = new(driver.pool_) CYIfComprehension($3); }
@@ -1866,10 +1893,50 @@ Statement_
     : LetStatement
     ;
 *//* }}} */
+
 /* JavaScript FTW: Function Statements {{{ */
 Statement
     : LexSetRegExp FunctionDeclaration { driver.Warning(yylloc, "warning, FunctionDeclaration is a SourceElement, not a Statement"); } { $$ = $2; }
     ;
 /* }}} */
+/* JavaScript FTW: Optional Arguments {{{ */
+FormalParameterList
+    : Identifier "=" AssignmentExpression FormalParameterList_ { $$ = new(driver.pool_) CYOptionalFunctionParameter($1, $3, $4); }
+    ;
+/* }}} */
+/* JavaScript FTW: Ruby Blocks {{{ */
+RubyProcParameterList_
+    : "," RubyProcParameterList { $$ = $2; }
+    | { $$ = NULL; }
+    ;
+
+RubyProcParameterList
+    : Identifier RubyProcParameterList_ { $$ = new(driver.pool_) CYFunctionParameter($1, $2); }
+    | { $$ = NULL; }
+    ;
+
+RubyProcParametersOpt
+    : "|" RubyProcParameterList "|" { $$ = $2; }
+    | { $$ = NULL; }
+    ;
+
+RubyProcExpression
+    : "{" RubyProcParametersOpt StatementListOpt "}" { $$ = new(driver.pool_) CYRubyProc($2, $3); }
+    ;
+
+LeftHandSideExpression
+    : LeftHandSideExpression RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    ;
+
+LeftHandSideExpressionNoBF
+    : LeftHandSideExpressionNoBF RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    ;
+
+@begin C
+LeftHandSideExpressionNoRE
+    : LeftHandSideExpressionNoRE RubyProcExpression { $$ = new(driver.pool_) CYRubyBlock($1, $2); }
+    ;
+@end
+/* }}} */
 
 %%