{
in_.push(false);
return_.push(false);
+ super_.push(false);
template_.push(false);
yield_.push(false);
#include "Pooling.hpp"
#include "Standard.hpp"
+struct CYClassTail;
struct CYExpression;
struct CYScript;
struct CYWord;
std::stack<bool> in_;
std::stack<bool> return_;
+ std::stack<bool> super_;
std::stack<bool> template_;
std::stack<bool> yield_;
+ std::stack<CYClassTail *> class_;
+
bool newline_;
bool last_;
bool next_;
return *next;
}
+template <typename Type_>
+struct CYList {
+ Type_ *first_;
+ Type_ *last_;
+
+ CYList(Type_ *first = NULL) :
+ first_(first),
+ last_(CYGetLast(first))
+ {
+ }
+
+ operator Type_ *() const {
+ return first_;
+ }
+
+ Type_ *operator ->() const {
+ return first_;
+ }
+
+ CYList &operator ->*(Type_ *next) {
+ if (next != NULL)
+ if (first_ == NULL) {
+ first_ = next;
+ last_ = next;
+ } else for (;; last_ = last_->next_)
+ if (last_->next_ == NULL) {
+ last_->next_ = next;
+ last_ = next;
+ break;
+ }
+ return *this;
+ }
+
+ CYList &operator ->*(CYList &next) {
+ if (*this == NULL)
+ *this = next;
+ else if (next != NULL) {
+ last_->next_ = next.first_;
+ last_ = next.last_;
+ }
+ return *this;
+ }
+};
+
#define CYForEach(value, list) \
for (__typeof__(*list) *value(list); value != NULL; value = value->next_)
#include "ObjectiveC/Syntax.hpp"
void CYCategory::Output(CYOutput &out, CYFlags flags) const {
- out << "(function($cys,$cyp,$cyc,$cyn,$cyt){";
- out << "$cyp=object_getClass($cys);";
- out << "$cyc=$cys;";
- if (messages_ != NULL)
- messages_->Output(out, true);
- out << "})(";
- name_->ClassName(out, true);
- out << ')';
- out << ';';
-}
+ out << "@implementation" << ' ' << *name_ << ' ' << '(' << ')' << '\n';
+ ++out.indent_;
-void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
- // XXX: I don't necc. need the ()s
- out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
- out << "$cyp=object_getClass($cys);";
- out << "$cyc=objc_allocateClassPair($cys,";
- name_->ClassName(out, false);
- out << ",0);";
- out << "$cym=object_getClass($cyc);";
- if (fields_ != NULL)
- fields_->Output(out);
- if (messages_ != NULL)
- messages_->Output(out, false);
- if (protocols_ != NULL) {
- out << '<';
- out << *protocols_;
- out << '>';
+ CYForEach (message, messages_) {
+ message->Output(out);
+ out << '\n';
}
- out << "objc_registerClassPair($cyc);";
- out << "return $cyc;";
- out << "}(";
- if (super_ != NULL)
- super_->Output(out, CYAssign::Precedence_, CYNoFlags);
- else
- out << "null";
- out << "))";
+
+ --out.indent_;
+ out << "@end";
+}
+
+void CYImplementation::Output(CYOutput &out, CYFlags flags) const {
+ out << "@implementation" << ' ' << *name_ << '\n';
+ ++out.indent_;
+
+ // XXX: implement
+
+ --out.indent_;
+ out << "@end";
}
-void CYClassField::Output(CYOutput &out) const {
+void CYImplementationField::Output(CYOutput &out) const {
}
void CYInstanceLiteral::Output(CYOutput &out, CYFlags flags) const {
number_->Output(out, CYRight(flags));
}
-void CYMessage::Output(CYOutput &out, bool replace) const {
+void CYMessage::Output(CYOutput &out) const {
out << (instance_ ? '-' : '+');
CYForEach (parameter, parameters_)
CYStatement *CYCategory::Replace(CYContext &context) {
CYVariable *cyc($V("$cyc")), *cys($V("$cys"));
- return $E($C1($F(NULL, $P6($L("$cys"), $L("$cyp"), $L("$cyc"), $L("$cyn"), $L("$cyt"), $L("$cym")), $$->*
+ return $E($C1($F(NULL, $P6($L($I("$cys")), $L($I("$cyp")), $L($I("$cyc")), $L($I("$cyn")), $L($I("$cyt")), $L($I("$cym"))), $$->*
$E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
$E($ CYAssign(cyc, cys))->*
$E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
messages_->Replace(context, true)
- ), name_->ClassName(context, true)));
+ ), $C1($V("objc_getClass"), $S(name_))));
}
-CYStatement *CYClassStatement::Replace(CYContext &context) {
+CYStatement *CYImplementation::Replace(CYContext &context) {
CYVariable *cyc($V("$cyc")), *cys($V("$cys"));
- CYExpression *name(name_->ClassName(context, false));
-
- return $E($C1($F(NULL, $P6($L("$cys"), $L("$cyp"), $L("$cyc"), $L("$cyn"), $L("$cyt"), $L("$cym")), $$->*
+ return $E($C1($F(NULL, $P6($L($I("$cys")), $L($I("$cyp")), $L($I("$cyc")), $L($I("$cyn")), $L($I("$cyt")), $L($I("$cym"))), $$->*
$E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
- $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->*
+ $E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, $S(name_), $D(0))))->*
$E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
protocols_->Replace(context)->*
fields_->Replace(context)->*
), super_ == NULL ? $ CYNull() : super_));
}
-CYStatement *CYClassField::Replace(CYContext &context) const { $T(NULL)
+CYStatement *CYImplementationField::Replace(CYContext &context) const { $T(NULL)
CYVariable *cyn($V("$cyn"));
CYVariable *cyt($V("$cyt"));
$E($C4($V(replace ? "class_replaceMethod" : "class_addMethod"),
$V(instance_ ? "$cyc" : "$cym"),
cyn,
- $N2($V("Functor"), $F(NULL, $P2($L("self"), $L("_cmd"), parameters_->Parameters(context)), $$->*
- $ CYVar($L1($L("$cyr", $N2($V("objc_super"), self, _class))))->*
+ $N2($V("Functor"), $F(NULL, $P2($L($I("self")), $L($I("_cmd")), parameters_->Parameters(context)), $$->*
+ $ CYVar($L1($L($I("$cyr"), $N2($V("objc_super"), self, _class))))->*
$ CYReturn($C1($M($F(NULL, NULL, code_.code_), $S("call")), self))
), cyt),
cyt
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYClassField :
- CYNext<CYClassField>
+struct CYImplementationField :
+ CYNext<CYImplementationField>
{
CYTypedIdentifier *typed_;
- CYClassField(CYTypedIdentifier *typed, CYClassField *next = NULL) :
- CYNext<CYClassField>(next),
+ CYImplementationField(CYTypedIdentifier *typed, CYImplementationField *next = NULL) :
+ CYNext<CYImplementationField>(next),
typed_(typed)
{
}
}
CYStatement *Replace(CYContext &context, bool replace) const;
- void Output(CYOutput &out, bool replace) const;
+ void Output(CYOutput &out) const;
CYExpression *TypeSignature(CYContext &context) const;
};
void Output(CYOutput &out) const;
};
-struct CYClassStatement :
+struct CYImplementation :
CYStatement
{
- CYClassName *name_;
+ CYIdentifier *name_;
CYExpression *super_;
CYProtocol *protocols_;
- CYClassField *fields_;
+ CYImplementationField *fields_;
CYMessage *messages_;
- CYClassStatement(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYClassField *fields, CYMessage *messages) :
+ CYImplementation(CYIdentifier *name, CYExpression *super, CYProtocol *protocols, CYImplementationField *fields, CYMessage *messages) :
name_(name),
super_(super),
protocols_(protocols),
struct CYCategory :
CYStatement
{
- CYClassName *name_;
+ CYIdentifier *name_;
CYMessage *messages_;
- CYCategory(CYClassName *name, CYMessage *messages) :
+ CYCategory(CYIdentifier *name, CYMessage *messages) :
name_(name),
messages_(messages)
{
} }
+void CYClassExpression::Output(CYOutput &out, CYFlags flags) const {
+ bool protect((flags & CYNoClass) != 0);
+ if (protect)
+ out << '(';
+ out << "class";
+ if (name_ != NULL)
+ out << ' ' << *name_;
+ out << *tail_;;
+ if (protect)
+ out << ')';
+}
+
+void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
+ out << "class" << ' ' << *name_ << *tail_;
+}
+
+void CYClassTail::Output(CYOutput &out) const {
+ if (extends_ == NULL)
+ out << ' ';
+ else {
+ out << '\n';
+ ++out.indent_;
+ out << "extends" << ' ';
+ extends_->Output(out, CYAssign::Precedence_ - 1, CYNoFlags);
+ out << '\n';
+ --out.indent_;
+ }
+
+ out << '{' << '\n';
+ ++out.indent_;
+
+ --out.indent_;
+ out << '}';
+}
+
void CYCompound::Output(CYOutput &out, CYFlags flags) const {
if (next_ == NULL)
expression_->Output(out, flags);
}
}
+void CYComputed::PropertyName(CYOutput &out) const {
+ out << '[';
+ expression_->Output(out, CYAssign::Precedence_, CYNoFlags);
+ out << ']';
+}
+
void CYCondition::Output(CYOutput &out, CYFlags flags) const {
test_->Output(out, Precedence() - 1, CYLeft(flags));
out << ' ' << '?' << ' ';
}
void CYExpress::Output(CYOutput &out, CYFlags flags) const {
- expression_->Output(out, flags | CYNoBF);
+ expression_->Output(out, flags | CYNoBFC);
out << ';';
}
-void CYExpression::ClassName(CYOutput &out, bool object) const {
- Output(out, CYAssign::Precedence_, CYNoFlags);
-}
-
void CYExpression::ForIn(CYOutput &out, CYFlags flags) const {
Output(out, flags | CYNoRightHand);
}
out << ' ' << "in" << ' ' << *set_ << ')';
}
-void CYFunction::Output(CYOutput &out, CYFlags flags) const {
- // XXX: one could imagine using + here to save a byte
- bool protect((flags & CYNoFunction) != 0);
- if (protect)
- out << '(';
- out << "function";
- if (name_ != NULL)
- out << ' ' << *name_;
+void CYFunction::Output(CYOutput &out) const {
out << '(' << parameters_ << ')' << ' ';
out << '{' << '\n';
++out.indent_;
out << code_;
--out.indent_;
out << '\t' << '}';
- if (protect)
- out << ')';
}
void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const {
- CYFunction::Output(out, flags);
+ // XXX: one could imagine using + here to save a byte
+ bool protect((flags & CYNoFunction) != 0);
+ if (protect)
+ out << '(';
+ out << "function";
+ if (name_ != NULL)
+ out << ' ' << *name_;
+ CYFunction::Output(out);
+ if (protect)
+ out << ')';
}
void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const {
- CYFunction::Output(out, flags);
+ out << "function" << ' ' << *name_;
+ CYFunction::Output(out);
}
void CYFunctionParameter::Output(CYOutput &out) const {
}
void CYProperty::Output(CYOutput &out) const {
+ if (next_ != NULL || out.pretty_)
+ out << ',';
+ out << '\n' << next_;
+}
+
+void CYPropertyGetter::Output(CYOutput &out) const {
+ out << "get" << ' ';
+ name_->PropertyName(out);
+ CYFunction::Output(out);
+ CYProperty::Output(out);
+}
+
+void CYPropertyMethod::Output(CYOutput &out) const {
+ name_->PropertyName(out);
+ CYFunction::Output(out);
+ CYProperty::Output(out);
+}
+
+void CYPropertySetter::Output(CYOutput &out) const {
+ out << "set" << ' ';
+ name_->PropertyName(out);
+ CYFunction::Output(out);
+ CYProperty::Output(out);
+}
+
+void CYPropertyValue::Output(CYOutput &out) const {
out << '\t';
name_->PropertyName(out);
out << ':' << ' ';
value_->Output(out, CYAssign::Precedence_, CYNoFlags);
- if (next_ != NULL)
- out << ',' << '\n' << *next_;
- else
- out << '\n';
+ CYProperty::Output(out);
}
void CYRegEx::Output(CYOutput &out, CYFlags flags) const {
return value;
}
+void CYSuperAccess::Output(CYOutput &out, CYFlags flags) const {
+ out << "super";
+ if (const char *word = property_->Word())
+ out << '.' << word;
+ else
+ out << '[' << *property_ << ']';
+}
+
+void CYSuperCall::Output(CYOutput &out, CYFlags flags) const {
+ out << "super" << '(' << arguments_ << ')';
+}
+
void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{' << '\n';
++out.indent_;
code_->Single(out, CYRight(flags), CYCompactShort);
}
-void CYWord::ClassName(CYOutput &out, bool object) const {
- if (object)
- out << "objc_getClass(";
- out << '"' << Word() << '"';
- if (object)
- out << ')';
-}
-
void CYWord::Output(CYOutput &out) const {
out << Word();
if (out.options_.verbose_) {
%union { bool bool_; }
+%union { CYMember *access_; }
%union { CYArgument *argument_; }
%union { CYAssignment *assignment_; }
%union { CYBoolean *boolean_; }
%union { CYClause *clause_; }
%union { cy::Syntax::Catch *catch_; }
+%union { CYClassTail *classTail_; }
%union { CYComprehension *comprehension_; }
%union { CYDeclaration *declaration_; }
%union { CYDeclarations *declarations_; }
%union { CYIdentifier *identifier_; }
%union { CYInfix *infix_; }
%union { CYLiteral *literal_; }
-%union { CYMember *member_; }
+%union { CYMethod *method_; }
%union { CYModule *module_; }
%union { CYNull *null_; }
%union { CYNumber *number_; }
@end
@begin ObjectiveC
-%union { CYClassName *className_; }
-%union { CYClassField *classField_; }
%union { CYMessage *message_; }
%union { CYMessageParameter *messageParameter_; }
+%union { CYImplementationField *implementationField_; }
%union { CYProtocol *protocol_; }
%union { CYSelectorPart *selector_; }
@end
%token _return_ "return"
%token _return__ "!return"
%token _super_ "super"
+%token _super__ "!super"
%token _switch_ "switch"
%token _this_ "this"
%token _throw_ "throw"
%token _boolean_ "boolean"
%token _byte_ "byte"
%token _char_ "char"
+%token _constructor_ "constructor"
%token _double_ "double"
%token _final_ "final"
%token _float_ "float"
%token _package_ "package"
%token _private_ "private"
%token _protected_ "protected"
+%token _prototype_ "prototype"
%token _public_ "public"
%token _set_ "set"
%token _short_ "short"
%type <identifier_> CatchParameter
%type <statement_> ClassDeclaration
%type <expression_> ClassExpression
+%type <classTail_> ClassHeritage
+%type <classTail_> ClassHeritageOpt
+%type <classTail_> ClassTail
%type <expression_> Comprehension
%type <comprehension_> ComprehensionFor
%type <comprehension_> ComprehensionIf
%type <comprehension_> ComprehensionTail
-%type <expression_> ComputedPropertyName
+%type <propertyName_> ComputedPropertyName
%type <expression_> ConditionalExpression
%type <statement_> ContinueStatement
%type <statement_> ConciseBody
%type <statement_> GeneratorBody
%type <statement_> GeneratorDeclaration
%type <expression_> GeneratorExpression
-%type <property_> GeneratorMethod
+%type <method_> GeneratorMethod
%type <statement_> HoistableDeclaration
%type <identifier_> Identifier
%type <identifier_> IdentifierType
%type <propertyName_> LiteralPropertyName
%type <expression_> LogicalANDExpression
%type <expression_> LogicalORExpression
-%type <member_> MemberAccess
+%type <access_> MemberAccess
%type <expression_> MemberExpression
-%type <property_> MethodDefinition
+%type <method_> MethodDefinition
%type <module_> ModulePath
%type <expression_> MultiplicativeExpression
%type <expression_> NewExpression
%type <statement_> StatementListOpt
%type <statement_> StatementListItem
%type <functionParameter_> StrictFormalParameters
+%type <expression_> SuperCall
+%type <expression_> SuperProperty
%type <statement_> SwitchStatement
%type <expression_> TemplateLiteral
%type <span_> TemplateSpans
@begin ObjectiveC
%type <expression_> BoxableExpression
%type <statement_> CategoryStatement
-%type <classField_> ClassFieldListOpt
-%type <classField_> ClassFields
-%type <statement_> ClassStatement
%type <expression_> ClassSuperOpt
+%type <implementationField_> ImplementationFieldListOpt
+%type <implementationField_> ImplementationFields
%type <message_> ClassMessageDeclaration
%type <message_> ClassMessageDeclarationListOpt
-%type <className_> ClassName
%type <protocol_> ClassProtocolListOpt
%type <protocol_> ClassProtocols
%type <protocol_> ClassProtocolsOpt
+%type <statement_> ImplementationStatement
%type <expression_> MessageExpression
%type <messageParameter_> MessageParameter
%type <messageParameter_> MessageParameters
LexPushReturnOn: { driver.return_.push(true); };
LexPopReturn: { driver.return_.pop(); };
+LexPushSuperOn: { driver.super_.push(true); };
+LexPushSuperOff: { driver.super_.push(false); };
+LexPopSuper: { driver.super_.pop(); };
+
LexPushYieldOn: { driver.yield_.push(true); };
LexPushYieldOff: { driver.yield_.push(false); };
LexPopYield: { driver.yield_.pop(); };
| "return" { $$ = CYNew CYWord("return"); }
| "!return" { $$ = CYNew CYWord("return"); }
| "super" { $$ = CYNew CYWord("super"); }
+ | "!super" { $$ = CYNew CYWord("super"); }
| "switch" { $$ = CYNew CYWord("switch"); }
| "this" { $$ = CYNew CYWord("this"); }
| "throw" { $$ = CYNew CYWord("throw"); }
| "await" { $$ = CYNew CYIdentifier("await"); }
| "boolean" { $$ = CYNew CYIdentifier("boolean"); }
| "byte" { $$ = CYNew CYIdentifier("byte"); }
+ | "constructor" { $$ = CYNew CYIdentifier("constructor"); }
| "double" { $$ = CYNew CYIdentifier("double"); }
| "each" { $$ = CYNew CYIdentifier("each"); }
| "final" { $$ = CYNew CYIdentifier("final"); }
| "float" { $$ = CYNew CYIdentifier("float"); }
+ | "from" { $$ = CYNew CYIdentifier("from"); }
+ | "get" { $$ = CYNew CYIdentifier("get"); }
| "goto" { $$ = CYNew CYIdentifier("goto"); }
| "implements" { $$ = CYNew CYIdentifier("implements"); }
| "interface" { $$ = CYNew CYIdentifier("interface"); }
| "package" { $$ = CYNew CYIdentifier("package"); }
| "private" { $$ = CYNew CYIdentifier("private"); }
| "protected" { $$ = CYNew CYIdentifier("protected"); }
+ | "prototype" { $$ = CYNew CYIdentifier("prototype"); }
| "public" { $$ = CYNew CYIdentifier("public"); }
- | "static" { $$ = CYNew CYIdentifier("static"); }
+ | "set" { $$ = CYNew CYIdentifier("set"); }
| "synchronized" { $$ = CYNew CYIdentifier("synchronized"); }
| "throws" { $$ = CYNew CYIdentifier("throws"); }
| "transient" { $$ = CYNew CYIdentifier("transient"); }
+ | "undefined" { $$ = CYNew CYIdentifier("undefined"); }
@begin ObjectiveC
| "bool" { $$ = CYNew CYIdentifier("bool"); }
| "BOOL" { $$ = CYNew CYIdentifier("BOOL"); }
Identifier
: IdentifierType
| "char" { $$ = CYNew CYIdentifier("char"); }
- | "from" { $$ = CYNew CYIdentifier("from"); }
- | "get" { $$ = CYNew CYIdentifier("get"); }
| "int" { $$ = CYNew CYIdentifier("int"); }
| "long" { $$ = CYNew CYIdentifier("long"); }
- | "set" { $$ = CYNew CYIdentifier("set"); }
| "short" { $$ = CYNew CYIdentifier("short"); }
- | "undefined" { $$ = CYNew CYIdentifier("undefined"); }
+ | "static" { $$ = CYNew CYIdentifier("static"); }
| "volatile" { $$ = CYNew CYIdentifier("volatile"); }
@begin C
| "extern" { $$ = CYNew CYIdentifier("extern"); }
;
PropertyDefinition
- : IdentifierReference { $$ = CYNew CYProperty($1->name_, $1); }
+ : IdentifierReference { $$ = CYNew CYPropertyValue($1->name_, $1); }
| CoverInitializedName { CYNOT(@$); }
- | PropertyName ":" AssignmentExpression { $$ = CYNew CYProperty($1, $3); }
+ | PropertyName ":" AssignmentExpression { $$ = CYNew CYPropertyValue($1, $3); }
| MethodDefinition { $$ = $1; }
;
PropertyName
: LiteralPropertyName { $$ = $1; }
- | ComputedPropertyName { CYNOT(@$); /* $$ = $1; */ }
+ | ComputedPropertyName { $$ = $1; }
;
LiteralPropertyName
;
ComputedPropertyName
- : "[" AssignmentExpression "]" { $$ = $2; }
+ : "[" AssignmentExpression "]" { $$ = CYNew CYComputed($2); }
;
CoverInitializedName
MemberExpression
: LexSetRegExp PrimaryExpression { $$ = $2; }
| MemberExpression { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
- | SuperProperty { CYNOT(@$); }
+ | SuperProperty { $$ = $1; }
| MetaProperty { CYNOT(@$); }
| LexSetRegExp "new" MemberExpression Arguments { $$ = CYNew cy::Syntax::New($3, $4); }
;
SuperProperty
- : LexSetRegExp "super" "[" Expression "]"
- | LexSetRegExp "super" "." IdentifierName
+ : LexSetRegExp "!super" "[" Expression "]" { $$ = CYNew CYSuperAccess($4); }
+ | LexSetRegExp "!super" "." IdentifierName { $$ = CYNew CYSuperAccess(CYNew CYString($4)); }
;
MetaProperty
CallExpression
: CallExpression_ Arguments { $$ = CYNew CYCall($1, $2); }
- | SuperCall { CYNOT(@$); }
+ | SuperCall { $$ = $1; }
| CallExpression { driver.context_ = $1; } MemberAccess { $3->SetLeft($1); $$ = $3; }
;
SuperCall
- : LexSetRegExp "super" Arguments
+ : LexSetRegExp "!super" Arguments { $$ = CYNew CYSuperCall($3); }
;
Arguments
/* 14.1 Function Definitions {{{ */
FunctionDeclaration
- : ";function" BindingIdentifier "(" FormalParameters ")" BRACE FunctionBody "}" { $$ = CYNew CYFunctionStatement($2, $4, $7); }
+ : ";function" BindingIdentifier "(" FormalParameters ")" BRACE LexPushSuperOff FunctionBody "}" LexPopSuper { $$ = CYNew CYFunctionStatement($2, $4, $8); }
;
FunctionExpression
- : "function" BindingIdentifierOpt "(" LexPushInOff FormalParameters ")" LexPopIn BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYFunctionExpression($2, $5, $10); }
+ : "function" BindingIdentifierOpt "(" LexPushInOff FormalParameters ")" LexPopIn BRACE LexPushSuperOff LexPushInOff FunctionBody "}" LexPopIn LexPopSuper { $$ = CYNew CYFunctionExpression($2, $5, $11); }
;
StrictFormalParameters
/* }}} */
/* 14.3 Method Definitions {{{ */
MethodDefinition
- : PropertyName "(" StrictFormalParameters ")" BRACE FunctionBody "}" { CYNOT(@$); /* $$ = CYNew CYFunctionMethod($1, $3, $6); */ }
+ : PropertyName "(" StrictFormalParameters ")" BRACE FunctionBody "}" { $$ = CYNew CYPropertyMethod($1, $3, $6); }
| GeneratorMethod { $$ = $1; }
- | "get" PropertyName "(" ")" BRACE FunctionBody "}" { CYNOT(@$); /* $$ = CYNew CYMethodGet($2, $6); */ }
- | "set" PropertyName "(" PropertySetParameterList ")" BRACE FunctionBody "}" { CYNOT(@$); /* $$ = CYNew CYMethodSet($2, $4); */ }
+ | "get" PropertyName "(" ")" BRACE FunctionBody "}" { $$ = CYNew CYPropertyGetter($2, $6); }
+ | "set" PropertyName "(" PropertySetParameterList ")" BRACE FunctionBody "}" { $$ = CYNew CYPropertySetter($2, CYNew CYFunctionParameter($4), $7); }
;
PropertySetParameterList
/* }}} */
/* 14.5 Class Definitions {{{ */
ClassDeclaration
- : ";class" BindingIdentifier ClassTail { CYNOT(@$); }
+ : ";class" BindingIdentifier ClassTail { $$ = CYNew CYClassStatement($2, $3); }
;
ClassExpression
- : "class" BindingIdentifierOpt ClassTail { CYNOT(@$); }
+ : "class" BindingIdentifierOpt ClassTail { $$ = CYNew CYClassExpression($2, $3); }
;
ClassTail
- : ClassHeritageOpt BRACE ClassBodyOpt "}"
+ : ClassHeritageOpt { driver.class_.push($1); } BRACE LexPushSuperOn ClassBodyOpt "}" LexPopSuper { driver.class_.pop(); $$ = $1; }
;
ClassHeritage
- : "extends" LeftHandSideExpression
+ : "extends" LeftHandSideExpression { $$ = CYNew CYClassTail($2); }
;
ClassHeritageOpt
- : ClassHeritage
- |
+ : ClassHeritage { $$ = $1; }
+ | { $$ = CYNew CYClassTail(NULL); }
;
ClassBody
;
ClassElement
- : MethodDefinition
- | "static" MethodDefinition
+ : MethodDefinition { if (CYFunctionExpression *constructor = $1->Constructor()) driver.class_.top()->constructor_ = constructor; else driver.class_.top()->instance_->*$1; }
+ | "static" MethodDefinition { driver.class_.top()->static_->*$2; }
| ";"
;
/* }}} */
| { $$ = NULL; }
;
-ClassFieldListOpt
- : TypedIdentifier ";" ClassFieldListOpt { $$ = CYNew CYClassField($1, $3); }
+ImplementationFieldListOpt
+ : TypedIdentifier ";" ImplementationFieldListOpt { $$ = CYNew CYImplementationField($1, $3); }
| LexSetRegExp { $$ = NULL; }
;
-ClassFields
- : BRACE ClassFieldListOpt "}" { $$ = $2; }
+ImplementationFields
+ : BRACE ImplementationFieldListOpt "}" { $$ = $2; }
;
MessageScope
;
ClassMessageDeclaration
- : MessageScope TypeOpt MessageParameters BRACE FunctionBody "}" { $$ = CYNew CYMessage($1, $2, $3, $5); }
+ : MessageScope TypeOpt MessageParameters BRACE LexPushSuperOn FunctionBody "}" LexPopSuper { $$ = CYNew CYMessage($1, $2, $3, $6); }
;
ClassMessageDeclarationListOpt
| { $$ = NULL; }
;
-ClassName
- : Identifier { $$ = $1; }
- | "(" AssignmentExpression ")" { $$ = $2; }
- ;
-
// XXX: this should be AssignmentExpressionNoRight
ClassProtocols
: ShiftExpression ClassProtocolsOpt { $$ = CYNew CYProtocol($1, $2); }
| { $$ = NULL; }
;
-ClassStatement
- : "@implementation" ClassName ClassSuperOpt ClassProtocolListOpt ClassFields ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYClassStatement($2, $3, $4, $5, $6); }
+ImplementationStatement
+ : "@implementation" Identifier ClassSuperOpt ClassProtocolListOpt ImplementationFields ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYImplementation($2, $3, $4, $5, $6); }
;
CategoryName
;
CategoryStatement
- : "@implementation" ClassName CategoryName ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYCategory($2, $4); }
+ : "@implementation" Identifier CategoryName ClassMessageDeclarationListOpt "@end" { $$ = CYNew CYCategory($2, $4); }
;
Statement__
- : ClassStatement { $$ = $1; }
+ : ImplementationStatement { $$ = $1; }
| CategoryStatement { $$ = $1; }
;
/* }}} */
MessageExpression
: "[" LexPushInOff AssignmentExpression { driver.contexts_.push_back($3); } SelectorList "]" LexPopIn { driver.contexts_.pop_back(); } { $$ = CYNew CYSendDirect($3, $5); }
- | "[" LexPushInOff LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
+ | "[" LexPushInOff LexSetRegExp "!super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
;
SelectorExpression_
return function;
}
+CYFunctionExpression *CYSuperize(CYContext &context, CYFunctionExpression *function) {
+ function->super_ = context.super_;
+ return function;
+}
+
static void CYImplicitReturn(CYStatement *&code) {
if (CYStatement *&last = CYGetLast(code))
last = last->Return();
CYExpression *CYArrayComprehension::Replace(CYContext &context) {
CYVariable *cyv($V("$cyv"));
- return $C0($F(NULL, $P1($L("$cyv"), comprehensions_->Parameters(context)), $$->*
+ return $C0($F(NULL, $P1($L($I("$cyv")), comprehensions_->Parameters(context)), $$->*
$E($ CYAssign(cyv, $ CYArray()))->*
comprehensions_->Replace(context, $E($C1($M(cyv, $S("push")), expression_)))->*
$ CYReturn(cyv)
} }
+CYExpression *CYClassExpression::Replace(CYContext &context) {
+ CYBuilder builder;
+
+ CYIdentifier *super(context.Unique());
+
+ CYIdentifier *old(context.super_);
+ context.super_ = super;
+
+ CYIdentifier *constructor(context.Unique());
+ CYForEach (member, tail_->static_)
+ member->Replace(context, builder, $V(constructor), true);
+
+ CYIdentifier *prototype(context.Unique());
+ CYForEach (member, tail_->instance_)
+ member->Replace(context, builder, $V(prototype), true);
+
+ if (tail_->constructor_ == NULL)
+ tail_->constructor_ = $ CYFunctionExpression(NULL, NULL, NULL);
+ tail_->constructor_ = CYSuperize(context, tail_->constructor_);
+
+ context.super_ = old;
+
+ return $C1($ CYFunctionExpression(NULL, $P($L(super)), $$
+ ->* $ CYVar($L1($L(constructor, tail_->constructor_)))
+ ->* $ CYVar($L1($L(prototype, $ CYFunctionExpression(NULL, NULL, NULL))))
+ ->* $E($ CYAssign($M($V(prototype), $S("prototype")), $M($V(super), $S("prototype"))))
+ ->* $E($ CYAssign($V(prototype), $N($V(prototype))))
+ ->* $E($ CYAssign($M($V(prototype), $S("constructor")), $V(constructor)))
+ ->* $ CYVar(builder.declarations_)
+ ->* builder.statements_
+ ->* $E($ CYAssign($M($V(constructor), $S("prototype")), $V(prototype)))
+ ->* $ CYReturn($V(constructor))
+ ), tail_->extends_ ?: $V($I("Object")));
+}
+
+CYStatement *CYClassStatement::Replace(CYContext &context) {
+ return $ CYVar($L1($L(name_, $ CYClassExpression(name_, tail_))));
+}
+
void CYClause::Replace(CYContext &context) { $T()
context.Replace(case_);
context.ReplaceAll(code_);
return next_ == NULL ? statement : next_->Replace(context, statement);
}
+CYExpression *CYComputed::PropertyName(CYContext &context) {
+ return expression_;
+}
+
CYExpression *CYCondition::Replace(CYContext &context) {
context.Replace(test_);
context.Replace(true_);
CYIdentifier *unique(nextlocal_->identifier_->Replace(context));
CYStatement *declare(
- $ CYVar($L1($ CYDeclaration(unique, $ CYObject()))));
+ $ CYVar($L1($L(unique, $ CYObject()))));
cy::Syntax::Catch *rescue(
$ cy::Syntax::Catch(cye, $$->*
next_->Replace(context);
}
-CYProperty *CYDeclarations::Property(CYContext &context) { $T(NULL)
- return $ CYProperty(declaration_->identifier_, declaration_->initialiser_, next_->Property(context));
-}
-
CYFunctionParameter *CYDeclarations::Parameter(CYContext &context) { $T(NULL)
return $ CYFunctionParameter($ CYDeclaration(declaration_->identifier_), next_->Parameter(context));
}
return $C1(this, value);
}
-CYExpression *CYExpression::ClassName(CYContext &context, bool object) {
- return this;
-}
-
CYStatement *CYExpression::ForEachIn(CYContext &context, CYExpression *value) {
return $E($ CYAssign(this, value));
}
CYStatement *CYForOfComprehension::Replace(CYContext &context, CYStatement *statement) const {
CYIdentifier *cys($I("$cys"));
- return $E($C0($F(NULL, $P1($L("$cys")), $$->*
+ return $E($C0($F(NULL, $P1($L($I("$cys"))), $$->*
$E($ CYAssign($V(cys), set_))->*
$ CYForIn(declaration_->Variable(context), $V(cys), $ CYBlock($$->*
$E($ CYAssign(declaration_->Variable(context), $M($V(cys), declaration_->Variable(context))))->*
)));
}
-void CYFunction::Inject(CYContext &context) {
- context.Replace(name_);
- context.scope_->Declare(context, name_, CYIdentifierOther);
-}
-
-void CYFunction::Replace_(CYContext &context, bool outer) {
- if (outer)
- Inject(context);
-
+void CYFunction::Replace(CYContext &context) {
CYThisScope *_this(context.this_);
context.this_ = &this_;
context.this_ = CYGetLast(context.this_);
+ CYIdentifier *super(context.super_);
+ context.super_ = super_;
+
CYNonLocal *nonlocal(context.nonlocal_);
CYNonLocal *nextlocal(context.nextlocal_);
CYScope scope(!localize, context);
- if (!outer && name_ != NULL)
- Inject(context);
-
parameters_->Replace(context, code_);
+
context.ReplaceAll(code_);
if (implicit_)
CYImplicitReturn(code_);
- if (CYIdentifier *identifier = this_.identifier_)
- code_ = $$->*
- $ CYVar($L1($ CYDeclaration(identifier, $ CYThis())))->*
- code_;
+ if (CYIdentifier *identifier = this_.identifier_) {
+ context.scope_->Declare(context, identifier, CYIdentifierVariable);
+ code_ = $$
+ ->*$E($ CYAssign($V(identifier), $ CYThis()))
+ ->*code_
+ ;
+ }
if (localize)
context.NonLocal(code_);
context.nextlocal_ = nextlocal;
context.nonlocal_ = nonlocal;
+ context.super_ = super;
context.this_ = _this;
scope.Close(context, code_);
}
CYExpression *CYFunctionExpression::Replace(CYContext &context) {
- Replace_(context, false);
+ CYScope scope(false, context);
+ if (name_ != NULL)
+ context.scope_->Declare(context, name_, CYIdentifierOther);
+ CYFunction::Replace(context);
+ scope.Close(context, code_);
return this;
}
}
CYStatement *CYFunctionStatement::Replace(CYContext &context) {
- Replace_(context, true);
+ context.scope_->Declare(context, name_, CYIdentifierOther);
+ CYFunction::Replace(context);
return this;
}
}
CYStatement *CYImport::Replace(CYContext &context) {
- return $ CYVar($L1($L(module_->part_->Word(), $C1($V("require"), module_->Replace(context, "/")))));
+ return $ CYVar($L1($L($I(module_->part_->Word()), $C1($V("require"), module_->Replace(context, "/")))));
}
CYExpression *CYIndirect::Replace(CYContext &context) {
return $E($ CYCall(CYNonLocalize(context, $ CYFunctionExpression(NULL, declarations_->Parameter(context), code_)), declarations_->Argument(context)));
}
+CYFunctionExpression *CYMethod::Constructor() {
+ return NULL;
+}
+
+void CYMethod::Replace(CYContext &context) {
+ CYFunction::Replace(context);
+}
+
CYString *CYModule::Replace(CYContext &context, const char *separator) const {
if (next_ == NULL)
return $ CYString(part_);
return $S($pool.sprintf(24, "%.17g", Value()));
}
+CYExpression *CYNumber::PropertyName(CYContext &context) {
+ return String(context);
+}
+
CYExpression *CYObject::Replace(CYContext &context) {
- properties_->Replace(context);
+ CYBuilder builder;
+ if (properties_ != NULL)
+ properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
+
+ if (builder) {
+ return $C1($M($ CYFunctionExpression(NULL, builder.declarations_->Parameter(context),
+ builder.statements_->*
+ $ CYReturn($ CYThis())
+ ), $S("call")), this, builder.declarations_->Argument(context));
+ }
+
+ CYForEach (property, properties_)
+ property->Replace(context);
return this;
}
return this;
}
+CYProperty *CYProperty::ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update) {
+ update |= name_->Computed();
+ if (update)
+ Replace(context, builder, self, true);
+ if (next_ != NULL)
+ next_ = next_->ReplaceAll(context, builder, self, update);
+ return update ? next_ : this;
+}
+
+void CYProperty::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool computed) {
+ CYExpression *name(name_->PropertyName(context));
+ if (computed) {
+ CYIdentifier *unique(context.Unique());
+ builder.declarations_->*$L1($L(unique, name));
+ name = $V(unique);
+ }
+
+ Replace(context, builder, self, name);
+}
+
+void CYPropertyGetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) {
+ CYIdentifier *unique(context.Unique());
+ builder.declarations_
+ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+ builder.statements_
+ ->* $E($C3($M($V("Object"), $S("defineProperty")), self, name, $ CYObject(CYList<CYProperty>()
+ ->* $ CYPropertyValue($S("configurable"), $ CYTrue())
+ ->* $ CYPropertyValue($S("enumerable"), $ CYTrue())
+ ->* $ CYPropertyValue($S("get"), $V(unique))
+ )));
+}
+
+CYFunctionExpression *CYPropertyMethod::Constructor() {
+ return name_->Constructor() ? $ CYFunctionExpression(NULL, parameters_, code_) : NULL;
+}
+
+void CYPropertyMethod::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) {
+ CYIdentifier *unique(context.Unique());
+ builder.declarations_
+ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+ builder.statements_
+ ->* $E($ CYAssign($M(self, name), $V(unique)));
+}
+
+void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) {
+ CYIdentifier *unique(context.Unique());
+ builder.declarations_
+ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
+ builder.statements_
+ ->* $E($C3($M($V("Object"), $S("defineProperty")), self, name, $ CYObject(CYList<CYProperty>()
+ ->* $ CYPropertyValue($S("configurable"), $ CYTrue())
+ ->* $ CYPropertyValue($S("enumerable"), $ CYTrue())
+ ->* $ CYPropertyValue($S("set"), $V(unique))
+ )));
+}
+
+void CYPropertyValue::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) {
+ CYIdentifier *unique(context.Unique());
+ builder.declarations_
+ ->* $L1($L(unique, value_));
+ builder.statements_
+ ->* $E($ CYAssign($M(self, name), $V(unique)));
+}
+
+void CYPropertyValue::Replace(CYContext &context) {
+ context.Replace(value_);
+}
+
// XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
#define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ"
//#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
}
}
-void CYProperty::Replace(CYContext &context) { $T()
- context.Replace(value_);
- next_->Replace(context);
- if (value_ == NULL)
- value_ = $U;
-}
-
CYStatement *CYReturn::Replace(CYContext &context) {
if (context.nonlocal_ != NULL) {
- CYProperty *value(value_ == NULL ? NULL : $ CYProperty($S("$cyv"), value_));
+ CYProperty *value(value_ == NULL ? NULL : $ CYPropertyValue($S("$cyv"), value_));
return $ cy::Syntax::Throw($ CYObject(
- $ CYProperty($S("$cyk"), $V(context.nonlocal_->Target(context)), value)
+ $ CYPropertyValue($S("$cyk"), $V(context.nonlocal_->Target(context)), value)
));
}
return NULL;
}
+CYExpression *CYString::PropertyName(CYContext &context) {
+ return this;
+}
+
CYString *CYString::String(CYContext &context) {
return this;
}
+CYExpression *CYSuperAccess::Replace(CYContext &context) {
+ return $C1($M($M($M($V(context.super_), $S("prototype")), property_), $S("bind")), $ CYThis());
+}
+
+CYExpression *CYSuperCall::Replace(CYContext &context) {
+ return $C($C1($M($V(context.super_), $S("bind")), $ CYThis()), arguments_);
+}
+
CYStatement *CYSwitch::Replace(CYContext &context) {
context.Replace(value_);
clauses_->Replace(context);
return this;
}
-CYExpression *CYWord::ClassName(CYContext &context, bool object) {
- CYString *name($S(this));
- if (object)
- return $C1($V("objc_getClass"), name);
- else
- return name;
+CYExpression *CYWord::PropertyName(CYContext &context) {
+ return $S(this);
}
#define $N5(func, args...) \
$N(func, $C5_(args))
-#define $L(arg0, args...) \
- $ CYDeclaration($I(arg0), ##args)
+#define $L(args...) \
+ $ CYDeclaration(args)
#define $L1(arg0) \
$ CYDeclarations(arg0)
#define $L2(arg0, args...) \
"char" L /*FII*/ F(tk::_char_, hi::Type);
"class" L /*FFK*/ F(tk::_class_, hi::Meta);
"const" L /*FFK*/ F(tk::_const_, hi::Meta);
+"constructor" L /*III*/ F(tk::_constructor_, hi::Special);
"continue" L /*KKK*/ F(tk::_continue_, hi::Control);
"debugger" L /*FKK*/ F(tk::_debugger_, hi::Meta);
"default" L /*KKK*/ F(tk::_default_, hi::Control);
"package" L /*FSS*/ F(tk::_package_, hi::Meta);
"private" L /*FSS*/ F(tk::_private_, hi::Meta);
"protected" L /*FSS*/ F(tk::_protected_, hi::Meta);
+"prototype" L /*III*/ F(tk::_prototype_, hi::Special);
"public" L /*FSS*/ F(tk::_public_, hi::Meta);
"return" L /*KKK*/ F(yyextra->return_.top() ? tk::_return__ : tk::_return_, hi::Control);
"set" L /*III*/ F(tk::_set_, hi::Meta);
"short" L /*FII*/ F(tk::_short_, hi::Type);
"static" L /*FS?*/ F(tk::_static_, hi::Meta);
-"super" L /*FFK*/ F(tk::_super_, hi::Constant);
+"super" L /*FFK*/ F(yyextra->super_.top() ? tk::_super__ : tk::_super_, hi::Constant);
"switch" L /*KKK*/ F(tk::_switch_, hi::Control);
"synchronized" L /*FII*/ F(tk::_synchronized_, hi::Meta);
"this" L /*KKK*/ F(tk::_this_, hi::Constant);
}
};
+struct CYExpression;
+struct CYAssignment;
+
struct CYPropertyName {
+ virtual bool Computed() const {
+ return false;
+ }
+
+ virtual bool Constructor() const {
+ return false;
+ }
+
+ virtual CYExpression *PropertyName(CYContext &context) = 0;
virtual void PropertyName(CYOutput &out) const = 0;
};
-struct CYExpression;
-struct CYAssignment;
-
enum CYNeeded {
CYNever = -1,
CYSometimes = 0,
CYNoFlags = 0,
CYNoBrace = (1 << 0),
CYNoFunction = (1 << 1),
- CYNoIn = (1 << 2),
- CYNoCall = (1 << 3),
- CYNoRightHand = (1 << 4),
- CYNoDangle = (1 << 5),
- CYNoInteger = (1 << 6),
- CYNoBF = (CYNoBrace | CYNoFunction),
+ CYNoClass = (1 << 2),
+ CYNoIn = (1 << 3),
+ CYNoCall = (1 << 4),
+ CYNoRightHand = (1 << 5),
+ CYNoDangle = (1 << 6),
+ CYNoInteger = (1 << 7),
+ CYNoBFC = (CYNoBrace | CYNoFunction | CYNoClass),
};
_finline CYFlags operator ~(CYFlags rhs) {
}
_finline CYFlags CYRight(CYFlags flags) {
- return flags & ~CYNoBF;
+ return flags & ~CYNoBFC;
}
_finline CYFlags CYCenter(CYFlags flags) {
virtual void Output(CYOutput &out, CYFlags flags) const = 0;
};
-struct CYStatements {
- CYStatement *first_;
- CYStatement *last_;
-
- CYStatements() :
- first_(NULL),
- last_(NULL)
- {
- }
-
- operator CYStatement *() const {
- return first_;
- }
-
- CYStatements &operator ->*(CYStatement *next) {
- if (next != NULL)
- if (first_ == NULL) {
- first_ = next;
- last_ = next;
- } else for (;; last_ = last_->next_)
- if (last_->next_ == NULL) {
- last_->next_ = next;
- last_ = next;
- break;
- }
- return *this;
- }
-};
-
-struct CYClassName {
- virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
- virtual void ClassName(CYOutput &out, bool object) const = 0;
-};
+typedef CYList<CYStatement> CYStatements;
struct CYWord :
CYThing,
- CYPropertyName,
- CYClassName
+ CYPropertyName
{
const char *word_;
word_ = value;
}
+ virtual bool Constructor() const {
+ return strcmp(word_, "constructor") == 0;
+ }
+
virtual const char *Word() const;
virtual void Output(CYOutput &out) const;
- virtual CYExpression *ClassName(CYContext &context, bool object);
- virtual void ClassName(CYOutput &out, bool object) const;
+ virtual CYExpression *PropertyName(CYContext &context);
virtual void PropertyName(CYOutput &out) const;
};
CYScope *scope_;
CYThisScope *this_;
+ CYIdentifier *super_;
CYIdentifierUsageVector rename_;
options_(options),
scope_(NULL),
this_(NULL),
+ super_(NULL),
nonlocal_(NULL),
nextlocal_(NULL),
unique_(0)
struct CYExpression :
CYForInitializer,
CYForInInitializer,
- CYClassName,
CYThing
{
virtual int Precedence() const = 0;
virtual void Output(CYOutput &out, CYFlags flags) const = 0;
void Output(CYOutput &out, int precedence, CYFlags flags) const;
- virtual CYExpression *ClassName(CYContext &context, bool object);
- virtual void ClassName(CYOutput &out, bool object) const;
-
virtual CYExpression *Replace(CYContext &context) = 0;
virtual CYAssignment *Assignment(CYContext &context);
CYString *Concat(CYContext &out, CYString *rhs) const;
virtual void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYExpression *PropertyName(CYContext &context);
virtual void PropertyName(CYOutput &out) const;
};
virtual CYString *String(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYExpression *PropertyName(CYContext &context);
+ virtual void PropertyName(CYOutput &out) const;
+};
+
+struct CYComputed :
+ CYPropertyName
+{
+ CYExpression *expression_;
+
+ CYComputed(CYExpression *expression) :
+ expression_(expression)
+ {
+ }
+
+ virtual bool Computed() const {
+ return true;
+ }
+
+ virtual CYExpression *PropertyName(CYContext &context);
virtual void PropertyName(CYOutput &out) const;
};
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYProperty :
- CYNext<CYProperty>,
- CYThing
-{
- CYPropertyName *name_;
- CYExpression *value_;
-
- CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
- CYNext<CYProperty>(next),
- name_(name),
- value_(value)
- {
- }
-
- void Replace(CYContext &context);
- virtual void Output(CYOutput &out) const;
-};
-
struct CYDeclaration :
CYForInInitializer
{
void Replace(CYContext &context);
CYExpression *Expression(CYContext &context);
- CYProperty *Property(CYContext &context);
CYArgument *Argument(CYContext &context);
CYFunctionParameter *Parameter(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYBuilder {
+ CYList<CYDeclarations> declarations_;
+ CYList<CYStatement> statements_;
+
+ operator bool() const {
+ return statements_ != NULL;
+ }
+};
+
+struct CYProperty :
+ CYNext<CYProperty>,
+ CYThing
+{
+ CYPropertyName *name_;
+
+ CYProperty(CYPropertyName *name, CYProperty *next = NULL) :
+ CYNext<CYProperty>(next),
+ name_(name)
+ {
+ }
+
+ CYProperty *ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update);
+ void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool computed);
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) = 0;
+
+ virtual void Replace(CYContext &context) = 0;
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYPropertyValue :
+ CYProperty
+{
+ CYExpression *value_;
+
+ CYPropertyValue(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
+ CYProperty(name, next),
+ value_(value)
+ {
+ }
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name);
+ virtual void Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
struct CYFor :
CYStatement
{
CYExpression *constructor_;
CYArgument *arguments_;
- New(CYExpression *constructor, CYArgument *arguments) :
+ New(CYExpression *constructor, CYArgument *arguments = NULL) :
constructor_(constructor),
arguments_(arguments)
{
};
struct CYFunction {
- CYIdentifier *name_;
CYFunctionParameter *parameters_;
CYStatement *code_;
CYNonLocal *nonlocal_;
bool implicit_;
CYThisScope this_;
+ CYIdentifier *super_;
- CYFunction(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
- name_(name),
+ CYFunction(CYFunctionParameter *parameters, CYStatement *code) :
parameters_(parameters),
code_(code),
nonlocal_(NULL),
- implicit_(false)
+ implicit_(false),
+ super_(NULL)
{
}
- void Inject(CYContext &context);
- virtual void Replace_(CYContext &context, bool outer);
- virtual void Output(CYOutput &out, CYFlags flags) const;
+ void Replace(CYContext &context);
+ void Output(CYOutput &out) const;
};
struct CYFunctionExpression :
CYFunction,
CYExpression
{
+ CYIdentifier *name_;
+
CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(name, parameters, code)
+ CYFunction(parameters, code),
+ name_(name)
{
}
CYExpression
{
CYFatArrow(CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(NULL, parameters, code)
+ CYFunction(parameters, code)
{
}
CYExpression
{
CYRubyProc(CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(NULL, parameters, code)
+ CYFunction(parameters, code)
{
}
+ CYPrecedence(0)
+ CYRightHand(false)
+
virtual CYExpression *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
CYFunction,
CYStatement
{
+ CYIdentifier *name_;
+
CYFunctionStatement(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(name, parameters, code)
+ CYFunction(parameters, code),
+ name_(name)
{
}
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYPropertyMethod;
+
+struct CYMethod :
+ CYFunction,
+ CYProperty
+{
+ CYMethod(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
+ CYFunction(parameters, code),
+ CYProperty(name, next)
+ {
+ }
+
+ virtual CYFunctionExpression *Constructor();
+
+ using CYProperty::Replace;
+ virtual void Replace(CYContext &context);
+};
+
+struct CYPropertyGetter :
+ CYMethod
+{
+ CYPropertyGetter(CYPropertyName *name, CYStatement *code, CYProperty *next = NULL) :
+ CYMethod(name, NULL, code, next)
+ {
+ }
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYPropertySetter :
+ CYMethod
+{
+ CYPropertySetter(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
+ CYMethod(name, parameters, code, next)
+ {
+ }
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYPropertyMethod :
+ CYMethod
+{
+ CYPropertyMethod(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
+ CYMethod(name, parameters, code, next)
+ {
+ }
+
+ virtual CYFunctionExpression *Constructor();
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYClassTail :
+ CYThing
+{
+ CYExpression *extends_;
+
+ CYFunctionExpression *constructor_;
+ CYList<CYProperty> instance_;
+ CYList<CYProperty> static_;
+
+ CYClassTail(CYExpression *extends) :
+ extends_(extends),
+ constructor_(NULL)
+ {
+ }
+
+ void Output(CYOutput &out) const;
+};
+
+struct CYClassExpression :
+ CYExpression
+{
+ CYIdentifier *name_;
+ CYClassTail *tail_;
+
+ CYClassExpression(CYIdentifier *name, CYClassTail *tail) :
+ name_(name),
+ tail_(tail)
+ {
+ }
+
+ CYPrecedence(0)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYClassStatement :
+ CYStatement
+{
+ CYIdentifier *name_;
+ CYClassTail *tail_;
+
+ CYClassStatement(CYIdentifier *name, CYClassTail *tail) :
+ name_(name),
+ tail_(tail)
+ {
+ }
+
+ CYCompact(Long)
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYSuperCall :
+ CYExpression
+{
+ CYArgument *arguments_;
+
+ CYSuperCall(CYArgument *arguments) :
+ arguments_(arguments)
+ {
+ }
+
+ CYPrecedence(2)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYSuperAccess :
+ CYExpression
+{
+ CYExpression *property_;
+
+ CYSuperAccess(CYExpression *property) :
+ property_(property)
+ {
+ }
+
+ CYPrecedence(1)
+ CYRightHand(false)
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYExpress :
CYStatement
{