]> git.saurik.com Git - cycript.git/commitdiff
Locations, array literal elisions, and fixed prompting.
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 1 Oct 2009 20:10:20 +0000 (20:10 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 1 Oct 2009 20:10:20 +0000 (20:10 +0000)
Cycript.l
Cycript.y
Library.mm
Output.cpp
Parser.hpp

index eb0c692a1d310968c1d74b1a6993bad7dd089746..c711e8df163afc2160d70ed1ff377a14e67a3a74 100644 (file)
--- a/Cycript.l
+++ b/Cycript.l
@@ -8,7 +8,21 @@ typedef cy::parser::token tk;
 #define T yylval->newline_ = yyextra->state_ == CYNewLine;
 #define C T yyextra->state_ = CYClear;
 #define R T yyextra->state_ = CYRestricted;
 #define T yylval->newline_ = yyextra->state_ == CYNewLine;
 #define C T yyextra->state_ = CYClear;
 #define R T yyextra->state_ = CYRestricted;
-#define N if (yyextra->state_ != CYNewLine) { bool restricted(yyextra->state_ == CYRestricted); if (restricted) { yyextra->state_ = CYClear; return tk::NewLine; } else yyextra->state_ = CYNewLine; }
+
+#define N \
+    if (yyextra->state_ != CYNewLine) { \
+        bool restricted(yyextra->state_ == CYRestricted); \
+        if (restricted) { \
+            yyextra->state_ = CYClear; \
+            return tk::NewLine; \
+        } else \
+            yyextra->state_ = CYNewLine; \
+    }
+
+#define L { \
+    yylloc->step(); \
+    yylloc->columns(yyleng); \
+}
 
 #define YY_INPUT(data, value, size) { \
     if (yyextra->size_ == 0) \
 
 #define YY_INPUT(data, value, size) { \
     if (yyextra->size_ == 0) \
@@ -41,104 +55,106 @@ Escape   \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}
 \/\/[^\n]* ;
 \/\*(\n|[^\*]|\*[^/])\*\/ if (memchr(yytext, '\n', yyleng) != NULL) N // XXX: supposedly I will be screwed on very very long multi-line comments and need to replace this with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf ; XXX: this rule doesn't work anyway, fucking A :(
 
 \/\/[^\n]* ;
 \/\*(\n|[^\*]|\*[^/])\*\/ if (memchr(yytext, '\n', yyleng) != NULL) N // XXX: supposedly I will be screwed on very very long multi-line comments and need to replace this with a manual lexer. http://websrv.cs.fsu.edu/~engelen/courses/COP5621/Pr2.pdf ; XXX: this rule doesn't work anyway, fucking A :(
 
