}
}
+#if YYDEBUG
+static bool bison_;
+#endif
+
+void Setup(cy::parser &parser) {
+#if YYDEBUG
+ if (bison_)
+ parser.set_debug_level(1);
+#endif
+}
+
void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expand = false) {
CYPool pool;
else {
CYDriver driver("");
cy::parser parser(driver);
- //parser.set_debug_level(1);
+ Setup(parser);
driver.data_ = command.c_str();
driver.size_ = command.size();
pid_t pid(_not(pid_t));
bool compile(false);
- for (;;) switch (getopt(argc, argv, "cp:")) {
+ for (;;) switch (getopt(argc, argv, "cg:p:")) {
case -1:
goto getopt;
case '?':
compile = true;
break;
+ case 'g':
+ if (false);
+#if YYDEBUG
+ else if (strcmp(optarg, "bison") == 0)
+ bison_ = true;
+#endif
+ else {
+ fprintf(stderr, "invalid name for -g\n");
+ return 1;
+ }
+ break;
+
case 'p': {
size_t size(strlen(optarg));
char *end;
else {
CYDriver driver(script ?: "<stdin>");
cy::parser parser(driver);
+ Setup(parser);
char *start, *end;
%{
+#define YYLTYPE cy::location
#include "Cycript.tab.hh"
typedef cy::parser::token tk;
#define YY_EXTRA_TYPE CYDriver *
-#define YYLTYPE cy::location
#define T yylval->newline_ = yyextra->state_ == CYNewLine;
#define C T yyextra->state_ = CYClear;
"volatile" L C yylval->word_ = new CYWord("volatile"); return tk::Volatile;
"each" L C yylval->word_ = new CYIdentifier("each"); return tk::Each;
+"let" L C yylval->word_ = new CYIdentifier("let"); return tk::Let;
[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
%defines
-//%debug
+%glr-parser
+%expect 1
+
+%debug
+
%error-verbose
%parse-param { CYDriver &driver }
%token <word_> Volatile "volatile"
%token <identifier_> Each "each"
+%token <identifier_> Let "let"
%token <identifier_> Identifier_
%token <number_> NumericLiteral
%type <expression_> BitwiseANDExpressionNoBF
%type <expression_> BitwiseANDExpressionNoIn
%type <statement_> Block
+%type <statement_> Block_
%type <boolean_> BooleanLiteral
%type <expression_> BitwiseORExpression
%type <expression_> BitwiseORExpressionNoBF
%type <statement_> LabelledStatement
%type <expression_> LeftHandSideExpression
%type <expression_> LeftHandSideExpressionNoBF
+%type <statement_> LetStatement
%type <literal_> Literal
%type <expression_> LogicalANDExpression
%type <expression_> LogicalANDExpressionNoBF
| error { if (yychar != 0 && yychar != cy::parser::token::CloseBrace && !yylval.newline_) YYABORT; else { yyerrok; driver.errors_.pop_back(); } }
;
-CommaOpt
+/*CommaOpt
: ","
|
- ;
+ ;*/
NewLineOpt
: "\n"
Identifier
: Identifier_ { $$ = $1; }
| "each" { $$ = $1; }
+ | "let" { $$ = $1; }
;
IdentifierOpt
PropertyNameAndValueList_
: "," PropertyNameAndValueList { $$ = $2; }
- | CommaOpt { $$ = NULL; }
+ | { $$ = NULL; }
;
PropertyNameAndValueListOpt
| TryStatement { $$ = $1; }
;
+Block_
+ : "{" StatementListOpt "}" { $$ = $2; }
+ ;
+
Block
- : "{" StatementListOpt "}" { if ($2) $$ = new(driver.pool_) CYBlock($2); else $$ = new(driver.pool_) CYEmpty(); }
+ : Block_ { if ($1) $$ = new(driver.pool_) CYBlock($1); else $$ = new(driver.pool_) CYEmpty(); }
;
StatementList
;
VariableStatement
- : "var" VariableDeclarationList Terminator { $$ = $2; }
+ : "var" VariableDeclarationList Terminator { $$ = new(driver.pool_) CYVar($2); }
;
VariableDeclarationList_
ForInStatement
: "for" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForIn($3, $5, $7); }
- | "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
;
ForInStatementInitialiser
;
TryStatement
- : "try" Block CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
+ : "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
;
CatchOpt
- : "catch" "(" Identifier ")" Block { $$ = new(driver.pool_) CYCatch($3, $5); }
+ : "catch" "(" Identifier ")" Block_ { $$ = new(driver.pool_) CYCatch($3, $5); }
| { $$ = NULL; }
;
FinallyOpt
- : "finally" Block { $$ = $2; }
+ : "finally" Block_ { $$ = $2; }
| { $$ = NULL; }
;
| FunctionDeclaration { $$ = $1; }
;
-/* Objective-C Extensions {{{ */
+/* Cycript: @class Declaration {{{ */
ClassSuperOpt
: ":" MemberExpressionNoBF { $$ = $2; }
| { $$ = NULL; }
: ClassDefinition { $$ = $1; }
| CategoryStatement { $$ = $1; }
;
-
+/* }}} */
+/* Cycript: Send Message {{{ */
VariadicCall
: "," AssignmentExpression VariadicCall { $$ = new(driver.pool_) CYArgument(NULL, $2, $3); }
| { $$ = NULL; }
| "@selector" "(" SelectorExpression ")" { $$ = new(driver.pool_) CYSelector($3); }
;
/* }}} */
-
+/* Cycript: Pointer Indirection/Addressing {{{ */
AssigneeExpression_
: "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); }
;
MemberAccess
: "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); }
;
-
+/* }}} */
+/* ECMAScript5: Object Literal Trailing Comma {{{ */
+PropertyNameAndValueList_
+ : "," { $$ = NULL; }
+ ;
+/* }}} */
+/* JavaScript 1.7: Array Comprehensions {{{ */
IfComprehension
: "if" "(" Expression ")" { $$ = new(driver.pool_) CYIfComprehension($3); }
;
PrimaryExpression_
: "[" AssignmentExpression ComprehensionList "]" { $$ = new(driver.pool_) CYArrayComprehension($2, $3); }
;
+/* }}} */
+/* JavaScript 1.7: for each {{{ */
+ForInStatement
+ : "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
+ ;
+/* }}} */
+/* JavaScript 1.7: Let Statements {{{ */
+LetStatement
+ : "let" "(" VariableDeclarationList ")" Block_ { $$ = new(driver.pool_) CYLet($3, $5); }
+ ;
+
+Statement
+ : LetStatement
+ ;
+/* }}} */
%%
void CYClause::Output(std::ostream &out) const {
if (case_ != NULL) {
out << "case";
- case_->Output(out, CYNoFlags);
+ case_->Output(out, CYNoLeader);
} else
out << "default";
out << ':';
if (code_ != NULL)
code_->Output(out, false);
- out << *next_;
+ if (next_ != NULL)
+ out << *next_;
+}
+
+const char *CYDeclaration::ForEachIn() const {
+ return identifier_->Value();
}
-void CYDeclaration::Part(std::ostream &out, CYFlags flags) const {
+void CYDeclaration::ForIn(std::ostream &out, CYFlags flags) const {
if ((flags & CYNoLeader) != 0)
out << ' ';
out << "var ";
out << ' ';
}
-void CYDeclarations::Part(std::ostream &out, CYFlags flags) const {
- if ((flags & CYNoLeader) != 0)
- out << ' ';
+void CYDeclarations::For(std::ostream &out) const {
out << "var ";
+ Output(out, CYNoIn);
+}
+void CYDeclarations::Output(std::ostream &out, CYFlags flags) const {
const CYDeclarations *declaration(this);
output:
CYDeclarations *next(declaration->next_);
}
}
-void CYDeclarations::Output(std::ostream &out) const {
- Part(out, CYNoFlags);
- out << ';';
-}
-
void CYDirectMember::Output(std::ostream &out, CYFlags flags) const {
object_->Output(out, Precedence(), CYLeft(flags));
if (const char *word = property_->Word())
Output(out, CYPA, CYNoFlags);
}
+const char *CYExpression::ForEachIn() const {
+ return NULL;
+}
+
+void CYExpression::For(std::ostream &out) const {
+ Output(out, CYNoIn);
+}
+
void CYExpression::ForEachIn(std::ostream &out) const {
// XXX: this should handle LeftHandSideExpression
Output(out, CYPA, CYNoFlags);
}
-void CYExpression::Part(std::ostream &out, CYFlags flags) const {
+void CYExpression::ForIn(std::ostream &out, CYFlags flags) const {
// XXX: this should handle LeftHandSideExpression
Output(out, flags);
}
void CYFor::Output(std::ostream &out) const {
out << "for(";
if (initialiser_ != NULL)
- initialiser_->Part(out, CYNoFlags);
+ initialiser_->For(out);
out << ';';
if (test_ != NULL)
test_->Output(out, CYNoFlags);
void CYForIn::Output(std::ostream &out) const {
out << "for(";
- initialiser_->Part(out, CYNoIn | CYNoTrailer);
+ initialiser_->ForIn(out, CYNoIn | CYNoTrailer);
out << "in";
set_->Output(out, CYNoLeader);
out << ')';
out << ')';
}
+void CYLet::Output(std::ostream &out) const {
+ out << "let(";
+ declarations_->Output(out, CYNoFlags);
+ out << "){";
+ if (statements_ != NULL)
+ statements_->Show(out);
+ out << "}";
+}
+
void CYMessage::Output(std::ostream &out, bool replace) const {
if (next_ != NULL)
next_->Output(out, replace);
}
}
+void CYVar::Output(std::ostream &out) const {
+ out << "var ";
+ declarations_->Output(out, CYNoFlags);
+ out << ';';
+}
+
void CYVariable::Output(std::ostream &out, CYFlags flags) const {
if ((flags & CYNoLeader) != 0)
out << ' ';
CYNoBF = (CYNoBrace | CYNoFunction),
};
-struct CYPart {
- virtual void Part(std::ostream &out, CYFlags flags) const = 0;
+struct CYForInitialiser {
+ virtual void For(std::ostream &out) const = 0;
};
-struct CYForInitialiser :
- CYPart
-{
-};
-
-struct CYForInInitialiser :
- CYPart
-{
+struct CYForInInitialiser {
+ virtual void ForIn(std::ostream &out, CYFlags flags) const = 0;
virtual const char *ForEachIn() const = 0;
virtual void ForEachIn(std::ostream &out) const = 0;
};
CYClassName
{
virtual unsigned Precedence() const = 0;
- virtual void Part(std::ostream &out, CYFlags flags) const;
- virtual const char *ForEachIn() const {
- return NULL;
- }
+ virtual void For(std::ostream &out) const;
+ virtual void ForIn(std::ostream &out, CYFlags flags) const;
+ virtual const char *ForEachIn() const;
virtual void ForEachIn(std::ostream &out) const;
virtual void Output(std::ostream &out, CYFlags flags) const = 0;
{
}
- virtual void Part(std::ostream &out, CYFlags flags) const;
-
- virtual const char *ForEachIn() const {
- return identifier_->Value();
- }
+ virtual void ForIn(std::ostream &out, CYFlags flags) const;
+ virtual const char *ForEachIn() const;
virtual void ForEachIn(std::ostream &out) const;
virtual void Output(std::ostream &out, CYFlags flags) const;
};
struct CYDeclarations :
- CYStatement,
+ CYNext<CYDeclarations>,
CYForInitialiser
{
CYDeclaration *declaration_;
- CYDeclarations *next_;
CYDeclarations(CYDeclaration *declaration, CYDeclarations *next) :
- declaration_(declaration),
- next_(next)
+ CYNext<CYDeclarations>(next),
+ declaration_(declaration)
+ {
+ }
+
+ virtual void For(std::ostream &out) const;
+ virtual void Output(std::ostream &out, CYFlags flags) const;
+};
+
+struct CYVar :
+ CYStatement
+{
+ CYDeclarations *declarations_;
+
+ CYVar(CYDeclarations *declarations) :
+ declarations_(declarations)
+ {
+ }
+
+ virtual void Output(std::ostream &out) const;
+};
+
+struct CYLet :
+ CYStatement
+{
+ CYDeclarations *declarations_;
+ CYStatement *statements_;
+
+ CYLet(CYDeclarations *declarations, CYStatement *statements) :
+ declarations_(declarations),
+ statements_(statements)
{
}
- virtual void Part(std::ostream &out, CYFlags flags) const;
virtual void Output(std::ostream &out) const;
};