diff --git a/compile.c b/compile.c index 97a7d21..36e7883 100644 --- a/compile.c +++ b/compile.c @@ -35,7 +35,7 @@ CORD compile(ast_t *ast) case Var: return Match(ast, Var)->name; case Int: return CORD_asprintf("((Int%ld_t)%ld)", Match(ast, Int)->precision, Match(ast, Int)->i); case Num: return CORD_asprintf(Match(ast, Num)->precision == 64 ? "%g" : "%gf", Match(ast, Num)->n); - case Char: return CORD_asprintf("'\\x%02X'", (int)Match(ast, Char)->c); + case Char: return CORD_asprintf("(char)'\\x%02X'", (int)Match(ast, Char)->c); case UnaryOp: { auto unop = Match(ast, UnaryOp); CORD expr = compile(unop->value); @@ -123,12 +123,28 @@ CORD compile(ast_t *ast) return CORD_cat_char(code, '"'); } case StringJoin: { - CORD code = NULL; - for (ast_list_t *chunk = Match(ast, StringJoin)->children; chunk; chunk = chunk->next) { - if (code) CORD_sprintf(&code, "CORD_cat(%r, %r)", code, compile(chunk->ast)); - else code = compile(chunk->ast); + ast_list_t *chunks = Match(ast, StringJoin)->children; + if (!chunks) { + return "\"\""; + } else if (!chunks->next) { + CORD code = compile(chunks->ast); + if (chunks->ast->tag != StringLiteral) + code = CORD_asprintf("__cord(%r)", code); + return code; + } else { + int64_t num_chunks = 0; + for (ast_list_t *chunk = chunks; chunk; chunk = chunk->next) + ++num_chunks; + + CORD code = CORD_asprintf("CORD_catn(%ld", num_chunks); + for (ast_list_t *chunk = chunks; chunk; chunk = chunk->next) { + CORD chunk_code = compile(chunk->ast); + if (chunk->ast->tag != StringLiteral) + chunk_code = CORD_asprintf("__cord(%r)", chunk_code); + CORD_sprintf(&code, "%r, %r", code, chunk_code); + } + return CORD_cat_char(code, ')'); } - return code; } case Block: { ast_list_t *stmts = Match(ast, Block)->statements; diff --git a/nextlang.h b/nextlang.h index 2e55b1c..2718ef6 100644 --- a/nextlang.h +++ b/nextlang.h @@ -31,11 +31,13 @@ #define CORD_asprintf(...) ({ CORD __c; CORD_sprintf(&__c, __VA_ARGS__); __c; }) #define __declare(var, val) __typeof(val) var = val #define __cord(x) _Generic(x, bool: x ? "yes" : "no", \ - int8_t: CORD_asprintf("%d", x), int16_t: CORD_asprintf("%d", x), \ + int8_t: CORD_asprintf("%d", x), \ + int16_t: CORD_asprintf("%d", x), \ int32_t: CORD_asprintf("%d", x), int64_t: CORD_asprintf("%ld", x), \ double: CORD_asprintf("%g", x), float: CORD_asprintf("%g", x), \ CORD: x, \ char*: x, \ + char: CORD_cat_char(NULL, x), \ default: "???") #define __heap(x) (__typeof(x)*)memcpy(GC_MALLOC(sizeof(x)), (__typeof(x)[1]){x}, sizeof(x)) #define __stack(x) (&(__typeof(x)){x}) diff --git a/parse.c b/parse.c index 75a0d1e..d7d8ff7 100644 --- a/parse.c +++ b/parse.c @@ -922,7 +922,6 @@ PARSER(parse_string) { ++pos; spaces(&pos); for (ast_t *interp; (interp=optional(ctx, &pos, parse_expr)); spaces(&pos)) { - interp = WrapAST(interp, FunctionCall, .fn=WrapAST(interp, Var, .name="__cord"), .args=new(ast_list_t, .ast=interp)); chunks = new(ast_list_t, .ast=interp, .next=chunks); chunk_start = pos; }