-"&"    C return tk::Ampersand;
-"&&"   C return tk::AmpersandAmpersand;
-"&="   C return tk::AmpersandEqual;
-"^"    C return tk::Carrot;
-"^="   C return tk::CarrotEqual;
-"="    C return tk::Equal;
-"=="   C return tk::EqualEqual;
-"==="  C return tk::EqualEqualEqual;
-"!"    C return tk::Exclamation;
-"!="   C return tk::ExclamationEqual;
-"!=="  C return tk::ExclamationEqualEqual;
-"-"    C return tk::Hyphen;
-"-="   C return tk::HyphenEqual;
-"--"   C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen;
-"->"   C return tk::HyphenRight;
-"<"    C return tk::Left;
-"<="   C return tk::LeftEqual;
-"<<"   C return tk::LeftLeft;
-"<<="  C return tk::LeftLeftEqual;
-"%"    C return tk::Percent;
-"%="   C return tk::PercentEqual;
-"."    C return tk::Period;
-"|"    C return tk::Pipe;
-"|="   C return tk::PipeEqual;
-"||"   C return tk::PipePipe;
-"+"    C return tk::Plus;
-"+="   C return tk::PlusEqual;
-"++"   C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus;
-">"    C return tk::Right;
-">="   C return tk::RightEqual;
-">>"   C return tk::RightRight;
-">>="  C return tk::RightRightEqual;
-">>>"  C return tk::RightRightRight;
-">>>=" C return tk::RightRightRightEqual;
-"/"    C return tk::Slash;
-"/="   C return tk::SlashEqual;
-"*"    C return tk::Star;
-"*="   C return tk::StarEqual;
-"~"    C return tk::Tilde;
-
-":"    C return tk::Colon;
-","    C return tk::Comma;
-"?"    C return tk::Question;
-";"    C return tk::SemiColon;
-
-"("    C return tk::OpenParen;
-")"    C return tk::CloseParen;
-
-"{"    C return tk::OpenBrace;
-"}"    C return tk::CloseBrace;
-
-"["    C return tk::OpenBracket;
-"]"    C return tk::CloseBracket;
-
-"@selector"  C return tk::AtSelector;
-
-"break"      R yylval->word_ = new CYWord("break"); return tk::Break;
-"case"       C yylval->word_ = new CYWord("case"); return tk::Case;
-"catch"      C yylval->word_ = new CYWord("catch"); return tk::Catch;
-"continue"   R yylval->word_ = new CYWord("continue"); return tk::Continue;
-"default"    C yylval->word_ = new CYWord("default"); return tk::Default;
-"delete"     C yylval->word_ = new CYWord("delete"); return tk::Delete;
-"do"         C yylval->word_ = new CYWord("do"); return tk::Do;
-"else"       C yylval->word_ = new CYWord("else"); return tk::Else;
-"false"      C yylval->false_ = new CYFalse(); return tk::False;
-"finally"    C yylval->word_ = new CYWord("finally"); return tk::Finally;
-"for"        C yylval->word_ = new CYWord("for"); return tk::For;
-"function"   C yylval->word_ = new CYWord("function"); return tk::Function;
-"if"         C yylval->word_ = new CYWord("if"); return tk::If;
-"in"         C yylval->word_ = new CYWord("in"); return tk::In;
-"instanceof" C yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf;
-"new"        C yylval->word_ = new CYWord("new"); return tk::New;
-"null"       C yylval->null_ = new CYNull(); return tk::Null;
-"return"     R yylval->word_ = new CYWord("return"); return tk::Return;
-"switch"     C yylval->word_ = new CYWord("switch"); return tk::Switch;
-"this"       C yylval->this_ = new CYThis(); return tk::This;
-"throw"      R yylval->word_ = new CYWord("throw"); return tk::Throw;
-"true"       C yylval->true_ = new CYTrue(); return tk::True;
-"try"        C yylval->word_ = new CYWord("try"); return tk::Try;
-"typeof"     C yylval->word_ = new CYWord("typeof"); return tk::TypeOf;
-"var"        C yylval->word_ = new CYWord("var"); return tk::Var;
-"void"       C yylval->word_ = new CYWord("void"); return tk::Void;
-"while"      C yylval->word_ = new CYWord("while"); return tk::While;
-"with"       C yylval->word_ = new CYWord("with"); return tk::With;
-
-[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); C return tk::Identifier;
-
-(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); C return tk::NumericLiteral;
-
-0[xX][0-9a-fA-F]+ C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral;
-
-0[bB][0-1]+ C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral;
-
-\"([^"\\\n]|{Escape})*\" C return tk::StringLiteral;
-'([^'\\\n]|{Escape})*' C return tk::StringLiteral;
-
-\n N
-[ \t] ;
+"&"    L C return tk::Ampersand;
+"&&"   L C return tk::AmpersandAmpersand;
+"&="   L C return tk::AmpersandEqual;
+"^"    L C return tk::Carrot;
+"^="   L C return tk::CarrotEqual;
+"="    L C return tk::Equal;
+"=="   L C return tk::EqualEqual;
+"==="  L C return tk::EqualEqualEqual;
+"!"    L C return tk::Exclamation;
+"!="   L C return tk::ExclamationEqual;
+"!=="  L C return tk::ExclamationEqualEqual;
+"-"    L C return tk::Hyphen;
+"-="   L C return tk::HyphenEqual;
+"--"   L C return yylval->newline_ ? tk::HyphenHyphen_ : tk::HyphenHyphen;
+"->"   L C return tk::HyphenRight;
+"<"    L C return tk::Left;
+"<="   L C return tk::LeftEqual;
+"<<"   L C return tk::LeftLeft;
+"<<="  L C return tk::LeftLeftEqual;
+"%"    L C return tk::Percent;
+"%="   L C return tk::PercentEqual;
+"."    L C return tk::Period;
+"|"    L C return tk::Pipe;
+"|="   L C return tk::PipeEqual;
+"||"   L C return tk::PipePipe;
+"+"    L C return tk::Plus;
+"+="   L C return tk::PlusEqual;
+"++"   L C return yylval->newline_ ? tk::PlusPlus_ : tk::PlusPlus;
+">"    L C return tk::Right;
+">="   L C return tk::RightEqual;
+">>"   L C return tk::RightRight;
+">>="  L C return tk::RightRightEqual;
+">>>"  L C return tk::RightRightRight;
+">>>=" L C return tk::RightRightRightEqual;
+"/"    L C return tk::Slash;
+"/="   L C return tk::SlashEqual;
+"*"    L C return tk::Star;
+"*="   L C return tk::StarEqual;
+"~"    L C return tk::Tilde;
+
+":"    L C return tk::Colon;
+","    L C return tk::Comma;
+"?"    L C return tk::Question;
+";"    L C return tk::SemiColon;
+
+"("    L C return tk::OpenParen;
+")"    L C return tk::CloseParen;
+
+"{"    L C return tk::OpenBrace;
+"}"    L C return tk::CloseBrace;
+
+"["    L C return tk::OpenBracket;
+"]"    L C return tk::CloseBracket;
+
+"@selector"  L C return tk::AtSelector;
+
+"break"      L R yylval->word_ = new CYWord("break"); return tk::Break;
+"case"       L C yylval->word_ = new CYWord("case"); return tk::Case;
+"catch"      L C yylval->word_ = new CYWord("catch"); return tk::Catch;
+"continue"   L R yylval->word_ = new CYWord("continue"); return tk::Continue;
+"default"    L C yylval->word_ = new CYWord("default"); return tk::Default;
+"delete"     L C yylval->word_ = new CYWord("delete"); return tk::Delete;
+"do"         L C yylval->word_ = new CYWord("do"); return tk::Do;
+"else"       L C yylval->word_ = new CYWord("else"); return tk::Else;
+"false"      L C yylval->false_ = new CYFalse(); return tk::False;
+"finally"    L C yylval->word_ = new CYWord("finally"); return tk::Finally;
+"for"        L C yylval->word_ = new CYWord("for"); return tk::For;
+"function"   L C yylval->word_ = new CYWord("function"); return tk::Function;
+"if"         L C yylval->word_ = new CYWord("if"); return tk::If;
+"in"         L C yylval->word_ = new CYWord("in"); return tk::In;
+"instanceof" L C yylval->word_ = new CYWord("instanceof"); return tk::InstanceOf;
+"new"        L C yylval->word_ = new CYWord("new"); return tk::New;
+"null"       L C yylval->null_ = new CYNull(); return tk::Null;
+"return"     L R yylval->word_ = new CYWord("return"); return tk::Return;
+"switch"     L C yylval->word_ = new CYWord("switch"); return tk::Switch;
+"this"       L C yylval->this_ = new CYThis(); return tk::This;
+"throw"      L R yylval->word_ = new CYWord("throw"); return tk::Throw;
+"true"       L C yylval->true_ = new CYTrue(); return tk::True;
+"try"        L C yylval->word_ = new CYWord("try"); return tk::Try;
+"typeof"     L C yylval->word_ = new CYWord("typeof"); return tk::TypeOf;
+"var"        L C yylval->word_ = new CYWord("var"); return tk::Var;
+"void"       L C yylval->word_ = new CYWord("void"); return tk::Void;
+"while"      L C yylval->word_ = new CYWord("while"); return tk::While;
+"with"       L C yylval->word_ = new CYWord("with"); return tk::With;
+
+[a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier;
+
+(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?){Exponent}? yylval->number_ = new CYNumber(strtod(yytext, NULL)); L C return tk::NumericLiteral;
+
+0[xX][0-9a-fA-F]+ L C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 16)); return tk::NumericLiteral;
+
+0[bB][0-1]+ L C yylval->number_ = new CYNumber(strtoull(yytext + 2, NULL, 2)); return tk::NumericLiteral;
+
+\"([^"\\\n]|{Escape})*\" L C return tk::StringLiteral;
+'([^'\\\n]|{Escape})*' L C return tk::StringLiteral;
+
+\n yylloc->end.lines(); yylloc->step(); N
+
+[ \t] L
+<<EOF>> L yyterminate();
 
 %%
 
 
 %%
 
