X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/2fad14e52c8cde8c45003a2ebb6907a57ca380e4..436a877be73ebe14fecd3ef0e9b7dd6b854d2e3b:/Parser.ypp.in?ds=sidebyside diff --git a/Parser.ypp.in b/Parser.ypp.in index 5efee05..11d8d29 100644 --- a/Parser.ypp.in +++ b/Parser.ypp.in @@ -1,5 +1,5 @@ -/* Cycript - Optimizing JavaScript Compiler/Runtime - * Copyright (C) 2009-2015 Jay Freeman (saurik) +/* Cycript - The Truly Universal Scripting Language + * Copyright (C) 2009-2016 Jay Freeman (saurik) */ /* GNU Affero General Public License, Version 3 {{{ */ @@ -27,6 +27,7 @@ #include "Driver.hpp" #include "Parser.hpp" #include "Stack.hpp" +#include "Syntax.hpp" #define CYNew new(driver.pool_) @begin ObjectiveC @@ -48,6 +49,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 +73,6 @@ %union { CYParenthetical *parenthetical_; } %union { CYProperty *property_; } %union { CYPropertyName *propertyName_; } -%union { CYRubyProc *rubyProc_; } %union { CYSpan *span_; } %union { CYStatement *statement_; } %union { CYString *string_; } @@ -184,6 +185,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; \ @@ -258,7 +266,6 @@ type; }) @begin E4X ObjectiveC %token At "@" -%token Pound "#" @end %token Ampersand "&" @@ -308,6 +315,7 @@ type; }) %token Comma "," %token Question "?" %token SemiColon ";" +%token Pound "#" %token NewLine "\n" %token __ "" @@ -496,6 +504,8 @@ type; }) %type BindingElement %type BitwiseORExpression %type BitwiseXORExpression +%type BracedExpression_ +%type BracedExpression %type BreakStatement %type BreakableStatement %type CallExpression_ @@ -616,9 +626,7 @@ type; }) %type RegularExpressionSlash %type RelationalExpression %type ReturnStatement -%type RubyBlockExpression_ -%type RubyBlockExpression -%type RubyProcExpression +%type BracedParameter %type RubyProcParameterList_ %type RubyProcParameterList %type RubyProcParameters @@ -778,11 +786,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 @@ -1226,13 +1234,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); } ; @@ -1615,7 +1623,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; } @@ -2415,7 +2423,7 @@ IdentifierNoOf ; ExternCStatement - : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); } + : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternalDefinition(CYNew CYString("C"), $typed); } | TypeDefinition[pass] { $$ = $pass; } ; @@ -2429,8 +2437,16 @@ ExternC | ExternCStatement[pass] { $$ = $pass; } ; +ABI + : StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } + ; + Statement__ - : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; } + : "extern" NewLineNot ABI[abi] ExternC[pass] { $$ = $pass; } + ; + +PrimaryExpression + : "(" LexOf "extern" NewLineOpt ABI[abi] TypedIdentifierField[typed] ")" { $$ = CYNew CYExternalExpression(CYNew CYString("C"), $typed); } ; /* }}} */ @end @@ -2657,6 +2673,17 @@ ArgumentList : 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_ @@ -2679,22 +2706,22 @@ 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 {{{ */