diff --git a/src/read.c b/src/read.c index 52594a90..c50080c4 100644 --- a/src/read.c +++ b/src/read.c @@ -91,9 +91,6 @@ read_datum(int tok, yyscan_t scanner) case tSYMBOL: return pic_symbol_value(pic_intern(pic, yylval.str.buf, yylval.str.len)); - case tSTRING: - return pic_obj_value(pic_str_new(pic, yylval.str.buf, yylval.str.len)); - case tINT: return pic_int_value(yylval.i); @@ -106,6 +103,11 @@ read_datum(int tok, yyscan_t scanner) case tCHAR: return pic_char_value(yylval.c); + case tSTRING: + val = pic_obj_value(pic_str_new(pic, yylval.str.buf, yylval.str.len)); + pic_free(pic, yylval.str.buf); + return val; + case tBYTEVECTOR: val = pic_obj_value(pic_blob_new(pic, yylval.blob.dat, yylval.blob.len)); pic_free(pic, yylval.blob.dat); diff --git a/src/scan.l b/src/scan.l index 055aff98..1ddb0e92 100644 --- a/src/scan.l +++ b/src/scan.l @@ -118,13 +118,33 @@ infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0" "\"" { BEGIN(STRING); + yylval.str.len = 0; + yylval.str.buf = yyalloc(yylval.str.len + 1, yyscanner); + strcpy(yylval.str.buf, ""); } -[^\\"]* { - yymore(); +[^\\"]+ { + yylval.str.len += yyleng; + yylval.str.buf = yyrealloc(yylval.str.buf, yylval.str.len + 1, yyscanner); + strcpy(yylval.str.buf + yylval.str.len - yyleng, yytext); } -"\"" { - yylval.str.buf = yytext; - yylval.str.len = yyleng - 1; +\\. { + yylval.str.len += 1; + yylval.str.buf = yyrealloc(yylval.str.buf, yylval.str.len + 1, yyscanner); + yylval.str.buf[yylval.str.len] = '\0'; + + switch (yytext[yyleng - 1]) { + case 'a': yylval.str.buf[yylval.str.len - 1] = '\a'; break; + case 'b': yylval.str.buf[yylval.str.len - 1] = '\b'; break; + case 't': yylval.str.buf[yylval.str.len - 1] = '\t'; break; + case 'n': yylval.str.buf[yylval.str.len - 1] = '\n'; break; + case 'r': yylval.str.buf[yylval.str.len - 1] = '\r'; break; + default: yylval.str.buf[yylval.str.len - 1] = yytext[yyleng - 1]; break; + } +} +\\[:blank:]*\n[:blank:]* { + /* skip intraline whitespaces */ +} +\" { BEGIN(INITIAL); return tSTRING; }