index b7e17eb7bac4fb912bc749c6deaea608a46063d0..46e81a4a25e0123f6c1d9cfcce37c847261d7f8e 100644 (file)
--- a/Cycript.y
+++ b/Cycript.y
@@ -189,8 +189,9 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %type <clause_> DefaultClause
 %type <statement_> DoWhileStatement
 %type <expression_> Element
 %type <clause_> DefaultClause
 %type <statement_> DoWhileStatement
 %type <expression_> Element
+%type <expression_> ElementOpt
 %type <element_> ElementList
 %type <element_> ElementList
-%type <element_> ElementList_
+%type <element_> ElementListOpt
 %type <statement_> ElseStatementOpt
 %type <statement_> EmptyStatement
 %type <expression_> EqualityExpression
 %type <statement_> ElseStatementOpt
 %type <statement_> EmptyStatement
 %type <expression_> EqualityExpression
@@ -300,13 +301,13 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 TerminatorOpt
     : ";"
     | "\n"
 TerminatorOpt
     : ";"
     | "\n"
-    | error { yyerrok; }
+    | error { yyerrok; driver.errors_.pop_back(); }
     ;
 
 Terminator
     : ";"
     | "\n"
     ;
 
 Terminator
     : ";"
     | "\n"
-    | error { if (yychar != 0 && yychar != cy::parser::token::CloseBrace && !yylval.newline_) YYABORT; else yyerrok; }
+    | error { if (yychar != 0 && yychar != cy::parser::token::CloseBrace && !yylval.newline_) YYABORT; else { yyerrok; driver.errors_.pop_back(); } }
     ;
 
 CommaOpt
     ;
 
 CommaOpt
