<XMLContent>"</" L return tk::LeftSlash;
@end
+"..." L C return tk::PeriodPeriodPeriod;
+
@begin E4X
"::" L C return tk::ColonColon;
".." L C return tk::PeriodPeriod;
%token Percent "%"
%token PercentEqual "%="
%token Period "."
+%token PeriodPeriodPeriod "..."
%token Pipe "|"
%token PipeEqual "|="
%token PipePipe "||"
%type <assignment_> AssignmentExpression_
%type <expression_> AssignmentExpressionNoBF
%type <expression_> AssignmentExpressionNoIn
+%type <identifier_> BindingIdentifier
%type <expression_> BitwiseANDExpression
%type <expression_> BitwiseANDExpressionNoBF
%type <expression_> BitwiseANDExpressionNoIn
%type <statement_> Block
%type <statement_> Block_
%type <boolean_> BooleanLiteral
+%type <declaration_> BindingElement
%type <expression_> BitwiseORExpression
%type <expression_> BitwiseORExpressionNoBF
%type <expression_> BitwiseORExpressionNoIn
%type <expression_> BitwiseXORExpressionNoBF
%type <expression_> BitwiseXORExpressionNoIn
%type <statement_> BreakStatement
+%type <statement_> BreakableStatement
%type <expression_> CallExpression
%type <expression_> CallExpressionNoBF
%type <clause_> CaseBlock
%type <expression_> ConditionalExpressionNoBF
%type <expression_> ConditionalExpressionNoIn
%type <statement_> ContinueStatement
+%type <statement_> DebuggerStatement
+%type <statement_> Declaration
%type <clause_> DefaultClause
%type <statement_> DoWhileStatement
%type <expression_> Element
%type <for_> ForStatementInitialiser
%type <statement_> ForInStatement
%type <forin_> ForInStatementInitialiser
+%type <declaration_> FormalParameter
%type <functionParameter_> FormalParameterList
%type <functionParameter_> FormalParameterList_
+%type <functionParameter_> FormalParameterListOpt
%type <statement_> FunctionBody
%type <statement_> FunctionDeclaration
%type <expression_> FunctionExpression
%type <statement_> LabelledStatement
%type <expression_> LeftHandSideExpression
%type <expression_> LeftHandSideExpressionNoBF
+//%type <expression_> LetExpression
%type <statement_> LetStatement
+%type <statement_> LexicalDeclaration
%type <literal_> Literal
%type <literal_> LiteralNoRE
%type <literal_> LiteralRE
%type <expression_> PrimaryExpressionNoRE
%type <expression_> PrimaryExpressionBF
%type <statement_> Program
+%type <statement_> ProgramBody
+%type <statement_> ProgramBodyOpt
%type <propertyName_> PropertyName
%type <propertyName_> PropertyName_
%type <property_> PropertyNameAndValueList
%type <functionParameter_> RubyProcParametersOpt
%type <expression_> ShiftExpression
%type <expression_> ShiftExpressionNoBF
-%type <statement_> SourceElement
-%type <statement_> SourceElement_
-%type <statement_> SourceElements
+%type <declaration_> SingleNameBinding
%type <statement_> Statement
%type <statement_> Statement_
%type <statement_> StatementList
%type <statement_> StatementListOpt
+%type <statement_> StatementListItem
%type <statement_> SwitchStatement
%type <statement_> ThrowStatement
%type <statement_> TryStatement
| "transient" { $$ = $1; }
| "volatile" { $$ = $1; }
- | "let" { $$ = $1; }
+ // XXX: is this allowed?! | "let" { $$ = $1; }
| "yield" { $$ = $1; }
| "each" { $$ = $1; }
| EmptyStatement { $$ = $1; }
| ExpressionStatement { $$ = $1; }
| IfStatement { $$ = $1; }
- | IterationStatement { $$ = $1; }
+ | BreakableStatement { $$ = $1; }
| ContinueStatement { $$ = $1; }
| BreakStatement { $$ = $1; }
| ReturnStatement { $$ = $1; }
| WithStatement { $$ = $1; }
| LabelledStatement { $$ = $1; }
- | SwitchStatement { $$ = $1; }
| ThrowStatement { $$ = $1; }
| TryStatement { $$ = $1; }
+ | DebuggerStatement { $$ = $1; }
;
Statement
: LexSetRegExp Statement_ { $$ = $2; }
;
+
+Declaration
+ : FunctionDeclaration { $$ = $1; }
+ | LexicalDeclaration { $$ = $1; }
+ ;
+
+BreakableStatement
+ : IterationStatement { $$ = $1; }
+ | SwitchStatement { $$ = $1; }
+ ;
/* }}} */
/* 12.1 Block {{{ */
Block_
;
StatementList
- : Statement StatementListOpt { $1->SetNext($2); $$ = $1; }
+ : StatementListItem StatementListOpt { $1->SetNext($2); $$ = $1; }
;
StatementListOpt
: StatementList { $$ = $1; }
| LexSetRegExp { $$ = NULL; }
;
+
+StatementListItem
+ : Statement { $$ = $1; }
+ | LexSetRegExp Declaration { $$ = $2; }
+ ;
+/* }}} */
+/* 12.2 Declarations {{{ */
+BindingIdentifier
+ : Identifier { $$ = $1; }
+ ;
+
+// XXX: BindingPattern
+/* }}} */
+/* 12.2.1 Let and Const Declarations {{{ */
+LexicalDeclaration
+ : LetOrConst VariableDeclarationList Terminator { $$ = CYNew CYVar($2); }
+ ;
+
+LetOrConst
+ : "let"
+ | "const"
+ ;
/* }}} */
-/* 12.2 Variable Statement {{{ */
+/* 12.2.2 Variable Statement {{{ */
VariableStatement
: "var" VariableDeclarationList Terminator { $$ = CYNew CYVar($2); }
;
;
VariableDeclaration
- : Identifier InitialiserOpt { $$ = CYNew CYDeclaration($1, $2); }
+ : BindingIdentifier InitialiserOpt { $$ = CYNew CYDeclaration($1, $2); }
+ // XXX: | BindingPattern Initialiser { $$ = CYNew CYDeclaration($1, $2); }
;
VariableDeclarationNoIn
- : Identifier InitialiserNoInOpt { $$ = CYNew CYDeclaration($1, $2); }
+ : BindingIdentifier InitialiserNoInOpt { $$ = CYNew CYDeclaration($1, $2); }
+ // XXX: | BindingPattern InitialiserNoIn { $$ = CYNew CYDeclaration($1, $2); }
;
InitialiserOpt
: "=" AssignmentExpressionNoIn { $$ = $2; }
;
/* }}} */
+/* 12.2.4 Destructuring Binding Patterns {{{ */
+// XXX: *
+
+BindingElement
+ : SingleNameBinding { $$ = $1; }
+ ;
+
+SingleNameBinding
+ : BindingIdentifier InitialiserOpt { $$ = CYNew CYDeclaration($1, $2); }
+ ;
+/* }}} */
/* 12.3 Empty Statement {{{ */
EmptyStatement
: ";" { $$ = CYNew CYEmpty(); }
| { $$ = NULL; }
;
/* }}} */
+/* 12.14 The debugger Statement {{{ */
+DebuggerStatement
+ : "debugger" Terminator { $$ = CYNew CYDebugger(); }
+ ;
+/* }}} */
/* 13 Function Definition {{{ */
FunctionDeclaration
- : "function" Identifier "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionStatement($2, $4, $7); }
+ : "function" Identifier "(" FormalParameterListOpt ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionStatement($2, $4, $7); }
;
FunctionExpression
- : "function" IdentifierOpt "(" FormalParameterList ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionExpression($2, $4, $7); }
+ : "function" IdentifierOpt "(" FormalParameterListOpt ")" Brace FunctionBody "}" { $$ = CYNew CYFunctionExpression($2, $4, $7); }
;
FormalParameterList_
| { $$ = NULL; }
;
-FormalParameterList
- : Identifier FormalParameterList_ { $$ = CYNew CYFunctionParameter($1, $2); }
+FormalParameterListOpt
+ : FormalParameterList
| { $$ = NULL; }
;
+FormalParameterList
+ // XXX: : FunctionRestParameter { $$ = $1; }
+ : FormalParameter FormalParameterList_ { $$ = CYNew CYFunctionParameter($1, $2); }
+ ;
+
+/* XXX: FunctionRestParameter
+ : "..." BindingIdentifier { $$ = CYNew CYFunctionRestParameter($2); }
+ ;*/
+
+FormalParameter
+ : BindingElement { $$ = $1; }
+ ;
+
FunctionBody
- : SourceElements { $$ = $1; }
+ : StatementListOpt { $$ = $1; }
;
/* }}} */
/* 14 Program {{{ */
Program
- : SourceElements { driver.program_ = CYNew CYProgram($1); }
- ;
-
-SourceElements
- : SourceElement SourceElements { $1->SetNext($2); $$ = $1; }
- | LexSetRegExp { $$ = NULL; }
+ : ProgramBodyOpt { driver.program_ = CYNew CYProgram($1); }
;
-SourceElement_
- : Statement_ { $$ = $1; }
- | FunctionDeclaration { $$ = $1; }
+ProgramBodyOpt
+ : ProgramBody { $$ = $1; }
+ | { $$ = NULL; }
;
-SourceElement
- : LexSetRegExp SourceElement_ { $$ = $2; }
+ProgramBody
+ : StatementList { $$ = $1; }
;
/* }}} */
| StringLiteral
;
-SourceElement_
+StatementListItem
: "@import" ImportPath { $$ = CYNew CYImport(); }
;
/* }}} */
: "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = CYNew CYForEachIn($4, $6, $8); }
;
/* }}} */
+/* JavaScript 1.7: let Expressions {{{ */
+/*LetExpression
+ : "let" "(" VariableDeclarationList ")" Expression { $$ = CYNew CYLetExpression($3, $5); }
+ ;
+
+MemberExpression
+ : LexSetRegExp LetExpression { $$ = $2; }
+ ;*/
+/* }}} */
/* JavaScript 1.7: let Statements {{{ */
LetStatement
- : "let" "(" VariableDeclarationList ")" Statement { $$ = CYNew CYLet($3, $5); }
+ : "let" "(" VariableDeclarationList ")" Statement { $$ = CYNew CYLetStatement($3, $5); }
;
Statement_
;
/* }}} */
-/* 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_ { $$ = CYNew CYOptionalFunctionParameter($1, $3, $4); }
- ;
-/* }}} */
/* JavaScript FTW: Ruby Blocks {{{ */
RubyProcParameterList_
: "," RubyProcParameterList { $$ = $2; }
;
RubyProcParameterList
- : Identifier RubyProcParameterList_ { $$ = CYNew CYFunctionParameter($1, $2); }
+ : Identifier RubyProcParameterList_ { $$ = CYNew CYFunctionParameter(CYNew CYDeclaration($1), $2); }
| { $$ = NULL; }
;
CYStatement *CYCategory::Replace(CYContext &context) {
CYVariable *cyc($V("$cyc")), *cys($V("$cys"));
- return $E($C1($F(NULL, $P5("$cys", "$cyp", "$cyc", "$cyn", "$cyt"), $$->*
+ return $E($C1($F(NULL, $P5($L("$cys"), $L("$cyp"), $L("$cyc"), $L("$cyn"), $L("$cyt")), $$->*
$E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
$E($ CYAssign(cyc, cys))->*
$E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
CYExpression *name(name_ != NULL ? name_->ClassName(context, false) : $C1($V("$cyq"), $S("CY$")));
- return $C1($F(NULL, $P6("$cys", "$cyp", "$cyc", "$cyn", "$cyt", "$cym"), $$->*
+ return $C1($F(NULL, $P6($L("$cys"), $L("$cyp"), $L("$cyc"), $L("$cyn"), $L("$cyt"), $L("$cym")), $$->*
$E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
$E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->*
$E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
$E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"),
$V(instance_ ? "$cyc" : "$cym"),
cyn,
- $N2($V("Functor"), $F(NULL, $P2("self", "_cmd", parameters_->Parameters(context)), $$->*
- $ CYVar($L1($L($I("$cyr"), $N2($V("Super"), self, _class))))->*
+ $N2($V("Functor"), $F(NULL, $P2($L("self"), $L("_cmd"), parameters_->Parameters(context)), $$->*
+ $ CYVar($L1($L("$cyr", $N2($V("Super"), self, _class))))->*
$ CYReturn($C1($M($F(NULL, NULL, code_), $S("call")), self))
), cyt),
cyt
CYFunctionParameter *CYMessageParameter::Parameters(CYContext &context) const { $T(NULL)
CYFunctionParameter *next(next_->Parameters(context));
- return name_ == NULL ? next : $ CYFunctionParameter(name_, next);
+ return name_ == NULL ? next : $ CYFunctionParameter($ CYDeclaration(name_), next);
}
CYSelector *CYMessageParameter::Selector(CYContext &context) const {
out << next_;
}
+void CYDebugger::Output(CYOutput &out, CYFlags flags) const {
+ out << "debugger" << ';';
+}
+
void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const {
out << "var";
Output(out, CYRight(flags));
void CYDeclarations::Output(CYOutput &out, CYFlags flags) const {
const CYDeclarations *declaration(this);
bool first(true);
- output:
- CYDeclarations *next(declaration->next_);
- CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags));
- first = false;
- declaration->declaration_->Output(out, jacks);
- if (next != NULL) {
+ for (;;) {
+ CYDeclarations *next(declaration->next_);
+
+ CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags));
+ first = false;
+ declaration->declaration_->Output(out, jacks);
+
+ if (next == NULL)
+ break;
+
out << ',' << ' ';
declaration = next;
- goto output;
}
}
}
void CYFunctionParameter::Output(CYOutput &out) const {
- out << *name_;
+ initialiser_->Output(out, CYNoFlags);
if (next_ != NULL)
out << ',' << ' ' << *next_;
}
statement_->Single(out, CYRight(flags));
}
-void CYLet::Output(CYOutput &out, CYFlags flags) const {
+void CYLetStatement::Output(CYOutput &out, CYFlags flags) const {
out << "let" << ' ' << '(' << *declarations_ << ')';
code_->Single(out, CYRight(flags));
}
out << ')';
}
-void CYOptionalFunctionParameter::Output(CYOutput &out) const {
- out << *name_ << '=';
- initializer_->Output(out, CYAssign::Precedence_, CYNoFlags);
- if (next_ != NULL)
- out << ',' << ' ' << *next_;
-}
-
void CYPostfix::Output(CYOutput &out, CYFlags flags) const {
lhs_->Output(out, Precedence(), CYLeft(flags));
out << Operator();
virtual CYExpression *Replace(CYContext &context) = 0;
virtual CYAssignment *Assignment(CYContext &context) = 0;
+
+ virtual void Output(CYOutput &out, CYFlags flags) const = 0;
};
struct CYNumber;
void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYDeclaration;
+
struct CYFunctionParameter :
CYNext<CYFunctionParameter>,
CYThing
{
- CYIdentifier *name_;
+ CYForInInitialiser *initialiser_;
- CYFunctionParameter(CYIdentifier *name, CYFunctionParameter *next = NULL) :
+ CYFunctionParameter(CYForInInitialiser *initialiser, CYFunctionParameter *next = NULL) :
CYNext<CYFunctionParameter>(next),
- name_(name)
- {
- }
-
- virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
- virtual void Output(CYOutput &out) const;
-};
-
-struct CYOptionalFunctionParameter :
- CYFunctionParameter
-{
- CYExpression *initializer_;
-
- CYOptionalFunctionParameter(CYIdentifier *name, CYExpression *initializer, CYFunctionParameter *next = NULL) :
- CYFunctionParameter(name, next),
- initializer_(initializer)
+ initialiser_(initialiser)
{
}
- virtual CYFunctionParameter *Replace(CYContext &context, CYBlock &code);
- virtual void Output(CYOutput &out) const;
+ void Replace(CYContext &context, CYBlock &code);
+ void Output(CYOutput &out) const;
};
struct CYComprehension :
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYLet :
+struct CYLetStatement :
CYStatement
{
CYDeclarations *declarations_;
CYStatement *code_;
- CYLet(CYDeclarations *declarations, CYStatement *code) :
+ CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
declarations_(declarations),
code_(code)
{
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYDebugger :
+ CYStatement
+{
+ CYDebugger()
+ {
+ }
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYCondition :
CYExpression
{
CYExpression *CYArrayComprehension::Replace(CYContext &context) {
CYVariable *cyv($V("$cyv"));
- return $C0($F(NULL, $P1("$cyv", comprehensions_->Parameters(context)), $$->*
+ return $C0($F(NULL, $P1($L("$cyv"), comprehensions_->Parameters(context)), $$->*
$E($ CYAssign(cyv, $ CYArray()))->*
comprehensions_->Replace(context, $E($C1($M(cyv, $S("push")), expression_)))->*
$ CYReturn(cyv)
CYIdentifier *unique(nextlocal_->identifier_->Replace(context));
CYStatement *declare(
- $ CYVar($L1($L(unique, $ CYObject()))));
+ $ CYVar($L1($ CYDeclaration(unique, $ CYObject()))));
cy::Syntax::Catch *rescue(
$ cy::Syntax::Catch(cye, $$->*
return this;
}
+CYStatement *CYDebugger::Replace(CYContext &context) {
+ return this;
+}
+
CYAssignment *CYDeclaration::Assignment(CYContext &context) {
if (initialiser_ == NULL)
return NULL;
}
CYStatement *CYDeclaration::ForEachIn(CYContext &context, CYExpression *value) {
- return $ CYVar($L1($L(identifier_, value)));
+ return $ CYVar($L1($ CYDeclaration(identifier_, value)));
}
CYExpression *CYDeclaration::Replace(CYContext &context) {
}
CYFunctionParameter *CYDeclarations::Parameter(CYContext &context) { $T(NULL)
- return $ CYFunctionParameter(declaration_->identifier_, next_->Parameter(context));
+ return $ CYFunctionParameter($ CYDeclaration(declaration_->identifier_), next_->Parameter(context));
}
CYArgument *CYDeclarations::Argument(CYContext &context) { $T(NULL)
}
CYFunctionParameter *CYForInComprehension::Parameter(CYContext &context) const {
- return $ CYFunctionParameter(name_);
+ return $ CYFunctionParameter($ CYDeclaration(name_));
}
CYStatement *CYForInComprehension::Replace(CYContext &context, CYStatement *statement) const {
CYIdentifier *cys($I("$cys")), *cyt($I("$cyt"));
- return $ CYLet($L2($L(cys, set_), $L(cyt)), $$->*
+ return $ CYLetStatement($L2($ CYDeclaration(cys, set_), $ CYDeclaration(cyt)), $$->*
$ CYForIn($V(cyt), $V(cys), $ CYBlock($$->*
initialiser_->ForEachIn(context, $M($V(cys), $V(cyt)))->*
code_
}
CYFunctionParameter *CYForEachInComprehension::Parameter(CYContext &context) const {
- return $ CYFunctionParameter(name_);
+ return $ CYFunctionParameter($ CYDeclaration(name_));
}
CYStatement *CYForEachInComprehension::Replace(CYContext &context, CYStatement *statement) const {
CYIdentifier *cys($I("cys"));
- return $E($C0($F(NULL, $P1("$cys"), $$->*
+ return $E($C0($F(NULL, $P1($L("$cys")), $$->*
$E($ CYAssign($V(cys), set_))->*
$ CYForIn($V(name_), $V(cys), $ CYBlock($$->*
$E($ CYAssign($V(name_), $M($V(cys), $V(name_))))->*
if (!outer && name_ != NULL)
Inject(context);
- if (parameters_ != NULL)
- parameters_ = parameters_->Replace(context, code_);
-
+ parameters_->Replace(context, code_);
code_.Replace(context);
if (localize)
return this;
}
-CYFunctionParameter *CYFunctionParameter::Replace(CYContext &context, CYBlock &code) {
- context.Replace(name_);
- context.scope_->Declare(context, name_, CYIdentifierArgument);
- if (next_ != NULL)
- next_ = next_->Replace(context, code);
- return this;
+void CYFunctionParameter::Replace(CYContext &context, CYBlock &code) { $T()
+ CYAssignment *assignment(initialiser_->Assignment(context));
+ context.Replace(initialiser_);
+
+ next_->Replace(context, code);
+
+ if (assignment != NULL)
+ // XXX: this cast is quite incorrect
+ code.AddPrev($ CYIf($ CYIdentical($ CYTypeOf(dynamic_cast<CYExpression *>(initialiser_)), $S("undefined")), $$->*
+ $E(assignment)
+ ));
}
CYStatement *CYFunctionStatement::Replace(CYContext &context) {
return this;
}
-CYStatement *CYLet::Replace(CYContext &context) {
+CYStatement *CYLetStatement::Replace(CYContext &context) {
return $E($ CYCall(CYNonLocalize(context, $ CYFunctionExpression(NULL, declarations_->Parameter(context), code_)), declarations_->Argument(context)));
}
return this;
}
-CYFunctionParameter *CYOptionalFunctionParameter::Replace(CYContext &context, CYBlock &code) {
- CYFunctionParameter *parameter($ CYFunctionParameter(name_, next_));
- parameter = parameter->Replace(context, code);
- context.Replace(initializer_);
-
- CYVariable *name($V(name_));
- code.AddPrev($ CYIf($ CYIdentical($ CYTypeOf(name), $S("undefined")), $$->*
- $E($ CYAssign(name, initializer_))
- ));
-
- return parameter;
-}
-
CYExpression *CYPostfix::Replace(CYContext &context) {
context.Replace(lhs_);
return this;
CYStatements()
#define $P1(arg0, args...) \
- $P($I(arg0), ##args)
+ $P(arg0, ##args)
#define $P2(arg0, arg1, args...) \
- $P($I(arg0), $P1(arg1, ##args))
+ $P(arg0, $P1(arg1, ##args))
#define $P3(arg0, arg1, arg2, args...) \
- $P($I(arg0), $P2(arg1, arg2, ##args))
+ $P(arg0, $P2(arg1, arg2, ##args))
#define $P4(arg0, arg1, arg2, arg3, args...) \
- $P($I(arg0), $P3(arg1, arg2, arg3, ##args))
+ $P(arg0, $P3(arg1, arg2, arg3, ##args))
#define $P5(arg0, arg1, arg2, arg3, arg4, args...) \
- $P($I(arg0), $P4(arg1, arg2, arg3, arg4, ##args))
+ $P(arg0, $P4(arg1, arg2, arg3, arg4, ##args))
#define $P6(arg0, arg1, arg2, arg3, arg4, arg5, args...) \
- $P($I(arg0), $P5(arg1, arg2, arg3, arg4, arg5, ##args))
+ $P(arg0, $P5(arg1, arg2, arg3, arg4, arg5, ##args))
#define $C(args...) \
($ CYCall(args))
#define $N5(func, args...) \
$N(func, $C5_(args))
-#define $L(args...) \
- $ CYDeclaration(args)
+#define $L(arg0, args...) \
+ $ CYDeclaration($I(arg0), ##args)
#define $L1(arg0) \
$ CYDeclarations(arg0)
#define $L2(arg0, args...) \