From 25cbab056b1f73e96b636c88779a92400d92dc15 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Tue, 18 Sep 2012 13:22:22 +0100 Subject: Slightly better string interpolation. --- c/lexer.l | 24 +++++++++++++++++++++--- c/parser.y | 8 ++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/c/lexer.l b/c/lexer.l index 412d9065..07cba83c 100644 --- a/c/lexer.l +++ b/c/lexer.l @@ -78,14 +78,32 @@ "%(" { return enter(QQSTRING_INTERP_START, YY_START, yyscanner); } - [a-z]+ { - yylval->literal = jv_string_sized(yytext, yyleng); - return QQSTRING_TEXT; + "%"[^(] { + return INVALID_CHARACTER; } ")" { yy_pop_state(yyscanner); return QQSTRING_END; } + "\\"[)%] { + char text[2] = {yytext[1], 0}; + yylval->literal = jv_string(text); + return QQSTRING_TEXT; + } + (\\[^u)%]|\\u[a-zA-Z0-9]{0,4})+ { + /* pass escapes to the json parser */ + jv escapes = jv_string_fmt("\"%.*s\"", yyleng, yytext); + yylval->literal = jv_parse_sized(jv_string_value(escapes), jv_string_length(jv_copy(escapes))); + jv_free(escapes); + return QQSTRING_TEXT; + } + [^\\)%]+ { + yylval->literal = jv_string_sized(yytext, yyleng); + return QQSTRING_TEXT; + } + . { + return INVALID_CHARACTER; + } } diff --git a/c/parser.y b/c/parser.y index 73972e79..b47c3574 100644 --- a/c/parser.y +++ b/c/parser.y @@ -102,7 +102,7 @@ int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors, if (tok == INVALID_CHARACTER) { FAIL(*yylloc, "Invalid character"); } else { - if (tok == LITERAL && !jv_is_valid(yylval->literal)) { + if ((tok == LITERAL || tok == QQSTRING_TEXT) && !jv_is_valid(yylval->literal)) { jv msg = jv_invalid_get_msg(jv_copy(yylval->literal)); if (jv_get_kind(msg) == JV_KIND_STRING) { FAIL(*yylloc, jv_string_value(msg)); @@ -147,6 +147,10 @@ static block gen_binop(block a, block b, int op) { return c; } +static block gen_format(block a) { + return block_join(a, gen_op_call(CALL_1_1, gen_op_block_unbound(CLOSURE_REF, "tostring"))); +} + static block gen_update(block a, block op, int optype) { block assign = a; block_append(&assign, gen_op_simple(DUP)); @@ -299,7 +303,7 @@ QQString QQSTRING_TEXT { $$ = gen_binop($1, gen_op_const(LOADK, $2), '+'); } | QQString QQSTRING_INTERP_START Exp QQSTRING_INTERP_END { - $$ = gen_binop($1, $3, '+'); + $$ = gen_binop($1, gen_format($3), '+'); } -- cgit v1.2.3