@@ -397,26 +398,31 @@ PrimaryExpressionNoBF
 /* }}} */
 /* 11.1.4 Array Initialiser {{{ */
 ArrayLiteral
 /* }}} */
 /* 11.1.4 Array Initialiser {{{ */
 ArrayLiteral
-    : "[" ElementList "]" { $$ = $2; }
+    : "[" ElementList "]" { $$ = new(driver.pool_) CYArray($2); }
     ;
 
 Element
     : AssignmentExpression { $$ = $1; }
     ;
 
 Element
     : AssignmentExpression { $$ = $1; }
+    ;
+
+ElementOpt
+    : Element { $$ = $1; }
     | { $$ = NULL; }
     ;
 
     | { $$ = NULL; }
     ;
 
-ElementList_
-    : "," ElementList { $$ = $2; }
+ElementListOpt
+    : ElementList { $$ = $1; }
     | { $$ = NULL; }
     ;
 
 ElementList
     | { $$ = NULL; }
     ;
 
 ElementList
-    : Element ElementList_ { $$ = new(driver.pool_) CYElement($1, $2); }
+    : ElementOpt "," ElementListOpt { $$ = new(driver.pool_) CYElement($1, $3); }
+    | Element { $$ = new(driver.pool_) CYElement($1, NULL); }
     ;
 /* }}} */
 /* 11.1.5 Object Initialiser {{{ */
 ObjectLiteral
     ;
 /* }}} */
 /* 11.1.5 Object Initialiser {{{ */
 ObjectLiteral
