aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-02-10 15:33:35 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-02-10 15:33:35 -0500
commit2c9ee0c629834bea159f033db2d9a42a4f8110a2 (patch)
treeea5cc103996a64b7c34355a7b138b8fa28ac1b50
parent4e545c67985299dabc2a061160e126068d43541e (diff)
String improvements
-rw-r--r--compile.c28
-rw-r--r--nextlang.h4
-rw-r--r--parse.c1
3 files changed, 25 insertions, 8 deletions
diff --git a/compile.c b/compile.c
index 97a7d21c..36e78832 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 2e55b1cf..2718ef6d 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 75a0d1e2..d7d8ff74 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;
}