-/* 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 {{{ */
#include "Driver.hpp"
#include "Parser.hpp"
#include "Stack.hpp"
+#include "Syntax.hpp"
#define CYNew new(driver.pool_)
@begin ObjectiveC
%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_; }
%union { CYParenthetical *parenthetical_; }
%union { CYProperty *property_; }
%union { CYPropertyName *propertyName_; }
-%union { CYRubyProc *rubyProc_; }
+%union { CYTypeSigning signing_; }
%union { CYSpan *span_; }
%union { CYStatement *statement_; }
%union { CYString *string_; }
case CYMarkModule:
driver.hold_ = yytranslate_(token::MarkModule);
break;
+ case CYMarkExpression:
+ driver.hold_ = yytranslate_(token::MarkExpression);
+ break;
}
};
@begin E4X ObjectiveC
%token At "@"
-%token Pound "#"
@end
%token Ampersand "&"
%token Comma ","
%token Question "?"
%token SemiColon ";"
+%token Pound "#"
%token NewLine "\n"
%token __ ""
%token _goto_ "goto"
%token _implements_ "implements"
%token _int_ "int"
+%token ___int128_ "__int128"
%token _interface_ "interface"
%token _let_ "let"
%token _let__ "!let"
%type <binding_> BindingElement
%type <expression_> BitwiseORExpression
%type <expression_> BitwiseXORExpression
+%type <target_> BracedExpression_
+%type <target_> BracedExpression
%type <statement_> BreakStatement
%type <statement_> BreakableStatement
%type <expression_> CallExpression_
%type <bool_> RegularExpressionSlash
%type <expression_> RelationalExpression
%type <statement_> ReturnStatement
-%type <target_> RubyBlockExpression_
-%type <target_> RubyBlockExpression
-%type <rubyProc_> RubyProcExpression
+%type <braced_> BracedParameter
%type <functionParameter_> RubyProcParameterList_
%type <functionParameter_> RubyProcParameterList
%type <functionParameter_> RubyProcParameters
%type <expression_> YieldExpression
@begin C
+%type <constant_> EnumConstantListOpt_
+%type <constant_> EnumConstantListOpt
+%type <number_> IntegerNumber
%type <integral_> IntegerType
%type <integral_> IntegerTypeOpt
%type <typedIdentifier_> PrefixedType
+%type <specifier_> PrimitiveReference
%type <specifier_> PrimitiveType
%type <structField_> StructFieldListOpt
%type <typedIdentifier_> SuffixedType
%type <typedIdentifier_> TypeSignifier
%type <typedIdentifier_> TypeSignifierNone
%type <typedIdentifier_> TypeSignifierOpt
+%type <signing_> TypeSigning
%type <modifier_> ParameterTail
%type <modifier_> TypeQualifierLeft
%type <modifier_> TypeQualifierLeftOpt
%type <typedIdentifier_> TypedIdentifierField
%type <typedIdentifier_> TypedIdentifierMaybe
%type <typedIdentifier_> TypedIdentifierNo
+%type <typedIdentifier_> TypedIdentifierTagged
%type <typedIdentifier_> TypedIdentifierYes
%type <typedFormal_> TypedParameterList_
%type <typedFormal_> TypedParameterList
%start Program
%token MarkModule
%token MarkScript
+%token MarkExpression
%%
Program
: MarkScript Script
| MarkModule Module
+ | MarkExpression Expression[expression] { driver.context_ = $expression; }
;
/* Lexer State {{{ */
: 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"); }
;
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); }
;
;
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; }
| { $$ = 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; }
- | "char" { $$ = CYNew CYTypeCharacter(CYTypeNeutral); }
- | "signed" "char" { $$ = CYNew CYTypeCharacter(CYTypeSigned); }
- | "unsigned" "char" { $$ = CYNew CYTypeCharacter(CYTypeUnsigned); }
- | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference($name); }
+ | 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] "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
| "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); }
- | TypeQualifierLeftOpt[modifier] PrimitiveType[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+ | TypeQualifierLeftOpt[modifier] PrimitiveReference[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
;
TypedIdentifierYes
: TypedIdentifierMaybe[typed] { if ($typed->identifier_ != 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; }
- | TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+ | TypedIdentifierTagged[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; }
;
TypedIdentifierEncoding
: TypedIdentifierNo[pass] { $$ = $pass; }
- | TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+ | TypedIdentifierTagged[typed] { if ($typed->identifier_ != 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->identifier_ == 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
;
PrimaryExpression
- : "(" LexOf "struct" NewLineOpt IdentifierType[name] TypeQualifierRightOpt[typed] ")" { $typed->specifier_ = CYNew CYTypeReference($name); $$ = CYNew CYTypeExpression($typed); }
+ : "(" 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 {{{ */
;
ExternCStatement
- : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
+ : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternalDefinition(CYNew CYString("C"), $typed); }
| TypeDefinition[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"); } 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
: 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_
| { $$ = 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 {{{ */