diff --git a/include/picrin.h b/include/picrin.h index 12a01233..3cf3fb36 100644 --- a/include/picrin.h +++ b/include/picrin.h @@ -66,6 +66,8 @@ bool pic_eq_p(pic_state *, pic_value, pic_value); pic_value pic_intern_cstr(pic_state *, const char *); +pic_value pic_str_new_cstr(pic_state *, const char *); + bool pic_parse(pic_state *, const char *, pic_value *); pic_value pic_eval(pic_state *, pic_value, struct pic_env *); diff --git a/include/picrin/string.h b/include/picrin/string.h index ccef6efb..f4a1d39f 100644 --- a/include/picrin/string.h +++ b/include/picrin/string.h @@ -9,6 +9,4 @@ struct pic_string { #define pic_str_ptr(v) ((struct pic_string *)v.u.data) -pic_value pic_str_new_cstr(pic_state *, const char *); - #endif diff --git a/src/codegen.c b/src/codegen.c index 59a341e6..5e82cc6d 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -374,6 +374,15 @@ pic_gen(pic_state *pic, struct pic_irep *irep, pic_value obj, struct pic_env *en irep->clen++; break; } + case PIC_TT_STRING: { + int pidx; + pidx = pic->plen++; + pic->pool[pidx] = obj; + irep->code[irep->clen].insn = OP_PUSHCONST; + irep->code[irep->clen].u.i = pidx; + irep->clen++; + break; + } case PIC_TT_PROC: case PIC_TT_UNDEF: case PIC_TT_PORT: { diff --git a/src/parse.y b/src/parse.y index 0a76e282..885d055d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -29,10 +29,10 @@ int yylex(struct parser_control *); %token tLPAREN tRPAREN tDOT %token tQUOTE -%token tSYMBOL tNUMBER tBOOLEAN +%token tSYMBOL tNUMBER tBOOLEAN tSTRING -%type datum simple_datum symbol compound_datum abbrev -%type number boolean list list_data +%type datum simple_datum compound_datum abbrev +%type list list_data %% @@ -58,24 +58,10 @@ datum ; simple_datum - : symbol - | number - | boolean -; - -symbol : tSYMBOL - { - $$ = $1; - } -; - -number - : tNUMBER -; - -boolean - : tBOOLEAN + | tNUMBER + | tBOOLEAN + | tSTRING ; compound_datum diff --git a/src/scan.l b/src/scan.l index 62cf0d2a..f23ebdc3 100644 --- a/src/scan.l +++ b/src/scan.l @@ -1,5 +1,6 @@ %{ #include +#include #include "picrin.h" #include "y.tab.h" @@ -10,6 +11,8 @@ struct parser_control { bool incomp; }; +static pic_value escape_string(pic_state *, const char *); + #define YY_DECL int yylex (struct parser_control *p) %} @@ -29,6 +32,10 @@ ureal {digit}+|\.{digit}+|{digit}+\.{digit}* sign [+-]? infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0" + /* string */ +string \"{string_elem}*\" +string_elem [^\"\\]|"\\\""|"\\\\" + %% [ \t\n\r] /* skip whitespace */ @@ -39,6 +46,10 @@ infnan "+inf.0"|"-inf.0"|"+nan.0"|"-nan.0" {boolean} { yylval.datum = pic_bool_value(strcmp(yytext, "#t") == 0 || strcmp(yytext, "#true") == 0); return tBOOLEAN; } {real} { yylval.datum = pic_float_value(atof(yytext)); return tNUMBER; } {identifier} { yylval.datum = pic_intern_cstr(p->pic, yytext); return tSYMBOL; } +{string} { + yylval.datum = escape_string(p->pic, yytext); + return tSTRING; + } %% @@ -48,6 +59,26 @@ yywrap() return 1; } +static pic_value +escape_string(pic_state *pic, const char *str) +{ + size_t len; + char *new_str; + int i; + pic_value v; + + len = strlen(str); + new_str = (char *)pic_alloc(pic, len + 1); + for (i = 1; i < len - 1; ++i) { + new_str[i-1] = str[i]; + } + new_str[i] = '\0'; + + v = pic_str_new_cstr(pic, new_str); + pic_free(pic, new_str); + return v; +} + void init_scanner(const char *str) {