Support literal Text("blah") for text that is constant ASCII strings
This commit is contained in:
parent
de7b564a91
commit
29a87ff325
@ -14,6 +14,8 @@
|
||||
int printf_text(FILE *stream, const struct printf_info *info, const void *const args[]);
|
||||
int printf_text_size(const struct printf_info *info, size_t n, int argtypes[n], int sizes[n]);
|
||||
|
||||
#define Text(str) ((Text_t){.length=sizeof(str)-1, .tag=TEXT_ASCII, .ascii="" str})
|
||||
|
||||
int Text$print(FILE *stream, Text_t t);
|
||||
void Text$visualize(Text_t t);
|
||||
Text_t Text$_concat(int n, Text_t items[n]);
|
||||
|
15
compile.c
15
compile.c
@ -1786,9 +1786,16 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
case TextLiteral: {
|
||||
CORD literal = Match(ast, TextLiteral)->cord;
|
||||
if (literal == CORD_EMPTY)
|
||||
return "((Text_t){.length=0})";
|
||||
CORD code = "Text$from_str(\"";
|
||||
return "Text(\"\")";
|
||||
bool all_ascii = true;
|
||||
CORD_pos i;
|
||||
CORD_FOR(i, literal) {
|
||||
if (!isascii(CORD_pos_fetch(i))) {
|
||||
all_ascii = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CORD code = all_ascii ? "Text(\"" : "Text$from_str(\"";
|
||||
CORD_FOR(i, literal) {
|
||||
char c = CORD_pos_fetch(i);
|
||||
switch (c) {
|
||||
@ -1804,7 +1811,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
if (isprint(c))
|
||||
code = CORD_cat_char(code, c);
|
||||
else
|
||||
CORD_sprintf(&code, "%r\"\"\\x%02X\"\"", code, (uint8_t)c);
|
||||
CORD_sprintf(&code, "%r\\x%02X\"\"", code, (uint8_t)c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1818,7 +1825,7 @@ CORD compile(env_t *env, ast_t *ast)
|
||||
code_err(ast, "%s is not a valid text language name", lang);
|
||||
ast_list_t *chunks = Match(ast, TextJoin)->children;
|
||||
if (!chunks) {
|
||||
return "((Text_t){.length=0})";
|
||||
return "Text(\"\")";
|
||||
} else if (!chunks->next && chunks->ast->tag == TextLiteral) {
|
||||
return compile(env, chunks->ast);
|
||||
} else {
|
||||
|
12
typecheck.c
12
typecheck.c
@ -1377,8 +1377,16 @@ bool is_constant(env_t *env, ast_t *ast)
|
||||
}
|
||||
case TextJoin: {
|
||||
auto text = Match(ast, TextJoin);
|
||||
// TODO: support short literal strings
|
||||
return !text->children;
|
||||
if (!text->children) return true; // Empty string, OK
|
||||
if (text->children->next) return false; // Concatenation, not constant
|
||||
|
||||
CORD literal = Match(text->children->ast, TextLiteral)->cord;
|
||||
CORD_pos i;
|
||||
CORD_FOR(i, literal) {
|
||||
if (!isascii(CORD_pos_fetch(i)))
|
||||
return false; // Non-ASCII requires grapheme logic, not constant
|
||||
}
|
||||
return true; // Literal ASCII string, OK
|
||||
}
|
||||
case Not: return is_constant(env, Match(ast, Not)->value);
|
||||
case Negative: return is_constant(env, Match(ast, Negative)->value);
|
||||
|
Loading…
Reference in New Issue
Block a user