-    : "{" PropertyNameAndValueListOpt "}" { $$ = new CYObject($2); }
+    : "{" PropertyNameAndValueListOpt "}" { $$ = new(driver.pool_) CYObject($2); }
     ;
 
 PropertyNameAndValueList_
     ;
 
 PropertyNameAndValueList_
@@ -834,8 +840,7 @@ Statement
     ;
 
 Block
     ;
 
 Block
-    : "{" "}" { $$ = new(driver.pool_) CYEmpty(); }
-    | "{" StatementList "}" { $$ = $2; }
+    : "{" StatementListOpt "}" { $$ = $2 ?: new(driver.pool_) CYEmpty(); }
     ;
 
 StatementList
     ;
 
 StatementList
@@ -1028,7 +1033,7 @@ FunctionBody
     ;
 
 Program
     ;
 
 Program
-    : SourceElements { driver.source_.push_back($1); $$ = $1; }
+    : SourceElements { driver.source_ = $1; }
     ;
 
 SourceElements
     ;
 
 SourceElements
@@ -1036,10 +1041,6 @@ SourceElements
     | { $$ = NULL; }
     ;
 
     | { $$ = NULL; }
     ;
 
-/*Command
-    : SourceElement { driver.source_.push_back($2); if (driver.filename_.empty() && false) YYACCEPT; $2->Show(std::cout); }
-    ;*/
-
 SourceElement
     : Statement { $$ = $1; }
     | FunctionDeclaration { $$ = $1; }
 SourceElement
     : Statement { $$ = $1; }
     | FunctionDeclaration { $$ = $1; }
@@ -1075,12 +1076,12 @@ SelectorExpressionOpt
     ;
 
 SelectorExpression_
     ;
 
 SelectorExpression_
-    : WordOpt ":" SelectorExpressionOpt { $$ = new CYSelector($1, true, $3); }
+    : WordOpt ":" SelectorExpressionOpt { $$ = new(driver.pool_) CYSelector($1, true, $3); }
     ;
 
 SelectorExpression
     : SelectorExpression_ { $$ = $1; }
     ;
 
 SelectorExpression
     : SelectorExpression_ { $$ = $1; }
-    | Word { $$ = new CYSelector($1, false, NULL); }
+    | Word { $$ = new(driver.pool_) CYSelector($1, false, NULL); }
     ;
 
 PrimaryExpression_
     ;
 
 PrimaryExpression_
index 1187375933449c6506372bd44342a4dd5aee0a62..2dc719e83b69613868929803b2014616903b2cce 100644 (file)
@@ -931,16 +931,11 @@ CYDriver::~CYDriver() {
     ScannerDestroy();
 }
 
     ScannerDestroy();
 }
 
