X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/7cf0481b5ad2ae2b3b17fbc475bacae5c1a4ddd4..554cd08dc5f6226ffd3eac34786b2c63bf17d9ad:/Parser.ypp.in?ds=sidebyside diff --git a/Parser.ypp.in b/Parser.ypp.in index f73ccd1..0d8e87d 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,11 +49,13 @@ %union { CYBinding *binding_; } %union { CYBindings *bindings_; } %union { CYBoolean *boolean_; } +%union { CYBraced *braced_; } %union { CYClause *clause_; } %union { cy::Syntax::Catch *catch_; } %union { CYClassTail *classTail_; } %union { CYComprehension *comprehension_; } %union { CYElement *element_; } +%union { CYEnumConstant *constant_; } %union { CYExpression *expression_; } %union { CYFalse *false_; } %union { CYVariable *variable_; } @@ -61,6 +64,7 @@ %union { CYForInInitializer *forin_; } %union { CYFunctionParameter *functionParameter_; } %union { CYIdentifier *identifier_; } +%union { CYImportSpecifier *import_; } %union { CYInfix *infix_; } %union { CYLiteral *literal_; } %union { CYMethod *method_; } @@ -70,7 +74,7 @@ %union { CYParenthetical *parenthetical_; } %union { CYProperty *property_; } %union { CYPropertyName *propertyName_; } -%union { CYRubyProc *rubyProc_; } +%union { CYTypeSigning signing_; } %union { CYSpan *span_; } %union { CYStatement *statement_; } %union { CYString *string_; } @@ -80,13 +84,19 @@ %union { CYWord *word_; } @begin C +%union { CYTypeIntegral *integral_; } +%union { CYTypeStructField *structField_; } %union { CYTypeModifier *modifier_; } %union { CYTypeSpecifier *specifier_; } -%union { CYTypedIdentifier *typedIdentifier_; } +%union { CYTypedFormal *typedFormal_; } +%union { CYTypedLocation *typedLocation_; } +%union { CYTypedName *typedName_; } %union { CYTypedParameter *typedParameter_; } +%union { CYType *typedThing_; } @end @begin ObjectiveC +%union { CYObjCKeyValue *keyValue_; } %union { CYImplementationField *implementationField_; } %union { CYMessage *message_; } %union { CYMessageParameter *messageParameter_; } @@ -179,6 +189,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; \ @@ -213,6 +230,9 @@ type; }) case CYMarkModule: driver.hold_ = yytranslate_(token::MarkModule); break; + case CYMarkExpression: + driver.hold_ = yytranslate_(token::MarkExpression); + break; } }; @@ -248,13 +268,11 @@ 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_ @@ -485,6 +512,8 @@ type; }) %type BindingElement %type BitwiseORExpression %type BitwiseXORExpression +%type BracedExpression_ +%type BracedExpression %type BreakStatement %type BreakableStatement %type CallExpression_ @@ -512,6 +541,7 @@ type; }) %type Declaration_ %type Declaration %type DefaultClause +%type ElementList_ %type ElementList %type ElementListOpt %type ElseStatementOpt @@ -521,6 +551,9 @@ type; }) %type ExpressionOpt %type ExpressionStatement_ %type ExpressionStatement +%type ExternC +%type ExternCStatement +%type ExternCStatementListOpt %type Finally %type ForBinding %type ForDeclaration @@ -530,6 +563,7 @@ type; }) %type FormalParameterList_ %type FormalParameterList %type FormalParameters +%type FromClause %type FunctionBody %type FunctionDeclaration %type FunctionExpression @@ -543,9 +577,18 @@ type; }) %type IdentifierNoOf %type IdentifierType %type IdentifierTypeNoOf +%type IdentifierTypeOpt %type IdentifierName %type IdentifierReference %type IfStatement +%type ImportClause +%type ImportDeclaration +%type ImportSpecifier +%type ImportedBinding +%type ImportedDefaultBinding +%type ImportsList_ +%type ImportsList +%type ImportsListOpt %type IndirectExpression %type Initializer %type InitializerOpt @@ -566,8 +609,16 @@ type; }) %type MemberAccess %type MemberExpression %type MethodDefinition +%type ModuleBody +%type ModuleBodyOpt +%type ModuleItem +%type ModuleItemList +%type ModuleItemListOpt %type ModulePath +%type ModuleSpecifier %type MultiplicativeExpression +%type NameSpaceImport +%type NamedImports %type NewExpression %type NullLiteral %type ObjectLiteral @@ -583,7 +634,7 @@ type; }) %type RegularExpressionSlash %type RelationalExpression %type ReturnStatement -%type RubyProcExpression +%type BracedParameter %type RubyProcParameterList_ %type RubyProcParameterList %type RubyProcParameters @@ -607,6 +658,7 @@ type; }) %type TemplateSpans %type ThrowStatement %type TryStatement +%type TypeDefinition %type UnaryExpression_ %type UnaryExpression %type VariableDeclaration @@ -616,26 +668,44 @@ type; }) %type VariableStatement %type WithStatement %type Word +%type WordNoUnary @begin ObjectiveC %type WordOpt @end %type YieldExpression @begin C -%type IntegerType -%type IntegerTypeOpt -%type PrefixedType +%type EnumConstantListOpt_ +%type EnumConstantListOpt +%type IntegerNumber +%type IntegerType +%type IntegerTypeOpt +%type PrefixedType +%type PrimitiveReference %type PrimitiveType -%type SuffixedType -%type TypeSignifier +%type StructFieldListOpt +%type SuffixedType +%type SuffixedTypeOpt +%type TypeSignifier +%type TypeSignifierNone +%type TypeSignifierOpt +%type TypeSigning +%type ParameterTail %type TypeQualifierLeft -%type TypeQualifierRight -%type TypedIdentifierMaybe -%type TypedIdentifierNo -%type TypedIdentifierYes -%type TypedParameterList_ -%type TypedParameterList -%type TypedParameterListOpt +%type TypeQualifierLeftOpt +%type TypeQualifierRight +%type TypeQualifierRightOpt +%type TypedIdentifierDefinition +%type TypedIdentifierEncoding +%type TypedIdentifierField +%type TypedIdentifierMaybe +%type TypedIdentifierNo +%type TypedIdentifierTagged +%type TypedIdentifierYes +%type TypedParameterList_ +%type TypedParameterList +%type TypedParameterListOpt +%type TypedParameters @end @begin ObjectiveC @@ -651,6 +721,9 @@ type; }) %type ClassProtocolsOpt %type ImplementationFieldListOpt %type ImplementationStatement +%type KeyValuePairList_ +%type KeyValuePairList +%type KeyValuePairListOpt %type MessageExpression %type MessageParameter %type MessageParameters @@ -664,7 +737,7 @@ type; }) %type SelectorExpressionOpt %type SelectorList %type SelectorWordOpt -%type TypeOpt +%type TypeOpt %type VariadicCall @end @@ -692,17 +765,22 @@ type; }) /* Token Priorities {{{ */ %nonassoc "if" %nonassoc "else" + +%nonassoc ":" +%nonassoc "!yield" /* }}} */ %start Program %token MarkModule %token MarkScript +%token MarkExpression %% Program : MarkScript Script | MarkModule Module + | MarkExpression Expression[expression] { driver.context_ = $expression; } ; /* Lexer State {{{ */ @@ -712,21 +790,23 @@ LexPopIn: { driver.in_.pop(); }; LexPushReturnOn: { driver.return_.push(true); }; LexPopReturn: { driver.return_.pop(); }; +Return: "return"[return] { if (!driver.return_.top()) CYERR(@return, "invalid return"); }; LexPushSuperOn: { driver.super_.push(true); }; LexPushSuperOff: { driver.super_.push(false); }; LexPopSuper: { driver.super_.pop(); }; +Super: "super"[super] { if (!driver.super_.top()) CYERR(@super, "invalid super"); }; LexPushYieldOn: { driver.yield_.push(true); }; 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 @@ -763,7 +843,7 @@ IdentifierName | "instanceof" { $$ = CYNew CYWord("instanceof"); } ; -Word +WordNoUnary : IdentifierNoOf[pass] { $$ = $pass; } | "break" { $$ = CYNew CYWord("break"); } | "case" { $$ = CYNew CYWord("case"); } @@ -774,7 +854,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"); } @@ -787,7 +866,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"); } @@ -796,11 +874,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"); } ; @@ -852,6 +935,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 @@ -888,6 +976,7 @@ LabelIdentifier IdentifierTypeNoOf : Identifier_[pass] { $$ = $pass; } | "abstract" { $$ = CYNew CYIdentifier("abstract"); } + | "as" { $$ = CYNew CYIdentifier("as"); } | "await" { $$ = CYNew CYIdentifier("await"); } | "boolean" { $$ = CYNew CYIdentifier("boolean"); } | "byte" { $$ = CYNew CYIdentifier("byte"); } @@ -909,6 +998,7 @@ IdentifierTypeNoOf | "package" { $$ = CYNew CYIdentifier("package"); } | "private" { $$ = CYNew CYIdentifier("private"); } | "protected" { $$ = CYNew CYIdentifier("protected"); } + | "__proto__" { $$ = CYNew CYIdentifier("__proto__"); } | "prototype" { $$ = CYNew CYIdentifier("prototype"); } | "public" { $$ = CYNew CYIdentifier("public"); } | "set" { $$ = CYNew CYIdentifier("set"); } @@ -916,6 +1006,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"); } @@ -930,11 +1021,19 @@ IdentifierType | "of" { $$ = CYNew CYIdentifier("of"); } ; +IdentifierTypeOpt + : IdentifierType[pass] { $$ = $pass; } + | { $$ = NULL; } + ; + IdentifierNoOf : IdentifierTypeNoOf | "char" { $$ = CYNew CYIdentifier("char"); } | "int" { $$ = CYNew CYIdentifier("int"); } + | "__int128" { $$ = CYNew CYIdentifier("__int128"); } | "long" { $$ = CYNew CYIdentifier("long"); } + | "__restrict" { $$ = CYNew CYIdentifier("__restrict"); } + | "restrict" { $$ = CYNew CYIdentifier("restrict"); } | "short" { $$ = CYNew CYIdentifier("short"); } | "static" { $$ = CYNew CYIdentifier("static"); } | "volatile" { $$ = CYNew CYIdentifier("volatile"); } @@ -992,10 +1091,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 @@ -1086,8 +1194,8 @@ MemberExpression ; SuperProperty - : "super"[super] { if (!driver.super_.top()) CYERR(@super, "invalid super"); } "[" Expression[property] "]" { $$ = CYNew CYSuperAccess($property); } - | "super"[super] { if (!driver.super_.top()) CYERR(@super, "invalid super"); } "." IdentifierName[property] { $$ = CYNew CYSuperAccess(CYNew CYString($property)); } + : Super "[" Expression[property] "]" { $$ = CYNew CYSuperAccess($property); } + | Super "." IdentifierName[property] { $$ = CYNew CYSuperAccess(CYNew CYString($property)); } ; MetaProperty @@ -1115,7 +1223,7 @@ CallExpression ; SuperCall - : "super"[super] { if (!driver.super_.top()) CYERR(@super, "invalid super"); } Arguments[arguments] { $$ = CYNew CYSuperCall($arguments); } + : Super Arguments[arguments] { $$ = CYNew CYSuperCall($arguments); } ; Arguments @@ -1143,13 +1251,13 @@ AccessExpression ; LeftHandSideExpression - : AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; } + : BracedExpression[pass] { $$ = $pass; } | IndirectExpression[pass] { $$ = $pass; } ; /* }}} */ /* 12.4 Postfix Expressions {{{ */ PostfixExpression - : AccessExpression[lhs] LexNewLineOrOpt { $$ = $lhs; } + : BracedExpression[pass] { $$ = $pass; } | AccessExpression[lhs] LexNewLineOrOpt "++" { $$ = CYNew CYPostIncrement($lhs); } | AccessExpression[lhs] LexNewLineOrOpt "--" { $$ = CYNew CYPostDecrement($lhs); } ; @@ -1169,7 +1277,6 @@ UnaryExpression_ UnaryExpression : PostfixExpression[expression] { $$ = $expression; } - | PostfixExpression[expression] "\n" { $$ = $expression; } | UnaryExpression_[pass] { $$ = $pass; } ; /* }}} */ @@ -1285,11 +1392,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 @@ -1359,7 +1461,7 @@ Block ; StatementList - : StatementListItem[statement] StatementListOpt[next] { $statement->SetNext($next); $$ = $statement; } + : StatementListItem[statement] StatementListOpt[next] { $$ = $statement; CYSetLast($$) = $next; } ; StatementListOpt @@ -1538,7 +1640,7 @@ ForStatementInitializer ; ForInStatementInitializer - : LexLet LexOf AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; } + : LexLet LexOf BracedExpression[pass] { $$ = $pass; } | LexLet LexOf IndirectExpression[pass] { $$ = $pass; } | LexLet LexOf Var_ LexBind ForBinding[binding] { $$ = CYNew CYForVariable($binding); } | ForDeclaration[pass] { $$ = $pass; } @@ -1566,10 +1668,6 @@ BreakStatement ; /* }}} */ /* 13.10 The return Statement {{{ */ -Return - : "return"[return] { if (!driver.return_.top()) CYERR(@return, "invalid return"); } - ; - ReturnStatement : Return TerminatorSoft { $$ = CYNew CYReturn(NULL); } | Return NewLineNot Expression[value] Terminator { $$ = CYNew CYReturn($value); } @@ -1736,7 +1834,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); */ } ; @@ -1804,88 +1902,88 @@ ScriptBodyOpt /* }}} */ /* 15.2 Modules {{{ */ Module - : ModuleBodyOpt + : ModuleBodyOpt[code] { driver.script_ = CYNew CYScript($code); } ; ModuleBody - : ModuleItemList + : ModuleItemList[pass] { $$ = $pass; } ; ModuleBodyOpt - : ModuleBody - | + : ModuleBody[pass] { $$ = $pass; } + | LexSetStatement LexLet LexOf { $$ = NULL; } ; ModuleItemList - : ModuleItemListOpt ModuleItem + : ModuleItem[statement] ModuleItemListOpt[next] { $$ = $statement; CYSetLast($$) = $next; } ; ModuleItemListOpt - : ModuleItemList - | + : ModuleItemList[pass] { $$ = $pass; } + | LexSetStatement LexLet LexOf { $$ = NULL; } ; ModuleItem - : LexSetStatement LexLet LexOf ImportDeclaration - | LexSetStatement LexLet LexOf ExportDeclaration - | StatementListItem + : LexSetStatement LexLet LexOf ImportDeclaration[pass] { $$ = $pass; } + | LexSetStatement LexLet LexOf ExportDeclaration { CYNOT(@$); } + | StatementListItem[pass] { $$ = $pass; } ; /* }}} */ /* 15.2.2 Imports {{{ */ ImportDeclaration - : "import" ImportClause FromClause Terminator - | "import" LexOf ModuleSpecifier Terminator + : "import" ImportClause[specifiers] FromClause[module] Terminator { $$ = CYNew CYImportDeclaration($specifiers, $module); } + | "import" LexOf ModuleSpecifier[module] Terminator { $$ = CYNew CYImportDeclaration(NULL, $module); } ; ImportClause - : ImportedDefaultBinding - | LexOf NameSpaceImport - | LexOf NamedImports - | ImportedDefaultBinding "," NameSpaceImport - | ImportedDefaultBinding "," NamedImports + : ImportedDefaultBinding[default] { $$ = $default; } + | LexOf NameSpaceImport[pass] { $$ = $pass; } + | LexOf NamedImports[pass] { $$ = $pass; } + | ImportedDefaultBinding[default] "," NameSpaceImport[next] { $$ = $default; CYSetLast($$) = $next; } + | ImportedDefaultBinding[default] "," NamedImports[next] { $$ = $default; CYSetLast($$) = $next; } ; ImportedDefaultBinding - : ImportedBinding + : ImportedBinding[binding] { $$ = CYNew CYImportSpecifier(CYNew CYIdentifier("default"), $binding); } ; NameSpaceImport - : "*" "as" ImportedBinding + : "*" "as" ImportedBinding[binding] { $$ = CYNew CYImportSpecifier(NULL, $binding); } ; NamedImports - : "{" ImportsListOpt "}" + : "{" ImportsListOpt[pass] "}" { $$ = $pass; } ; FromClause - : "from" ModuleSpecifier + : "from" ModuleSpecifier[pass] { $$ = $pass; } ; ImportsList_ - : "," ImportsListOpt - | + : "," ImportsListOpt[pass] { $$ = $pass; } + | { $$ = NULL; } ; ImportsList - : ImportSpecifier ImportsList_ + : ImportSpecifier[import] ImportsList_[next] { $$ = $import; CYSetLast($$) = $next; } ; ImportsListOpt - : ImportsList - | LexOf + : ImportsList[pass] { $$ = $pass; } + | LexOf { $$ = NULL; } ; ImportSpecifier - : ImportedBinding - | LexOf IdentifierName "as" ImportedBinding + : ImportedBinding[binding] { $$ = CYNew CYImportSpecifier($binding, $binding); } + | LexOf IdentifierName[name] "as" ImportedBinding[binding] { $$ = CYNew CYImportSpecifier($name, $binding); } ; ModuleSpecifier - : StringLiteral + : StringLiteral[pass] { $$ = $pass; } ; ImportedBinding - : BindingIdentifier + : BindingIdentifier[pass] { $$ = $pass; } ; /* }}} */ /* 15.2.3 Exports {{{ */ @@ -1931,72 +2029,175 @@ ExportSpecifier @begin C /* Cycript (C): Type Encoding {{{ */ TypeSignifier - : IdentifierType[identifier] { $$ = CYNew CYTypedIdentifier(@identifier, $identifier); } - | "(" "*" TypeQualifierRight[typed] ")" { $$ = $typed; } + : IdentifierType[name] { $$ = CYNew CYTypedName(@name, $name); } + | StringLiteral[name] { $$ = CYNew CYTypedName(@name, $name); } + | NumericLiteral[name] { $$ = CYNew CYTypedName(@name, $name); } + | "(" "*" TypeQualifierRightOpt[typed] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); } + ; + +TypeSignifierNone + : { $$ = CYNew CYTypedName(@$); } + ; + +TypeSignifierOpt + : TypeSignifier[pass] { $$ = $pass; } + | TypeSignifierNone[pass] { $$ = $pass; } + ; + +Restrict + : "__restrict" + | "restrict" + ; + +RestrictOpt + : Restrict + | + ; + +ParameterModifier + : "throw" "(" ")" + ; + +ParameterModifierOpt + : ParameterModifier + | + ; + +ParameterTail + : TypedParameterListOpt[formal] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($formal->variadic_, $formal->parameters_); } ; SuffixedType - : SuffixedType[typed] "[" NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->modifier_); } - | "(" "^" TypeQualifierRight[typed] ")" "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); } - | TypeSignifier[typed] "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeFunctionWith($parameters, $$->modifier_); } - | "("[parenthesis] TypedParameterListOpt[parameters] ")" { $$ = CYNew CYTypedIdentifier(@parenthesis); $$->modifier_ = CYNew CYTypeFunctionWith($parameters, $$->modifier_); } - | TypeSignifier[pass] { $$ = $pass; } - | { $$ = CYNew CYTypedIdentifier(@$); } + : SuffixedTypeOpt[typed] "[" RestrictOpt NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->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 CYTypedName(@parenthesis); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + ; + +SuffixedTypeOpt + : SuffixedType[pass] { $$ = $pass; } + | TypeSignifierOpt[pass] { $$ = $pass; } ; PrefixedType - : "*" TypeQualifierRight[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); } + : "*" TypeQualifierRightOpt[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); } ; TypeQualifierLeft - : { $$ = NULL; } - | "const" TypeQualifierLeft[modifier] { $$ = $modifier; CYSetLast($$) = CYNew CYTypeConstant(); } - | "volatile" TypeQualifierLeft[modifier] { $$ = $modifier; CYSetLast($$) = CYNew CYTypeVolatile(); } + : "const" TypeQualifierLeftOpt[modifier] { $$ = $modifier; CYSetLast($$) = CYNew CYTypeConstant(); } + | "volatile" TypeQualifierLeftOpt[modifier] { $$ = $modifier; CYSetLast($$) = CYNew CYTypeVolatile(); } + ; + +TypeQualifierLeftOpt + : TypeQualifierLeft[pass] { $$ = $pass; } + | { $$ = NULL; } ; TypeQualifierRight - : PrefixedType[pass] { $$ = $pass; } - | SuffixedType[pass] { $$ = $pass; } - | "const" TypeQualifierRight[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); } - | "volatile" TypeQualifierRight[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeVolatile($$->modifier_); } + : SuffixedType[pass] { $$ = $pass; } + | PrefixedType[pass] { $$ = $pass; } + | "const" TypeQualifierRightOpt[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); } + | "volatile" TypeQualifierRightOpt[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeVolatile($$->modifier_); } + | Restrict TypeQualifierRightOpt[typed] { $$ = $typed; } + ; + +TypeQualifierRightOpt + : TypeQualifierRight[pass] { $$ = $pass; } + | TypeSignifierOpt[pass] { $$ = $pass; } ; IntegerType - : "int" { $$ = CYNew CYTypeVariable("int"); } - | "unsigned" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeUnsigned($specifier); } - | "signed" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeSigned($specifier); } - | "long" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeLong($specifier); } - | "short" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeShort($specifier); } + : "int" { $$ = CYNew CYTypeIntegral(CYTypeNeutral); } + | "unsigned" IntegerTypeOpt[integral] { $$ = $integral->Unsigned(); if ($$ == NULL) CYERR(@1, "incompatible unsigned"); } + | "signed" IntegerTypeOpt[integral] { $$ = $integral->Signed(); if ($$ == NULL) CYERR(@1, "incompatible signed"); } + | "long" IntegerTypeOpt[integral] { $$ = $integral->Long(); if ($$ == NULL) CYERR(@1, "incompatible long"); } + | "short" IntegerTypeOpt[integral] { $$ = $integral->Short(); if ($$ == NULL) CYERR(@1, "incompatible short"); } ; IntegerTypeOpt : IntegerType[pass] { $$ = $pass; } - | { $$ = CYNew CYTypeVariable("int"); } + | { $$ = CYNew CYTypeIntegral(CYTypeNeutral); } + ; + +StructFieldListOpt + : TypedIdentifierField[typed] ";" StructFieldListOpt[next] { $$ = CYNew CYTypeStructField($typed, $typed->name_, $next); } + | { $$ = NULL; } + ; + +IntegerNumber + : NumericLiteral[pass] { $$ = $pass; } + | "-" NumericLiteral[positive] { $$ = $positive; $$->value_ = -$$->value_; } + ; + +EnumConstantListOpt_ + : "," EnumConstantListOpt[pass] { $$ = $pass; } + | { $$ = NULL; } + ; + +EnumConstantListOpt + : IdentifierType[name] "=" IntegerNumber[value] EnumConstantListOpt_[next] { $$ = CYNew CYEnumConstant($name, $value, $next); } + | { $$ = NULL; } + ; + +TypeSigning + : { $$ = CYTypeNeutral; } + | "signed" { $$ = CYTypeSigned; } + | "unsigned" { $$ = CYTypeUnsigned; } ; PrimitiveType : IdentifierType[name] { $$ = CYNew CYTypeVariable($name); } | IntegerType[pass] { $$ = $pass; } - | "void" { $$ = CYNew CYTypeVoid(); } - | "char" { $$ = CYNew CYTypeVariable("char"); } - | "signed" "char" { $$ = CYNew CYTypeSigned(CYNew CYTypeVariable("char")); } - | "unsigned" "char" { $$ = CYNew CYTypeUnsigned(CYNew CYTypeVariable("char")); } + | TypeSigning[signing] "char" { $$ = CYNew CYTypeCharacter($signing); } + | TypeSigning[signing] "__int128" { $$ = CYNew CYTypeInt128($signing); } + ; + +PrimitiveReference + : PrimitiveType[pass] { $$ = $pass; } + | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference(CYTypeReferenceStruct, $name); } + | "enum" IdentifierType[name] { $$ = CYNew CYTypeReference(CYTypeReferenceEnum, $name); } + | "struct" AutoComplete { driver.mode_ = CYDriver::AutoStruct; YYACCEPT; } + | "enum" AutoComplete { driver.mode_ = CYDriver::AutoEnum; YYACCEPT; } ; TypedIdentifierMaybe - : TypeQualifierLeft[modifier] PrimitiveType[specifier] TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + : TypeQualifierLeft[modifier] "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + | "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); } + | TypeQualifierLeftOpt[modifier] PrimitiveReference[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } ; TypedIdentifierYes - : TypedIdentifierMaybe[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; } + : TypedIdentifierMaybe[typed] { if ($typed->name_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; } ; TypedIdentifierNo - : TypedIdentifierMaybe[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; } + : TypedIdentifierMaybe[typed] { if ($typed->name_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; } + ; + +TypedIdentifierTagged + : TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + | TypeQualifierLeftOpt[modifier] "enum" ":" PrimitiveType[specifier] "{" EnumConstantListOpt[constants] "}" TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeEnum(NULL, $specifier, $constants); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + ; + +TypedIdentifierField + : TypedIdentifierYes[pass] { $$ = $pass; } + | TypedIdentifierTagged[typed] { if ($typed->name_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; } + ; + +TypedIdentifierEncoding + : TypedIdentifierNo[pass] { $$ = $pass; } + | TypedIdentifierTagged[typed] { if ($typed->name_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; } + | "void" TypeSignifierNone[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); } + ; + +TypedIdentifierDefinition + : TypedIdentifierYes[pass] { $$ = $pass; } + | TypeQualifierLeftOpt[modifier] "struct" IdentifierTypeOpt[name] "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->name_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct($name, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; } + | "void" TypeSignifier[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); } ; PrimaryExpression - : "@encode" "(" TypedIdentifierMaybe[typed] ")" { $$ = CYNew CYEncodedType($typed); } + : "@encode" "(" TypedIdentifierEncoding[typed] ")" { $$ = CYNew CYEncodedType($typed); } ; /* }}} */ @end @@ -2010,7 +2211,7 @@ ClassSuperOpt ; ImplementationFieldListOpt - : TypedIdentifierMaybe[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $next); } + : TypedIdentifierField[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $typed->name_, $next); } | { $$ = NULL; } ; @@ -2021,11 +2222,11 @@ MessageScope TypeOpt : "(" TypedIdentifierNo[type] ")" { $$ = $type; } - | { $$ = CYNew CYTypedIdentifier(CYNew CYTypeVariable("id")); } + | { $$ = CYNew CYType(CYNew CYTypeVariable("id")); } ; MessageParameter - : Word[tag] ":" TypeOpt[type] BindingIdentifier[identifier] { $type->identifier_ = $identifier; $$ = CYNew CYMessageParameter($tag, $type); } + : Word[tag] ":" TypeOpt[type] BindingIdentifier[identifier] { $$ = CYNew CYMessageParameter($tag, $type, $identifier); } ; MessageParameterList @@ -2034,12 +2235,12 @@ MessageParameterList MessageParameterListOpt : MessageParameterList[pass] { $$ = $pass; } - | { $$ = NULL; } + | TypedParameterList_[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); /*XXX*/ if ($formal->parameters_ != NULL) CYERR(@$, "temporarily unsupported"); $$ = NULL; } ; MessageParameters : MessageParameterList[pass] { $$ = $pass; } - | Word[tag] { $$ = CYNew CYMessageParameter($tag, NULL); } + | Word[tag] { $$ = CYNew CYMessageParameter($tag); } ; ClassMessageDeclaration @@ -2152,15 +2353,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()); } @@ -2203,20 +2418,40 @@ 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] { CYIdentifier *identifier; if ($typed->name_ == NULL) identifier = NULL; else { identifier = $typed->name_->Identifier(); if (identifier == NULL) CYERR($typed->location_, "invalid identifier"); } $$ = $formal; $$->parameters_ = CYNew CYTypedParameter($typed, identifier, $$->parameters_); } + | "..." { $$ = CYNew CYTypedFormal(true); } ; TypedParameterListOpt : TypedParameterList[pass] { $$ = $pass; } - | { $$ = NULL; } + | "void" { $$ = CYNew CYTypedFormal(false); } + | { $$ = CYNew CYTypedFormal(false); } + ; + +TypedParameters + : TypedParameterListOpt[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); $$ = $formal->parameters_; } + ; + +PrimaryExpression + : "[" LexOf "&" "]" "(" TypedParameters[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); } + ; +/* }}} */ +/* Cycript (C): Structure Definitions {{{ */ +IdentifierNoOf + : "struct" NewLineOpt { $$ = CYNew CYIdentifier("struct"); } + ; + +Statement__ + : "struct" NewLineNot IdentifierType[name] "{" StructFieldListOpt[fields] "}" { $$ = CYNew CYStructDefinition($name, CYNew CYStructTail($fields)); } ; PrimaryExpression - : "[" LexOf "&" "]" "(" TypedParameterListOpt[parameters] ")" "->" TypedIdentifierMaybe[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); } + : "(" LexOf "struct" NewLineOpt IdentifierType[name] TypeQualifierRightOpt[typed] ")" { $typed->specifier_ = CYNew CYTypeReference(CYTypeReferenceStruct, $name); $$ = CYNew CYTypeExpression($typed); } + | "(" LexOf "struct" NewLineOpt AutoComplete { driver.mode_ = CYDriver::AutoStruct; YYACCEPT; } ; /* }}} */ /* Cycript (C): Type Definitions {{{ */ @@ -2224,12 +2459,16 @@ IdentifierNoOf : "typedef" NewLineOpt { $$ = CYNew CYIdentifier("typedef"); } ; +TypeDefinition + : "typedef" NewLineNot TypedIdentifierDefinition[typed] TerminatorHard { CYIdentifier *identifier; if ($typed->name_ == NULL) identifier = NULL; else { identifier = $typed->name_->Identifier(); if (identifier == NULL) CYERR($typed->location_, "invalid identifier"); } $$ = CYNew CYTypeDefinition($typed, identifier); } + ; + Statement__ - : "typedef" NewLineNot TypedIdentifierYes[typed] Terminator { $$ = CYNew CYTypeDefinition($typed); } + : TypeDefinition[pass] { $$ = $pass; } ; PrimaryExpression - : "(" LexOf "typedef" NewLineOpt TypedIdentifierNo[typed] ")" { $$ = CYNew CYTypeExpression($typed); } + : "(" LexOf "typedef" NewLineOpt TypedIdentifierEncoding[typed] ")" { $$ = CYNew CYTypeExpression($typed); } ; /* }}} */ /* Cycript (C): extern "C" {{{ */ @@ -2237,11 +2476,33 @@ IdentifierNoOf : "extern" NewLineOpt { $$ = CYNew CYIdentifier("extern"); } ; +ExternCStatement + : TypedIdentifierField[typed] TerminatorHard { CYIdentifier *identifier; if ($typed->name_ == NULL) identifier = NULL; else { identifier = $typed->name_->Identifier(); if (identifier == NULL) CYERR($typed->location_, "invalid identifier"); } $$ = CYNew CYExternalDefinition(CYNew CYString("C"), $typed, identifier); } + | TypeDefinition[pass] { $$ = $pass; } + ; + +ExternCStatementListOpt + : ExternCStatement[statement] ExternCStatementListOpt[next] { $$ = $statement; CYSetLast($$) = $next; } + | { $$ = NULL; } + ; + +ExternC + : "{" ExternCStatementListOpt[pass] "}" { $$ = $pass; } + | 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"); } TypedIdentifierYes[typed] Terminator { $$ = CYNew CYExternal($abi, $typed); } + : "extern" NewLineNot ABI[abi] ExternC[pass] { $$ = $pass; } ; -/* }}} */ +PrimaryExpression + : "(" LexOf "extern" NewLineOpt ABI[abi] TypedIdentifierField[typed] ")" { $$ = CYNew CYExternalExpression(CYNew CYString("C"), $typed, $typed->name_); } + ; +/* }}} */ @end @begin E4X @@ -2461,16 +2722,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; } @@ -2492,16 +2760,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); } ; -PostfixExpression - : PostfixExpression[lhs] RubyProcExpression[rhs] LexNewLineOrOpt { $$ = CYNew CYRubyBlock($lhs, $rhs); } +BracedExpression_ + : AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; } + | BracedExpression_[lhs] { if (!$lhs->IsNew()) CYMAP(OpenBrace_, OpenBrace); } BracedParameter[rhs] LexNewLineOrOpt { $rhs->SetLeft($lhs); $$ = $rhs; } + ; + +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()); } ; /* }}} */