#include <streambuf>
#include <string>
#include <vector>
-#include <map>
-#include <set>
#include "List.hpp"
#include "Location.hpp"
#include "Options.hpp"
#include "Pooling.hpp"
+#include "String.hpp"
+
+double CYCastDouble(const char *value, size_t size);
+double CYCastDouble(const char *value);
+double CYCastDouble(CYUTF8String value);
+
+void CYNumerify(std::ostringstream &str, double value);
+void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c = false);
+
+// XXX: this really should not be here ... :/
+void *CYPoolFile(CYPool &pool, const char *path, size_t *psize);
+CYUTF8String CYPoolFileUTF8String(CYPool &pool, const char *path);
struct CYContext;
_assert(out_.sputc(value) != EOF);
recent_ = indent_;
if (value == '\n')
- position_.lines(1);
+ position_.Lines(1);
else
- position_.columns(1);
+ position_.Columns(1);
}
_finline void operator ()(const char *data, std::streamsize size) {
_assert(out_.sputn(data, size) == size);
recent_ = indent_;
- position_.columns(size);
+ position_.Columns(size);
}
_finline void operator ()(const char *data) {
}
};
+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),
+ CYNoColon = (1 << 8),
+ 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;
- }
-};
+typedef CYList<CYStatement> CYStatements;
-struct CYClassName {
- virtual CYExpression *ClassName(CYContext &context, bool object) = 0;
- virtual void ClassName(CYOutput &out, bool object) const = 0;
+struct CYForInitializer :
+ CYStatement
+{
+ virtual CYForInitializer *Replace(CYContext &context) = 0;
+ virtual void Output(CYOutput &out, CYFlags flags) const = 0;
};
struct CYWord :
CYThing,
- CYPropertyName,
- CYClassName
+ CYPropertyName
{
const char *word_;
{
}
- void Set(const char *value) {
- 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;
};
return lhs << rhs.Word();
}
+enum CYIdentifierKind {
+ CYIdentifierArgument,
+ CYIdentifierCatch,
+ CYIdentifierGlobal,
+ CYIdentifierLexical,
+ CYIdentifierMagic,
+ CYIdentifierOther,
+ CYIdentifierVariable,
+};
+
struct CYIdentifier :
CYNext<CYIdentifier>,
CYWord
{
- CYIdentifier *replace_;
+ CYLocation location_;
size_t offset_;
size_t usage_;
CYIdentifier(const char *word) :
CYWord(word),
- replace_(NULL),
offset_(0),
usage_(0)
{
}
virtual const char *Word() const;
- CYIdentifier *Replace(CYContext &context);
+ CYIdentifier *Replace(CYContext &context, CYIdentifierKind);
};
struct CYLabel :
}
};
-enum CYIdentifierFlags {
- CYIdentifierArgument,
- CYIdentifierVariable,
- CYIdentifierOther,
- CYIdentifierMagic,
- CYIdentifierCatch,
-};
-
-typedef std::set<const char *, CYCStringLess> CYCStringSet;
-typedef std::set<CYIdentifier *, CYIdentifierValueLess> CYIdentifierValueSet;
-typedef std::map<CYIdentifier *, CYIdentifierFlags> CYIdentifierAddressFlagsMap;
-
-struct CYIdentifierUsage {
+struct CYIdentifierFlags :
+ CYNext<CYIdentifierFlags>
+{
CYIdentifier *identifier_;
- size_t usage_;
-};
+ CYIdentifierKind kind_;
+ unsigned count_;
+ unsigned offset_;
-typedef std::vector<CYIdentifierUsage> CYIdentifierUsageVector;
+ CYIdentifierFlags(CYIdentifier *identifier, CYIdentifierKind kind, CYIdentifierFlags *next = NULL) :
+ CYNext<CYIdentifierFlags>(next),
+ identifier_(identifier),
+ kind_(kind),
+ count_(0),
+ offset_(0)
+ {
+ }
+};
struct CYScope {
bool transparent_;
CYScope *parent_;
+ bool damaged_;
+ CYIdentifierFlags *shadow_;
- CYIdentifierAddressFlagsMap internal_;
- CYIdentifierValueSet identifiers_;
+ CYIdentifierFlags *internal_;
CYScope(bool transparent, CYContext &context);
- void Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags);
- virtual CYIdentifier *Lookup(CYContext &context, CYIdentifier *identifier);
- void Merge(CYContext &context, CYIdentifier *identifier);
+ CYIdentifierFlags *Lookup(CYContext &context, const char *word);
+ CYIdentifierFlags *Lookup(CYContext &context, CYIdentifier *identifier);
+
+ CYIdentifierFlags *Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierKind kind);
+ void Merge(CYContext &context, const CYIdentifierFlags *flags);
+
void Close(CYContext &context, CYStatement *&statements);
+ void Close(CYContext &context);
+ void Damage();
};
struct CYScript :
CYScope *scope_;
CYThisScope *this_;
-
- CYIdentifierUsageVector rename_;
+ CYIdentifier *super_;
CYNonLocal *nonlocal_;
CYNonLocal *nextlocal_;
unsigned unique_;
+ std::vector<CYIdentifier *> replace_;
+
CYContext(CYOptions &options) :
options_(options),
scope_(NULL),
this_(NULL),
+ super_(NULL),
nonlocal_(NULL),
nextlocal_(NULL),
unique_(0)
virtual CYStatement *Return();
};
-struct CYForInitializer {
- virtual CYExpression *Replace(CYContext &context) = 0;
- virtual void Output(CYOutput &out, CYFlags flags) const = 0;
-};
+struct CYTarget;
+struct CYVar;
struct CYForInInitializer {
- virtual void ForIn(CYOutput &out, CYFlags flags) const = 0;
- virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value) = 0;
-
- virtual CYExpression *Replace(CYContext &context) = 0;
- virtual CYAssignment *Assignment(CYContext &context) = 0;
+ virtual CYStatement *Initialize(CYContext &context, CYExpression *value) = 0;
+ virtual CYTarget *Replace(CYContext &context) = 0;
virtual void Output(CYOutput &out, CYFlags flags) const = 0;
};
struct CYString;
struct CYExpression :
- CYForInitializer,
- CYForInInitializer,
- CYClassName,
CYThing
{
virtual int Precedence() const = 0;
return true;
}
- virtual void ForIn(CYOutput &out, CYFlags flags) const;
- virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
+ virtual bool Eval() const {
+ return false;
+ }
- virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+ virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
virtual void Output(CYOutput &out) const;
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);
virtual CYExpression *Primitive(CYContext &context) {
return NULL;
}
};
+struct CYTarget :
+ CYExpression,
+ CYForInInitializer
+{
+ virtual bool RightHand() const {
+ return false;
+ }
+
+ virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
+
+ virtual CYTarget *Replace(CYContext &context) = 0;
+ using CYExpression::Output;
+};
+
#define CYAlphabetic(value) \
virtual bool Alphabetic() const { \
return value; \
return Precedence_; \
}
-#define CYRightHand(value) \
- virtual bool RightHand() const { \
- return value; \
- }
-
struct CYCompound :
CYExpression
{
};
struct CYParenthetical :
- CYExpression
+ CYTarget
{
CYExpression *expression_;
CYPrecedence(0)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYDeclaration;
+struct CYBinding;
struct CYFunctionParameter :
CYNext<CYFunctionParameter>,
CYThing
{
- CYForInInitializer *initialiser_;
+ CYBinding *binding_;
- CYFunctionParameter(CYForInInitializer *initialiser, CYFunctionParameter *next = NULL) :
+ CYFunctionParameter(CYBinding *binding, CYFunctionParameter *next = NULL) :
CYNext<CYFunctionParameter>(next),
- initialiser_(initialiser)
+ binding_(binding)
{
}
{
}
- CYComprehension *Modify(CYComprehension *next) {
- next_ = next;
- return this;
- }
-
virtual CYFunctionParameter *Parameter(CYContext &context) const = 0;
CYFunctionParameter *Parameters(CYContext &context) const;
virtual CYStatement *Replace(CYContext &context, CYStatement *statement) const;
struct CYForInComprehension :
CYComprehension
{
- CYDeclaration *declaration_;
- CYExpression *set_;
+ CYBinding *binding_;
+ CYExpression *iterable_;
- CYForInComprehension(CYDeclaration *declaration, CYExpression *set, CYComprehension *next = NULL) :
+ CYForInComprehension(CYBinding *binding, CYExpression *iterable, CYComprehension *next = NULL) :
CYComprehension(next),
- declaration_(declaration),
- set_(set)
+ binding_(binding),
+ iterable_(iterable)
{
}
struct CYForOfComprehension :
CYComprehension
{
- CYDeclaration *declaration_;
- CYExpression *set_;
+ CYBinding *binding_;
+ CYExpression *iterable_;
- CYForOfComprehension(CYDeclaration *declaration, CYExpression *set, CYComprehension *next = NULL) :
+ CYForOfComprehension(CYBinding *binding, CYExpression *iterable, CYComprehension *next = NULL) :
CYComprehension(next),
- declaration_(declaration),
- set_(set)
+ binding_(binding),
+ iterable_(iterable)
{
}
};
struct CYArrayComprehension :
- CYExpression
+ CYTarget
{
CYExpression *expression_;
CYComprehension *comprehensions_;
CYPrecedence(0)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYLiteral :
- CYExpression
+ CYTarget
{
+ CYLocation location_;
+
CYPrecedence(0)
- CYRightHand(false)
virtual CYExpression *Primitive(CYContext &context) {
return this;
struct CYTrivial :
CYLiteral
{
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
};
struct CYMagic :
- CYExpression
+ CYTarget
{
CYPrecedence(0)
- CYRightHand(false)
};
struct CYRange {
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;
};
};
struct CYTemplate :
- CYExpression
+ CYTarget
{
CYString *string_;
CYSpan *spans_;
}
CYPrecedence(0)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) 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;
};
struct CYThis :
CYMagic
{
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYBoolean :
CYTrivial
{
+ CYPrecedence(4)
+
+ virtual bool RightHand() const {
+ return true;
+ }
+
virtual bool Value() const = 0;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
};
struct CYVariable :
- CYExpression
+ CYTarget
{
CYIdentifier *name_;
}
CYPrecedence(0)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ virtual bool Eval() const {
+ return strcmp(name_->Word(), "eval") == 0;
+ }
+
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
virtual CYFunctionParameter *Parameter() const;
};
+struct CYSymbol :
+ CYTarget
+{
+ const char *name_;
+
+ CYSymbol(const char *name) :
+ name_(name)
+ {
+ }
+
+ CYPrecedence(0)
+
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYPrefix :
CYExpression
{
struct CYAssignment :
CYExpression
{
- CYExpression *lhs_;
+ CYTarget *lhs_;
CYExpression *rhs_;
- CYAssignment(CYExpression *lhs, CYExpression *rhs) :
+ CYAssignment(CYTarget *lhs, CYExpression *rhs) :
lhs_(lhs),
rhs_(rhs)
{
}
- void SetLeft(CYExpression *lhs) {
- lhs_ = lhs;
+ void SetRight(CYExpression *rhs) {
+ rhs_ = rhs;
}
virtual const char *Operator() const = 0;
CYThing,
CYNext<CYClause>
{
- CYExpression *case_;
+ CYExpression *value_;
CYStatement *code_;
- CYClause(CYExpression *_case, CYStatement *code) :
- case_(_case),
+ CYClause(CYExpression *value, CYStatement *code) :
+ value_(value),
code_(code)
{
}
};
struct CYElement :
+ CYNext<CYElement>,
CYThing
{
+ CYElement(CYElement *next) :
+ CYNext<CYElement>(next)
+ {
+ }
+
virtual bool Elision() const = 0;
virtual void Replace(CYContext &context) = 0;
};
struct CYElementValue :
- CYNext<CYElement>,
CYElement
{
CYExpression *value_;
- CYElementValue(CYExpression *value, CYElement *next) :
- CYNext<CYElement>(next),
+ CYElementValue(CYExpression *value, CYElement *next = NULL) :
+ CYElement(next),
value_(value)
{
}
{
CYExpression *value_;
- CYElementSpread(CYExpression *value) :
+ CYElementSpread(CYExpression *value, CYElement *next = NULL) :
+ CYElement(next),
value_(value)
{
}
{
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYProperty :
- CYNext<CYProperty>,
- CYThing
-{
- CYPropertyName *name_;
- CYExpression *value_;
+struct CYBinding {
+ CYIdentifier *identifier_;
+ CYExpression *initializer_;
- CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next = NULL) :
- CYNext<CYProperty>(next),
- name_(name),
- value_(value)
+ CYBinding(CYIdentifier *identifier, CYExpression *initializer = NULL) :
+ identifier_(identifier),
+ initializer_(initializer)
{
}
- void Replace(CYContext &context);
- virtual void Output(CYOutput &out) const;
+ CYTarget *Target(CYContext &context);
+
+ virtual CYAssignment *Replace(CYContext &context, CYIdentifierKind kind);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYDeclaration :
+struct CYForLexical :
CYForInInitializer
{
- CYIdentifier *identifier_;
- CYExpression *initialiser_;
+ bool constant_;
+ CYBinding *binding_;
- CYDeclaration(CYIdentifier *identifier, CYExpression *initialiser = NULL) :
- identifier_(identifier),
- initialiser_(initialiser)
+ CYForLexical(bool constant, CYBinding *binding) :
+ constant_(constant),
+ binding_(binding)
{
}
- virtual void ForIn(CYOutput &out, CYFlags flags) const;
- virtual CYStatement *ForEachIn(CYContext &out, CYExpression *value);
+ virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYForVariable :
+ CYForInInitializer
+{
+ CYBinding *binding_;
+
+ CYForVariable(CYBinding *binding) :
+ binding_(binding)
+ {
+ }
- virtual CYAssignment *Assignment(CYContext &context);
- CYVariable *Variable(CYContext &context);
+ virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYDeclarations :
- CYNext<CYDeclarations>,
+struct CYBindings :
+ CYNext<CYBindings>,
CYThing
{
- CYDeclaration *declaration_;
+ CYBinding *binding_;
- CYDeclarations(CYDeclaration *declaration, CYDeclarations *next = NULL) :
- CYNext<CYDeclarations>(next),
- declaration_(declaration)
+ CYBindings(CYBinding *binding, CYBindings *next = NULL) :
+ CYNext<CYBindings>(next),
+ binding_(binding)
{
}
- void Replace(CYContext &context);
+ CYExpression *Replace(CYContext &context, CYIdentifierKind kind);
- 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 CYForDeclarations :
+struct CYVar :
CYForInitializer
{
- CYDeclarations *declarations_;
+ CYBindings *bindings_;
- CYForDeclarations(CYDeclarations *declarations) :
- declarations_(declarations)
+ CYVar(CYBindings *bindings) :
+ bindings_(bindings)
{
}
- virtual CYExpression *Replace(CYContext &context);
+ CYCompact(None)
+
+ virtual CYForInitializer *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYVar :
- CYStatement
+struct CYLexical :
+ CYForInitializer
{
- CYDeclarations *declarations_;
+ bool constant_;
+ CYBindings *bindings_;
- CYVar(CYDeclarations *declarations) :
- declarations_(declarations)
+ CYLexical(bool constant, CYBindings *bindings) :
+ constant_(constant),
+ bindings_(bindings)
{
}
CYCompact(None)
- virtual CYStatement *Replace(CYContext &context);
+ virtual CYForInitializer *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYLetStatement :
- CYStatement
+struct CYBuilder {
+ CYList<CYBindings> bindings_;
+ CYList<CYStatement> statements_;
+
+ operator bool() const {
+ return statements_ != NULL;
+ }
+};
+
+struct CYProperty :
+ CYNext<CYProperty>,
+ CYThing
{
- CYDeclarations *declarations_;
- CYStatement *code_;
+ CYPropertyName *name_;
- CYLetStatement(CYDeclarations *declarations, CYStatement *code) :
- declarations_(declarations),
- code_(code)
+ CYProperty(CYPropertyName *name, CYProperty *next = NULL) :
+ CYNext<CYProperty>(next),
+ name_(name)
{
}
- CYCompact(Long)
+ virtual bool Update() const;
- virtual CYStatement *Replace(CYContext &context);
- virtual void Output(CYOutput &out, CYFlags flags) const;
+ CYProperty *ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update);
+ void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool protect);
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) = 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, bool protect);
+ virtual void Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
};
struct CYFor :
CYStatement
{
- CYForInitializer *initialiser_;
+ CYForInitializer *initializer_;
CYExpression *test_;
CYExpression *increment_;
CYStatement *code_;
- CYFor(CYForInitializer *initialiser, CYExpression *test, CYExpression *increment, CYStatement *code) :
- initialiser_(initialiser),
+ CYFor(CYForInitializer *initializer, CYExpression *test, CYExpression *increment, CYStatement *code) :
+ initializer_(initializer),
test_(test),
increment_(increment),
code_(code)
struct CYForIn :
CYStatement
{
- CYForInInitializer *initialiser_;
- CYExpression *set_;
+ CYForInInitializer *initializer_;
+ CYExpression *iterable_;
+ CYStatement *code_;
+
+ CYForIn(CYForInInitializer *initializer, CYExpression *iterable, CYStatement *code) :
+ initializer_(initializer),
+ iterable_(iterable),
+ code_(code)
+ {
+ }
+
+ CYCompact(Long)
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYForInitialized :
+ CYStatement
+{
+ CYBinding *binding_;
+ CYExpression *iterable_;
CYStatement *code_;
- CYForIn(CYForInInitializer *initialiser, CYExpression *set, CYStatement *code) :
- initialiser_(initialiser),
- set_(set),
+ CYForInitialized(CYBinding *binding, CYExpression *iterable, CYStatement *code) :
+ binding_(binding),
+ iterable_(iterable),
code_(code)
{
}
struct CYForOf :
CYStatement
{
- CYForInInitializer *initialiser_;
- CYExpression *set_;
+ CYForInInitializer *initializer_;
+ CYExpression *iterable_;
CYStatement *code_;
- CYForOf(CYForInInitializer *initialiser, CYExpression *set, CYStatement *code) :
- initialiser_(initialiser),
- set_(set),
+ CYForOf(CYForInInitializer *initializer, CYExpression *iterable, CYStatement *code) :
+ initializer_(initializer),
+ iterable_(iterable),
code_(code)
{
}
{
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
void Output(CYOutput &out, CYFlags flags) const;
};
struct CYMember :
- CYExpression
+ CYTarget
{
CYExpression *object_;
CYExpression *property_;
}
CYPrecedence(1)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
}
CYPrecedence(1)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYResolveMember :
+ CYMember
+{
+ CYResolveMember(CYExpression *object, CYExpression *property) :
+ CYMember(object, property)
+ {
+ }
+
+ CYPrecedence(1)
+
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
namespace Syntax {
struct New :
- CYExpression
+ CYTarget
{
CYExpression *constructor_;
CYArgument *arguments_;
- New(CYExpression *constructor, CYArgument *arguments) :
+ New(CYExpression *constructor, CYArgument *arguments = NULL) :
constructor_(constructor),
arguments_(arguments)
{
return arguments_ == NULL ? 2 : 1;
}
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
- virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+ virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
};
} }
-struct CYCall :
- CYExpression
+struct CYApply :
+ CYTarget
{
- CYExpression *function_;
CYArgument *arguments_;
- CYCall(CYExpression *function, CYArgument *arguments = NULL) :
- function_(function),
+ CYApply(CYArgument *arguments = NULL) :
arguments_(arguments)
{
}
CYPrecedence(1)
- CYRightHand(false)
-
- virtual CYExpression *Replace(CYContext &context);
- virtual void Output(CYOutput &out, CYFlags flags) const;
- virtual CYExpression *AddArgument(CYContext &context, CYExpression *value);
+ virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
};
-struct CYRubyProc;
-
-struct CYRubyBlock :
- CYExpression
+struct CYCall :
+ CYApply
{
- CYExpression *call_;
- CYRubyProc *proc_;
+ CYExpression *function_;
- CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
- call_(call),
- proc_(proc)
+ CYCall(CYExpression *function, CYArgument *arguments = NULL) :
+ CYApply(arguments),
+ function_(function)
+ {
+ }
+
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+ virtual CYTarget *Replace(CYContext &context);
+};
+
+struct CYEval :
+ CYApply
+{
+ CYEval(CYArgument *arguments) :
+ CYApply(arguments)
{
}
- CYPrecedence(1)
- CYRightHand(false)
-
- virtual CYExpression *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
+ virtual CYTarget *Replace(CYContext &context);
+};
+
+struct CYRubyProc;
+
+struct CYRubyBlock :
+ CYTarget
+{
+ CYExpression *call_;
+ CYRubyProc *proc_;
+
+ CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
+ call_(call),
+ proc_(proc)
+ {
+ }
+
+ CYPrecedence(1)
+
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+
+ virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
};
struct CYIf :
};
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
+ CYTarget
{
+ CYIdentifier *name_;
+
CYFunctionExpression(CYIdentifier *name, CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(name, parameters, code)
+ CYFunction(parameters, code),
+ name_(name)
{
}
CYPrecedence(0)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ CYTarget *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
CYExpression
{
CYFatArrow(CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(NULL, parameters, code)
+ CYFunction(parameters, code)
{
}
CYPrecedence(0)
- CYRightHand(false)
- virtual CYExpression *Replace(CYContext &context);
+ CYExpression *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYRubyProc :
CYFunction,
- CYExpression
+ CYTarget
{
CYRubyProc(CYFunctionParameter *parameters, CYStatement *code) :
- CYFunction(NULL, parameters, code)
+ CYFunction(parameters, code)
{
}
- virtual CYExpression *Replace(CYContext &context);
+ CYPrecedence(0)
+
+ CYTarget *Replace(CYContext &context) override;
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)
{
}
CYCompact(None)
- virtual CYStatement *Replace(CYContext &context);
+ CYStatement *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
-struct CYExpress :
+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, bool protect);
+ 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, bool protect);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYPropertyMethod :
+ CYMethod
+{
+ CYPropertyMethod(CYPropertyName *name, CYFunctionParameter *parameters, CYStatement *code, CYProperty *next = NULL) :
+ CYMethod(name, parameters, code, next)
+ {
+ }
+
+ bool Update() const override;
+
+ virtual CYFunctionExpression *Constructor();
+
+ virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect);
+ 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 :
+ CYTarget
+{
+ CYIdentifier *name_;
+ CYClassTail *tail_;
+
+ CYClassExpression(CYIdentifier *name, CYClassTail *tail) :
+ name_(name),
+ tail_(tail)
+ {
+ }
+
+ CYPrecedence(0)
+
+ CYTarget *Replace(CYContext &context) override;
+ 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)
+
+ CYStatement *Replace(CYContext &context) override;
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYSuperCall :
+ CYTarget
+{
+ CYArgument *arguments_;
+
+ CYSuperCall(CYArgument *arguments) :
+ arguments_(arguments)
+ {
+ }
+
+ CYPrecedence(2)
+
+ CYTarget *Replace(CYContext &context) override;
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYSuperAccess :
+ CYTarget
+{
+ CYExpression *property_;
+
+ CYSuperAccess(CYExpression *property) :
+ property_(property)
+ {
+ }
+
+ CYPrecedence(1)
+
+ CYTarget *Replace(CYContext &context) override;
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYExpress :
+ CYForInitializer
{
CYExpression *expression_;
CYCompact(None)
- virtual CYStatement *Replace(CYContext &context);
+ CYForInitializer *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
virtual CYStatement *Return();
CYCompact(Short)
- virtual CYStatement *Replace(CYContext &context);
+ CYStatement *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
CYCompact(Short)
- virtual CYStatement *Replace(CYContext &context);
+ CYStatement *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
CYCompact(None)
- virtual CYStatement *Replace(CYContext &context);
+ CYStatement *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
CYPrecedence(0)
- virtual CYExpression *Replace(CYContext &context);
+ CYExpression *Replace(CYContext &context) override;
virtual void Output(CYOutput &out, CYFlags flags) const;
};
};
struct CYEmpty :
- CYStatement
+ CYForInitializer
{
CYCompact(Short)
- virtual CYStatement *Replace(CYContext &context);
+ virtual CYForInitializer *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
struct CYTypeSpecifier :
CYThing
{
- virtual CYExpression *Replace(CYContext &context) = 0;
+ virtual CYTarget *Replace(CYContext &context) = 0;
};
struct CYTypeError :
CYTypeError() {
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
-struct CYTypeVoid :
+enum CYTypeSigning {
+ CYTypeNeutral,
+ CYTypeSigned,
+ CYTypeUnsigned,
+};
+
+struct CYTypeCharacter :
CYTypeSpecifier
{
- CYTypeVoid() {
+ CYTypeSigning signing_;
+
+ CYTypeCharacter(CYTypeSigning signing) :
+ signing_(signing)
+ {
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
-struct CYTypeVariable :
+struct CYTypeIntegral :
CYTypeSpecifier
{
- CYIdentifier *name_;
+ CYTypeSigning signing_;
+ int length_;
- CYTypeVariable(CYIdentifier *name) :
- name_(name)
+ CYTypeIntegral(CYTypeSigning signing, int length = 1) :
+ signing_(signing),
+ length_(length)
{
}
- CYTypeVariable(const char *name) :
- name_(new($pool) CYIdentifier(name))
- {
+ CYTypeIntegral *Long() {
+ if (length_ != 1 && length_ != 2)
+ return NULL;
+ ++length_;
+ return this;
}
- virtual CYExpression *Replace(CYContext &context);
- virtual void Output(CYOutput &out) const;
-};
+ CYTypeIntegral *Short() {
+ if (length_ != 1)
+ return NULL;
+ --length_;
+ return this;
+ }
-struct CYTypeUnsigned :
- CYTypeSpecifier
-{
- CYTypeSpecifier *specifier_;
+ CYTypeIntegral *Signed() {
+ if (signing_ != CYTypeNeutral)
+ return NULL;
+ signing_ = CYTypeSigned;
+ return this;
+ }
- CYTypeUnsigned(CYTypeSpecifier *specifier) :
- specifier_(specifier)
- {
+ CYTypeIntegral *Unsigned() {
+ if (signing_ != CYTypeNeutral)
+ return NULL;
+ signing_ = CYTypeUnsigned;
+ return this;
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
-struct CYTypeSigned :
+struct CYTypeVoid :
CYTypeSpecifier
{
- CYTypeSpecifier *specifier_;
-
- CYTypeSigned(CYTypeSpecifier *specifier) :
- specifier_(specifier)
- {
+ CYTypeVoid() {
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
-struct CYTypeLong :
+struct CYTypeReference :
CYTypeSpecifier
{
- CYTypeSpecifier *specifier_;
+ CYIdentifier *name_;
- CYTypeLong(CYTypeSpecifier *specifier) :
- specifier_(specifier)
+ CYTypeReference(CYIdentifier *name) :
+ name_(name)
{
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
-struct CYTypeShort :
+struct CYTypeVariable :
CYTypeSpecifier
{
- CYTypeSpecifier *specifier_;
+ CYIdentifier *name_;
- CYTypeShort(CYTypeSpecifier *specifier) :
- specifier_(specifier)
+ CYTypeVariable(CYIdentifier *name) :
+ name_(name)
{
}
- virtual CYExpression *Replace(CYContext &context);
+ CYTypeVariable(const char *name) :
+ name_(new($pool) CYIdentifier(name))
+ {
+ }
+
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
};
virtual int Precedence() const = 0;
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type) = 0;
- CYExpression *Replace(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type) = 0;
+ CYTarget *Replace(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const = 0;
void Output(CYOutput &out, int precedence, CYIdentifier *identifier) const;
CYPrecedence(1)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
};
CYPrecedence(0)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
};
CYPrecedence(0)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
};
CYPrecedence(0)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
};
return this;
}
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out) const;
CYTypeFunctionWith *Function();
};
struct CYEncodedType :
- CYExpression
+ CYTarget
{
CYTypedIdentifier *typed_;
CYPrecedence(1)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
virtual void Output(CYOutput &out) const;
};
+struct CYTypedFormal {
+ bool variadic_;
+ CYTypedParameter *parameters_;
+
+ CYTypedFormal(bool variadic) :
+ variadic_(variadic),
+ parameters_(NULL)
+ {
+ }
+};
+
struct CYLambda :
- CYExpression
+ CYTarget
{
CYTypedIdentifier *typed_;
CYTypedParameter *parameters_;
CYPrecedence(1)
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYImportSpecifier :
+ CYNext<CYImportSpecifier>
+{
+ CYWord *name_;
+ CYIdentifier *binding_;
+
+ CYImportSpecifier(CYWord *name, CYIdentifier *binding) :
+ name_(name),
+ binding_(binding)
+ {
+ }
+
+ CYStatement *Replace(CYContext &context, CYIdentifier *module);
+};
+
+struct CYImportDeclaration :
+ CYStatement
+{
+ CYImportSpecifier *specifiers_;
+ CYString *module_;
+
+ CYImportDeclaration(CYImportSpecifier *specifiers, CYString *module) :
+ specifiers_(specifiers),
+ module_(module)
+ {
+ }
+
+ CYCompact(None)
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYExternal :
CYStatement
{
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYTypeExpression :
+ CYTarget
+{
+ CYTypedIdentifier *typed_;
+
+ CYTypeExpression(CYTypedIdentifier *typed) :
+ typed_(typed)
+ {
+ }
+
+ CYPrecedence(0)
+
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYTypeDefinition :
CYStatement
{
CYPrecedence(0)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
};
struct CYTypeFunctionWith :
CYTypeModifier
{
+ bool variadic_;
CYTypedParameter *parameters_;
- CYTypeFunctionWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
+ CYTypeFunctionWith(bool variadic, CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
CYTypeModifier(next),
+ variadic_(variadic),
parameters_(parameters)
{
}
CYPrecedence(1)
- virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+ virtual CYTarget *Replace_(CYContext &context, CYTarget *type);
virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
virtual CYTypeFunctionWith *Function() { return this; }
};
+struct CYTypeStructField :
+ CYNext<CYTypeStructField>
+{
+ CYTypedIdentifier *typed_;
+
+ CYTypeStructField(CYTypedIdentifier *typed, CYTypeStructField *next = NULL) :
+ CYNext<CYTypeStructField>(next),
+ typed_(typed)
+ {
+ }
+};
+
+struct CYStructTail :
+ CYThing
+{
+ CYTypeStructField *fields_;
+
+ CYStructTail(CYTypeStructField *fields) :
+ fields_(fields)
+ {
+ }
+
+ CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeStruct :
+ CYTypeSpecifier
+{
+ CYIdentifier *name_;
+ CYStructTail *tail_;
+
+ CYTypeStruct(CYIdentifier *name, CYStructTail *tail) :
+ name_(name),
+ tail_(tail)
+ {
+ }
+
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYStructDefinition :
+ CYStatement
+{
+ CYIdentifier *name_;
+ CYStructTail *tail_;
+
+ CYStructDefinition(CYIdentifier *name, CYStructTail *tail) :
+ name_(name),
+ tail_(tail)
+ {
+ }
+
+ CYCompact(None)
+
+ virtual CYStatement *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
namespace cy {
namespace Syntax {
};
struct CYIndirect :
- CYPrefix
+ CYTarget
{
+ CYExpression *rhs_;
+
CYIndirect(CYExpression *rhs) :
- CYPrefix(rhs)
+ rhs_(rhs)
{
}
- virtual const char *Operator() const {
- return "*";
- }
+ // XXX: this should be checked
+ CYPrecedence(2)
- CYAlphabetic(false)
-
- virtual CYExpression *Replace(CYContext &context);
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
};
#define CYReplace \
struct CY ## name ## Assign : \
CYAssignment \
{ args \
- CY ## name ## Assign(CYExpression *lhs, CYExpression *rhs) : \
+ CY ## name ## Assign(CYTarget *lhs, CYExpression *rhs) : \
CYAssignment(lhs, rhs) \
{ \
} \