diff options
author | kdx <kikoodx@paranoici.org> | 2023-06-13 04:25:19 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2023-06-13 04:25:19 +0200 |
commit | dea6dce494e9c403f1f9e2178cd8c7d0aad79738 (patch) | |
tree | 41611f96256ec2525ec19513b796166faed6a3cd | |
parent | bef68b681f0af54061858a6689057850b390d79c (diff) | |
download | golem-dea6dce494e9c403f1f9e2178cd8c7d0aad79738.tar.gz |
escape sequences
-rw-r--r-- | samples/helloworld.golem | 3 | ||||
-rw-r--r-- | src/main.c | 56 | ||||
-rwxr-xr-x | testing.sh | 1 |
3 files changed, 44 insertions, 16 deletions
diff --git a/samples/helloworld.golem b/samples/helloworld.golem index 37698c0..57333b5 100644 --- a/samples/helloworld.golem +++ b/samples/helloworld.golem @@ -5,8 +5,7 @@ define iterations = 9; main() { local i; - strcpy(str, "Hello, World!"); - strappend(str, '\n'); + strcpy(str, "Hello, World!\n"); i = 0; loop { @@ -96,6 +96,33 @@ is_punct(const char *p) return (strchr("+-/*()<>,;{}[]=&^|", p[0]) != NULL); } +static int +escaped_char(char *s, char **skipped) +{ + if (*s == '\\') { + int rv = -1; + switch (s[1]) { + case 'a': rv = '\a'; break; + case 'b': rv = '\b'; break; + case 'f': rv = '\f'; break; + case 'n': rv = '\n'; break; + case 'r': rv = '\r'; break; + case 't': rv = '\t'; break; + case 'v': rv = '\v'; break; + case '\\':rv = '\\'; break; + case '\'':rv = '\''; break; + case '"': rv = '"'; break; + default: break; + } + if (rv >= 0) { + *skipped = s + 2; + return rv; + } + } + *skipped = s + 1; + return *s; +} + static Token * tokenize(char *p) { @@ -139,17 +166,14 @@ tokenize(char *p) continue; } - if (*p == '\'' && p[1] != '\0' && p[2] == '\'') { - cur = cur->next = new_token(TOK_NUM, p, p + 3); - cur->val = (unsigned char)p[1]; - p += 3; - continue; - } - - if (strncmp(p, "'\\n'", 4) == 0) { - cur = cur->next = new_token(TOK_NUM, p, p + 4); - cur->val = '\n'; - p += 4; + if (*p == '\'' && p[1] != '\'') { + char *q = p; + const int c = escaped_char(p + 1, &p); + if (*p != '\'') + error("unclosed single quotes", 0); + p += 1; + cur = cur->next = new_token(TOK_NUM, q, p); + cur->val = (unsigned char)c; continue; } @@ -1141,8 +1165,14 @@ codegen(Node *node) for (int i = 0; i < strings_size; i++) { printf("@__str_%x\n", strings_size - i - 1); - for (int k = 1; k < strings->lhs->len - 1; k++) - printf("\t%04x\n", (unsigned)strings->lhs->loc[k]); + for (int k = 1; k < strings->lhs->len - 1;) { + char *q = strings->lhs->loc + k; + const int c = escaped_char(q, &q); + if (c == '"') /* TODO: handle this */ + error("can't escape double quotes", 0); + printf("\t%04x\n", (unsigned)c); + k = q - strings->lhs->loc; + } printf("\t0000\n"); strings = strings->next; } @@ -55,5 +55,4 @@ test "$1" "main() return;" test "$1" "main() { local a; a = 5; dbg a; a++; dbg a; }" test "$1" "main() { local a; a = 5; dbg a; a--; dbg a; }" test "$1" "main() { wrt [\"(\"]; wrt '\n'; }" -exit rm -f build/tmp.* |