X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/0559abf83c4cc9bbd896b69dfaae1e8422521479..4b645e23d2abde4de1ced347750b070f89b685c3:/Parser.ypp.in diff --git a/Parser.ypp.in b/Parser.ypp.in index 2a1bf22..0d48316 100644 --- a/Parser.ypp.in +++ b/Parser.ypp.in @@ -48,6 +48,7 @@ %union { CYBinding *binding_; } %union { CYBindings *bindings_; } %union { CYBoolean *boolean_; } +%union { CYBraced *braced_; } %union { CYClause *clause_; } %union { cy::Syntax::Catch *catch_; } %union { CYClassTail *classTail_; } @@ -71,7 +72,6 @@ %union { CYParenthetical *parenthetical_; } %union { CYProperty *property_; } %union { CYPropertyName *propertyName_; } -%union { CYRubyProc *rubyProc_; } %union { CYSpan *span_; } %union { CYStatement *statement_; } %union { CYString *string_; } @@ -85,11 +85,13 @@ %union { CYTypeStructField *structField_; } %union { CYTypeModifier *modifier_; } %union { CYTypeSpecifier *specifier_; } +%union { CYTypedFormal *typedFormal_; } %union { CYTypedIdentifier *typedIdentifier_; } %union { CYTypedParameter *typedParameter_; } @end @begin ObjectiveC +%union { CYObjCKeyValue *keyValue_; } %union { CYImplementationField *implementationField_; } %union { CYMessage *message_; } %union { CYMessageParameter *messageParameter_; } @@ -182,6 +184,13 @@ type; }) yyla.type = yytranslate_(token::to); \ } while (false) +#define CYHLD(location, token) do { \ + if (driver.hold_ != empty_symbol) \ + CYERR(location, "unexpected hold"); \ + driver.hold_ = yyla.type; \ + yyla.type = yytranslate_(token); \ +} while (false) + #define CYERR(location, message) do { \ error(location, message); \ YYABORT; \ @@ -251,7 +260,6 @@ type; }) %token SlashRight "/>" %token LeftSlash " ArgumentListOpt %type Arguments %type ArrayComprehension +%type ArrayElement %type ArrayLiteral %type ArrowFunction %type ArrowParameters %type AssignmentExpression -%type AssignmentExpressionOpt %type BindingIdentifier %type BindingIdentifierOpt %type BindingList_ @@ -493,6 +503,8 @@ type; }) %type BindingElement %type BitwiseORExpression %type BitwiseXORExpression +%type BracedExpression_ +%type BracedExpression %type BreakStatement %type BreakableStatement %type CallExpression_ @@ -520,6 +532,7 @@ type; }) %type Declaration_ %type Declaration %type DefaultClause +%type ElementList_ %type ElementList %type ElementListOpt %type ElseStatementOpt @@ -612,9 +625,7 @@ type; }) %type RegularExpressionSlash %type RelationalExpression %type ReturnStatement -%type RubyBlockExpression_ -%type RubyBlockExpression -%type RubyProcExpression +%type BracedParameter %type RubyProcParameterList_ %type RubyProcParameterList %type RubyProcParameters @@ -648,6 +659,7 @@ type; }) %type VariableStatement %type WithStatement %type Word +%type WordNoUnary @begin ObjectiveC %type WordOpt @end @@ -675,9 +687,10 @@ type; }) %type TypedIdentifierMaybe %type TypedIdentifierNo %type TypedIdentifierYes -%type TypedParameterList_ -%type TypedParameterList -%type TypedParameterListOpt +%type TypedParameterList_ +%type TypedParameterList +%type TypedParameterListOpt +%type TypedParameters @end @begin ObjectiveC @@ -693,6 +706,9 @@ type; }) %type ClassProtocolsOpt %type ImplementationFieldListOpt %type ImplementationStatement +%type KeyValuePairList_ +%type KeyValuePairList +%type KeyValuePairListOpt %type MessageExpression %type MessageParameter %type MessageParameters @@ -734,6 +750,9 @@ type; }) /* Token Priorities {{{ */ %nonassoc "if" %nonassoc "else" + +%nonassoc ":" +%nonassoc "!yield" /* }}} */ %start Program @@ -766,11 +785,11 @@ LexPushYieldOff: { driver.yield_.push(false); }; LexPopYield: { driver.yield_.pop(); }; LexNewLineOrOpt - : { CYLEX(); if (driver.hold_ != empty_symbol) CYERR(@$, "unexpected hold"); if (driver.newline_) { driver.hold_ = yyla.type; yyla.type = yytranslate_(cy::parser::token::NewLine); } } + : { CYLEX(); if (driver.newline_) { CYHLD(@$, tk::NewLine); } } ; LexNewLineOrNot - : { CYLEX(); if (driver.hold_ != empty_symbol) CYERR(@$, "unexpected hold"); driver.hold_ = yyla.type; yyla.type = yytranslate_(driver.newline_ ? cy::parser::token::NewLine : cy::parser::token::__); } + : { CYLEX(); CYHLD(@$, driver.newline_ ? tk::NewLine : tk::__); } ; LexNoStar @@ -807,7 +826,7 @@ IdentifierName | "instanceof" { $$ = CYNew CYWord("instanceof"); } ; -Word +WordNoUnary : IdentifierNoOf[pass] { $$ = $pass; } | "break" { $$ = CYNew CYWord("break"); } | "case" { $$ = CYNew CYWord("case"); } @@ -818,7 +837,6 @@ Word | "continue" { $$ = CYNew CYWord("continue"); } | "debugger" { $$ = CYNew CYWord("debugger"); } | "default" { $$ = CYNew CYWord("default"); } - | "delete" { $$ = CYNew CYWord("delete"); } | "do" { $$ = CYNew CYWord("do"); } | "else" { $$ = CYNew CYWord("else"); } | "enum" { $$ = CYNew CYWord("enum"); } @@ -831,7 +849,6 @@ Word | "import" { $$ = CYNew CYWord("import"); } | "!in" { $$ = CYNew CYWord("in"); } | "!of" { $$ = CYNew CYWord("of"); } - | "new" { $$ = CYNew CYWord("new"); } | "null" { $$ = CYNew CYWord("null"); } | "return" { $$ = CYNew CYWord("return"); } | "super" { $$ = CYNew CYWord("super"); } @@ -840,11 +857,16 @@ Word | "throw" { $$ = CYNew CYWord("throw"); } | "true" { $$ = CYNew CYWord("true"); } | "try" { $$ = CYNew CYWord("try"); } - | "typeof" { $$ = CYNew CYWord("typeof"); } | "var" { $$ = CYNew CYWord("var"); } - | "void" { $$ = CYNew CYWord("void"); } | "while" { $$ = CYNew CYWord("while"); } | "with" { $$ = CYNew CYWord("with"); } + ; + +Word + : WordNoUnary[pass] { $$ = $pass; } + | "delete" { $$ = CYNew CYWord("delete"); } + | "typeof" { $$ = CYNew CYWord("typeof"); } + | "void" { $$ = CYNew CYWord("void"); } | "yield" { $$ = CYNew CYIdentifier("yield"); } ; @@ -967,6 +989,7 @@ IdentifierTypeNoOf | "target" { $$ = CYNew CYIdentifier("target"); } | "throws" { $$ = CYNew CYIdentifier("throws"); } | "transient" { $$ = CYNew CYIdentifier("transient"); } + | "typeid" { $$ = CYNew CYIdentifier("typeid"); } | "undefined" { $$ = CYNew CYIdentifier("undefined"); } @begin ObjectiveC | "bool" { $$ = CYNew CYIdentifier("bool"); } @@ -1050,10 +1073,19 @@ ArrayLiteral : "[" ElementListOpt[elements] "]" { $$ = CYNew CYArray($elements); } ; -ElementList - : AssignmentExpressionOpt[value] "," ElementListOpt[next] { $$ = CYNew CYElementValue($value, $next); } +ArrayElement + : AssignmentExpression[value] { $$ = CYNew CYElementValue($value); } | LexOf "..." AssignmentExpression[values] { $$ = CYNew CYElementSpread($values); } - | AssignmentExpression[value] { $$ = CYNew CYElementValue($value, NULL); } + ; + +ElementList_ + : "," ElementListOpt[elements] { $$ = $elements; } + | { $$ = NULL; } + ; + +ElementList + : ArrayElement[element] ElementList_[next] { $$ = $element; $$->SetNext($next); } + | LexOf "," ElementListOpt[next] { $$ = CYNew CYElementValue(NULL, $next); } ; ElementListOpt @@ -1201,13 +1233,13 @@ AccessExpression ; LeftHandSideExpression - : RubyBlockExpression[pass] { $$ = $pass; } + : BracedExpression[pass] { $$ = $pass; } | IndirectExpression[pass] { $$ = $pass; } ; /* }}} */ /* 12.4 Postfix Expressions {{{ */ PostfixExpression - : RubyBlockExpression[pass] { $$ = $pass; } + : BracedExpression[pass] { $$ = $pass; } | AccessExpression[lhs] LexNewLineOrOpt "++" { $$ = CYNew CYPostIncrement($lhs); } | AccessExpression[lhs] LexNewLineOrOpt "--" { $$ = CYNew CYPostDecrement($lhs); } ; @@ -1342,11 +1374,6 @@ AssignmentExpression | ArrowFunction[pass] { $$ = $pass; } | LexOf LeftHandSideAssignment[assignment] AssignmentExpression[rhs] { $assignment->SetRight($rhs); $$ = $assignment; } ; - -AssignmentExpressionOpt - : AssignmentExpression[pass] { $$ = $pass; } - | LexOf { $$ = NULL; } - ; /* }}} */ /* 12.15 Comma Operator ( , ) {{{ */ Expression @@ -1595,7 +1622,7 @@ ForStatementInitializer ; ForInStatementInitializer - : LexLet LexOf RubyBlockExpression[pass] { $$ = $pass; } + : LexLet LexOf BracedExpression[pass] { $$ = $pass; } | LexLet LexOf IndirectExpression[pass] { $$ = $pass; } | LexLet LexOf Var_ LexBind ForBinding[binding] { $$ = CYNew CYForVariable($binding); } | ForDeclaration[pass] { $$ = $pass; } @@ -1789,7 +1816,7 @@ GeneratorBody YieldExpression : "!yield" LexNewLineOrNot "\n" LexOf { CYNOT(@$); /* $$ = CYNew CYYieldValue(NULL); */ } - | "!yield" LexNewLineOrNot "" LexNoStar LexOf { CYNOT(@$); /* $$ = CYNew CYYieldValue(NULL); */ } + | "!yield" LexNewLineOrNot "" LexNoStar LexOf { CYNOT(@$); /* $$ = CYNew CYYieldValue(NULL); */ } %prec "!yield" | "!yield" LexNewLineOrNot "" LexNoStar AssignmentExpression[value] { CYNOT(@$); /* $$ = CYNew CYYieldValue($value); */ } | "!yield" LexNewLineOrNot "" LexNoStar LexOf "yield *" AssignmentExpression[generator] { CYNOT(@$); /* $$ = CYNew CYYieldGenerator($generator); */ } ; @@ -2017,12 +2044,12 @@ ParameterModifierOpt ; ParameterTail - : TypedParameterListOpt[parameters] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($parameters); } + : TypedParameterListOpt[formal] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($formal->variadic_, $formal->parameters_); } ; SuffixedType : SuffixedTypeOpt[typed] "[" RestrictOpt NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->modifier_); } - | "(" "^" TypeQualifierRightOpt[typed] ")" "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); } + | "(" "^" TypeQualifierRightOpt[typed] ")" "(" TypedParameters[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); } | TypeSignifier[typed] "(" ParameterTail[modifier] { $$ = $typed; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } | "("[parenthesis] ParameterTail[modifier] { $$ = CYNew CYTypedIdentifier(@parenthesis); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } ; @@ -2154,7 +2181,7 @@ MessageParameterList MessageParameterListOpt : MessageParameterList[pass] { $$ = $pass; } - | { $$ = NULL; } + | TypedParameterList_[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); /*XXX*/ if ($formal->parameters_ != NULL) CYERR(@$, "temporarily unsupported"); $$ = NULL; } ; MessageParameters @@ -2272,15 +2299,29 @@ BoxableExpression | BooleanLiteral[pass] { $$ = $pass; } | NumericLiteral[pass] { $$ = $pass; } | StringLiteral[pass] { $$ = $pass; } - | ArrayLiteral[pass] { $$ = $pass; } - | ObjectLiteral[pass] { $$ = $pass; } | CoverParenthesizedExpressionAndArrowParameterList[pass] { $$ = $pass; } | "YES" { $$ = CYNew CYTrue(); } | "NO" { $$ = CYNew CYFalse(); } ; +KeyValuePairList_ + : "," KeyValuePairListOpt[next] { $$ = $next; } + | { $$ = NULL; } + +KeyValuePairList + : AssignmentExpression[key] ":" AssignmentExpression[value] KeyValuePairList_[next] { $$ = CYNew CYObjCKeyValue($key, $value, $next); } + ; + +KeyValuePairListOpt + : KeyValuePairList[pass] { $$ = $pass; } + | LexOf { $$ = NULL; } + ; + PrimaryExpression : "@" BoxableExpression[expression] { $$ = CYNew CYBox($expression); } + | "@" "[" ElementListOpt[elements] "]" { $$ = CYNew CYObjCArray($elements); } + | "@" "{" KeyValuePairListOpt[pairs] "}" { $$ = CYNew CYObjCDictionary($pairs); } + | "@YES" { $$ = CYNew CYBox(CYNew CYTrue()); } | "@NO" { $$ = CYNew CYBox(CYNew CYFalse()); } | "@true" { $$ = CYNew CYBox(CYNew CYTrue()); } @@ -2323,21 +2364,26 @@ MemberAccess /* Cycript (C): Lambda Expressions {{{ */ TypedParameterList_ : "," TypedParameterList[parameters] { $$ = $parameters; } - | { $$ = NULL; } + | { $$ = CYNew CYTypedFormal(false); } ; TypedParameterList - : TypedIdentifierMaybe[typed] TypedParameterList_[next] { $$ = CYNew CYTypedParameter($typed, $next); } + : TypedIdentifierMaybe[typed] TypedParameterList_[formal] { $$ = $formal; $$->parameters_ = CYNew CYTypedParameter($typed, $$->parameters_); } + | "..." { $$ = CYNew CYTypedFormal(true); } ; TypedParameterListOpt : TypedParameterList[pass] { $$ = $pass; } - | "void" { $$ = NULL; } - | { $$ = NULL; } + | "void" { $$ = CYNew CYTypedFormal(false); } + | { $$ = CYNew CYTypedFormal(false); } + ; + +TypedParameters + : TypedParameterListOpt[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); $$ = $formal->parameters_; } ; PrimaryExpression - : "[" LexOf "&" "]" "(" TypedParameterListOpt[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); } + : "[" LexOf "&" "]" "(" TypedParameters[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); } ; /* }}} */ /* Cycript (C): Structure Definitions {{{ */ @@ -2613,16 +2659,23 @@ ComprehensionIf : "if" "(" AssignmentExpression[test] ")" { $$ = CYNew CYIfComprehension($test); } ; /* }}} */ -/* JavaScript FTW: Coalesce Operator {{{ */ -ConditionalExpression - : LogicalORExpression[test] "?" LexPushInOff LexOf ":" LexPopIn AssignmentExpression[false] { $$ = CYNew CYCondition($test, $test, $false); } - ; -/* }}} */ /* JavaScript FTW: Named Arguments {{{ */ ArgumentList - : LexOf Word[tag] ":" AssignmentExpression[value] ArgumentList_[next] { $$ = CYNew CYArgument($tag, $value, $next); } + : LexOf WordNoUnary[tag] ":" AssignmentExpression[value] ArgumentList_[next] { $$ = CYNew CYArgument($tag, $value, $next); } + ; +/* }}} */ +/* JavaScript FTW: Subscript Access {{{ */ +MemberAccess + : "." "[" AssignmentExpression[property] "]" { $$ = CYNew CYSubscriptMember(NULL, $property); } + ; +/* }}} */ + +/* JavaScript FTW: Java "Anonymous Inner Classes" {{{ */ +BracedParameter + : "{" PropertyDefinitionListOpt[properties] "}" { $$ = CYNew CYExtend(NULL, $properties); } ; /* }}} */ + /* JavaScript FTW: Ruby Blocks {{{ */ RubyProcParameterList_ : "," RubyProcParameterList[parameters] { $$ = $parameters; } @@ -2644,22 +2697,34 @@ RubyProcParametersOpt | { $$ = NULL; } ; -RubyProcExpression - : "{" RubyProcParametersOpt[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyProc($parameters, $code); } +BracedParameter + : ";{" RubyProcParametersOpt[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyBlock(NULL, CYNew CYRubyProc($parameters, $code)); } ; PrimaryExpression : "{" RubyProcParameters[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyProc($parameters, $code); } ; -RubyBlockExpression_ +BracedExpression_ : AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; } - | RubyBlockExpression_[lhs] RubyProcExpression[rhs] LexNewLineOrOpt { $$ = CYNew CYRubyBlock($lhs, $rhs); } + | BracedExpression_[lhs] { if (!$lhs->IsNew()) CYMAP(OpenBrace_, OpenBrace); } BracedParameter[rhs] LexNewLineOrOpt { $rhs->SetLeft($lhs); $$ = $rhs; } ; -RubyBlockExpression - : RubyBlockExpression_[pass] "\n" { $$ = $pass; } - | RubyBlockExpression_[pass] { $$ = $pass; } +BracedExpression + : BracedExpression_[pass] "\n" { $$ = $pass; } + | BracedExpression_[pass] { $$ = $pass; } + ; +/* }}} */ +/* JavaScript FTW: Ruby Scopes {{{ */ +MemberAccess + : "::" "[" Expression[property] "]" { $$ = CYNew CYResolveMember(NULL, $property); } + | "::" IdentifierName[property] { $$ = CYNew CYResolveMember(NULL, CYNew CYString($property)); } + | "::" AutoComplete { driver.mode_ = CYDriver::AutoResolve; YYACCEPT; } + ; +/* }}} */ +/* JavaScript FTW: Ruby Symbols {{{ */ +PrimaryExpression + : ":" Word[name] { $$ = CYNew CYSymbol($name->Word()); } ; /* }}} */