-void CYDriver::Clear() {
-    pool_.Clear();
-    state_ = CYClear;
-    data_ = NULL;
-    size_ = 0;
-    source_.clear();
-}
-
-void cy::parser::error(const cy::parser::location_type &loc, const std::string &msg) {
-    std::cerr << loc << ": " << msg << std::endl;
+void cy::parser::error(const cy::parser::location_type &location, const std::string &message) {
+    CYDriver::Error error;
+    error.location_ = location;
+    error.message_ = message;
+    driver.errors_.push_back(error);
 }
 
 void CYConsole(FILE *fin, FILE *fout, FILE *ferr) {
 }
 
 void CYConsole(FILE *fin, FILE *fout, FILE *ferr) {
@@ -949,67 +944,85 @@ void CYConsole(FILE *fin, FILE *fout, FILE *ferr) {
     __gnu_cxx::stdio_filebuf<char> bin(fin, std::ios::in);
     std::istream sin(&bin);
 
     __gnu_cxx::stdio_filebuf<char> bin(fin, std::ios::in);
     std::istream sin(&bin);
 
-    CYDriver driver("");
-
-    while (!feof(fin)) { _pooled
-        driver.Clear();
-
+    restart: while (!feof(fin)) { _pooled
         fputs("cy# ", fout);
         fflush(fout);
 
         fputs("cy# ", fout);
         fflush(fout);
 
-        cy::parser parser(driver);
         std::string command;
         std::string command;
+        std::vector<std::string> lines;
+
+      read:
+        if (!std::getline(sin, line))
+            break;
+
+        lines.push_back(line);
+        command += line;
+
+        CYDriver driver("");
+        cy::parser parser(driver);
+
+        driver.data_ = command.c_str();
+        driver.size_ = command.size();
+
+        if (parser.parse() != 0) {
+            for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i) {
+                cy::position begin(i->location_.begin);
+                if (begin.line != lines.size() || begin.column - 1 != lines.back().size()) {
+                    std::cerr << i->message_ << std::endl;
+                    goto restart;
+                }
+            }
+
+            driver.errors_.clear();
 
 
-        for (;;) {
-            if (!std::getline(sin, line))
-                return;
-            command += line;
-            driver.data_ = command.c_str();
-            driver.size_ = command.size();
-            if (parser.parse() == 0)
-                break;
             fputs("cy> ", fout);
             fflush(fout);
             fputs("cy> ", fout);
             fflush(fout);
-        }
 
 
-        for (std::vector<CYSource *>::const_iterator i(driver.source_.begin()); i != driver.source_.end(); ++i) {
-            CYSource *source(*i);
+            command += '\n';
+            goto read;
+        }
 
 
-            std::ostringstream str;
-            source->Show(str);
+        if (driver.source_ == NULL)
+            goto restart;
 
 
-            std::string code(str.str());
-            std::cout << code << std::endl;
+        std::ostringstream str;
+        driver.source_->Show(str);
 
 
-            JSStringRef script(JSStringCreateWithUTF8CString(code.c_str()));
+        std::string code(str.str());
+        std::cout << code << std::endl;
 
 
-            JSContextRef context(JSGetContext());
+        JSStringRef script(JSStringCreateWithUTF8CString(code.c_str()));
 
 
-            JSValueRef exception(NULL);
-            JSValueRef result(JSEvaluateScript(context, script, NULL, NULL, 0, &exception));
-            JSStringRelease(script);
+        JSContextRef context(JSGetContext());
 
 
-            if (exception != NULL)
-                result = exception;
+        JSValueRef exception(NULL);
+        JSValueRef result(JSEvaluateScript(context, script, NULL, NULL, 0, &exception));
+        JSStringRelease(script);
 
 
-            if (!JSValueIsUndefined(context, result)) {
-                CFStringRef json;
+        if (exception != NULL)
+            result = exception;
 
 
-                @try { json:
-                    json = JSValueToJSONCopy(context, result);
-                } @catch (id error) {
-                    CYThrow(context, error, &result);
-                    goto json;
-                }
+        if (JSValueIsUndefined(context, result))
+            goto restart;
 
 
-                fputs([reinterpret_cast<const NSString *>(json) UTF8String], fout);
-                CFRelease(json);
+        CFStringRef json;
 
 
-                fputs("\n", fout);
-                fflush(fout);
-            }
+        @try { json:
+            json = JSValueToJSONCopy(context, result);
+        } @catch (id error) {
+            CYThrow(context, error, &result);
+            goto json;
         }
         }
+
+        fputs([reinterpret_cast<const NSString *>(json) UTF8String], fout);
+        CFRelease(json);
+
+        fputs("\n", fout);
+        fflush(fout);
     }
     }
+
+    fputs("\n", fout);
+    fflush(fout);
 }
 
 MSInitialize { _pooled
 }
 
 MSInitialize { _pooled
index 4e4040a5f00b36ed1fa923f5c85abf571f82325d..2b10d71c093c7600f9d6c0e4acf28838d1eb9bfc 100644 (file)
@@ -28,6 +28,13 @@ void CYArgument::Output(std::ostream &out, bool send) const {
     }
 }
 
     }
 }
 
