From 931b816a74a6791a373085a3f53b1dab592baf55 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 1 Oct 2009 21:24:18 +0000 Subject: [PATCH] Finished implementing strings. --- Application.mm | 12 +++++++++++- Cycript.l | 48 +++++++++++++++++++++++++++++++++++++++++++++--- Output.cpp | 2 +- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Application.mm b/Application.mm index 4dc765b..1739471 100644 --- a/Application.mm +++ b/Application.mm @@ -34,17 +34,27 @@ int main(int argc, const char *argv[]) { std::string command; std::vector lines; + bool extra(false); + const char *prompt("cy# "); + if (setjmp(ctrlc_) != 0) { fputs("\n", fout); fflush(fout); goto restart; } - const char *prompt("cy# "); read: char *line(readline(prompt)); if (line == NULL) break; + + if (!extra) { + extra = true; + if (line[0] == '\\') { + goto restart; + } + } + lines.push_back(line); command += line; free(line); diff --git a/Cycript.l b/Cycript.l index c711e8d..13ae15e 100644 --- a/Cycript.l +++ b/Cycript.l @@ -24,6 +24,16 @@ typedef cy::parser::token tk; yylloc->columns(yyleng); \ } +int H(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + #define YY_INPUT(data, value, size) { \ if (yyextra->size_ == 0) \ value = YY_NULL; \ @@ -48,7 +58,7 @@ typedef cy::parser::token tk; %option reentrant Exponent [eE][+-]?[0-9]+ -Escape \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} +Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} %% @@ -148,13 +158,45 @@ Escape \\['"\\bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4} 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]|{Escape})*\"|'([^'\\\n]|{Escape})*' L C { + char *value(reinterpret_cast(apr_palloc(yyextra->pool_, yyleng))); + char *local(value); + + for (int i(1); i != yyleng - 1; ++i) { + char next(yytext[i]); + + if (yytext[i] == '\\') + switch (next = yytext[++i]) { + case '\\': next = '\\'; break; + case '\'': next = '\''; break; + case '"': next = '"'; break; + case 'b': next = '\b'; break; + case 'f': next = '\f'; break; + case 'n': next = '\n'; break; + case 'r': next = '\r'; break; + case 't': next = '\t'; break; + case 'v': next = '\v'; break; + case '0': next = '\0'; break; + + case 'x': + next = H(yytext[i + 1]) << 4 | H(yytext[i + 2]); + i += 2; + break; + } + + *local++ = next; + } + + *local = '\0'; + yylval->string_ = new CYString(value, local - value); + return tk::StringLiteral; +} \n yylloc->end.lines(); yylloc->step(); N [ \t] L <> L yyterminate(); +. yyterminate(); %% diff --git a/Output.cpp b/Output.cpp index 2b10d71..edd262f 100644 --- a/Output.cpp +++ b/Output.cpp @@ -294,7 +294,7 @@ void CYSelector::Output(std::ostream &out) const { void CYSource::Show(std::ostream &out) const { for (const CYSource *next(this); next != NULL; next = next->next_) - next->Output(out); + next->Output(out, false); } void CYSource::Output(std::ostream &out, bool block) const { -- 2.47.2