summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 13:22:22 +0100
committerStephen Dolan <mu@netsoc.tcd.ie>2012-09-18 13:22:22 +0100
commit25cbab056b1f73e96b636c88779a92400d92dc15 (patch)
tree89fa9da3f5178a68660c5976101140bdbaeb54cb
parent8041ce31192af8b54e83691372f23b0b9637234c (diff)
Slightly better string interpolation.
-rw-r--r--c/lexer.l24
-rw-r--r--c/parser.y8
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), '+');
}