+void CYArray::Output(std::ostream &out) const {
+    out << '[';
+    if (elements_ != NULL)
+        elements_->Output(out);
+    out << ']';
+}
+
 void CYBoolean::Output(std::ostream &out) const {
     out << (Value() ? "true" : "false");
 }
 void CYBoolean::Output(std::ostream &out) const {
     out << (Value() ? "true" : "false");
 }
@@ -107,21 +114,13 @@ void CYDoWhile::Output(std::ostream &out) const {
     out << "while" << *test_ << ';';
 }
 
     out << "while" << *test_ << ';';
 }
 
-void CYElement::Output(std::ostream &out, bool raw) const {
-    if (!raw)
-        out << '[';
+void CYElement::Output(std::ostream &out) const {
     if (value_ != NULL)
         value_->Output(out, true);
     if (value_ != NULL)
         value_->Output(out, true);
-    if (next_ != NULL) {
+    if (next_ != NULL || value_ == NULL)
         out << ',';
         out << ',';
-        next_->Output(out, true);
-    }
-    if (!raw)
-        out << ']';
-}
-
-void CYElement::Output(std::ostream &out) const {
-    Output(out, false);
+    if (next_ != NULL)
+        next_->Output(out);
 }
 
 void CYEmpty::Output(std::ostream &out) const {
 }
 
 void CYEmpty::Output(std::ostream &out) const {
index 346fb93271f7f697612fdbe4b945f7936db917b0..2663eb85dc71c48fc5bde633314e8074be38a550 100644 (file)
@@ -5,6 +5,7 @@
 #include <string>
 #include <vector>
 
 #include <string>
 #include <vector>
 
+#include "location.hh"
 #include "Pooling.hpp"
 
 template <typename Type_>
 #include "Pooling.hpp"
 
 template <typename Type_>
@@ -117,7 +118,15 @@ class CYDriver {
 
     std::string filename_;
 
 
     std::string filename_;
 
-    std::vector<CYSource *> source_;
+    struct Error {
+        cy::location location_;
+        std::string message_;
+    };
+
+    typedef std::vector<Error> Errors;
+
+    CYSource *source_;
+    Errors errors_;
 
   private:
     void ScannerInit();
 
   private:
     void ScannerInit();
@@ -126,8 +135,6 @@ class CYDriver {
   public:
     CYDriver(const std::string &filename);
     ~CYDriver();
   public:
     CYDriver(const std::string &filename);
     ~CYDriver();
-
-    void Clear();
 };
 
 struct CYForInitialiser :
 };
 
 struct CYForInitialiser :
@@ -399,9 +406,7 @@ struct CYClause :
     virtual void Output(std::ostream &out) const;
 };
 
     virtual void Output(std::ostream &out) const;
 };
 
-struct CYElement :
-    CYLiteral
-{
+struct CYElement {
     CYExpression *value_;
     CYElement *next_;
 
     CYExpression *value_;
     CYElement *next_;
 
@@ -411,7 +416,19 @@ struct CYElement :
     {
     }
 
     {
     }
 
-    void Output(std::ostream &out, bool raw) const;
+    void Output(std::ostream &out) const;
+};
+
+struct CYArray :
+    CYLiteral
+{
+    CYElement *elements_;
+
+    CYArray(CYElement *elements) :
+        elements_(elements)
+    {
+    }
+
     virtual void Output(std::ostream &out) const;
 };
 
     virtual void Output(std::ostream &out) const;
 };