From b3e5203f6260cb400d7c73b56f91eddea6b24502 Mon Sep 17 00:00:00 2001 From: kdx Date: Sat, 10 Jun 2023 19:06:23 +0200 Subject: string literal --- samples/helloworld.golem | 15 ++++++++++ src/main.c | 75 ++++++++++++++++++++++++++++++++++++++---------- testing.sh | 1 + 3 files changed, 76 insertions(+), 15 deletions(-) diff --git a/samples/helloworld.golem b/samples/helloworld.golem index d1758ac..aac5202 100644 --- a/samples/helloworld.golem +++ b/samples/helloworld.golem @@ -3,6 +3,9 @@ global str[32]; main() { local i; + print("uwu"); + wrt '\n'; + strappend(str, 'H'); strappend(str, 'e'); strappend(str, 'L'); @@ -27,6 +30,18 @@ main() { } } +strcpy(dst, src) { + local rv; + rv = dst; + loop { + [dst] = [src]; + src = src + 1; + if ([src] == 0) + return rv; + dst = dst + 1; + } +} + strappend(s, c) { loop { if ([s] == 0) { diff --git a/src/main.c b/src/main.c index ecb539a..cbddd10 100644 --- a/src/main.c +++ b/src/main.c @@ -10,6 +10,7 @@ typedef enum { TOK_PUNCT, TOK_NUM, TOK_WORD, + TOK_STRING, TOK_EOF, } TokenType; @@ -17,6 +18,7 @@ static const char * str_tok[] = { [TOK_PUNCT] = "TOK_PUNCT", [TOK_NUM] = "TOK_NUM", [TOK_WORD] = "TOK_WORD", + [TOK_STRING] = "TOK_STRING", [TOK_EOF] = "TOK_EOF", }; @@ -109,6 +111,15 @@ tokenize(char *p) cur->val = val; continue; } + + if (*p == '"') { + char *end = strchr(p + 1, '"'); + if (end == NULL) + error("unclosed double quotes"); + cur = cur->next = new_token(TOK_STRING, p + 1, end); + p = end + 1; + continue; + } if (*p == '\'' && p[1] != '\0' && p[2] == '\'') { cur = cur->next = new_token(TOK_NUM, p, p + 3); @@ -159,6 +170,7 @@ typedef enum { NOD_OR, // | NOD_XOR, // ^ NOD_NUM, // integer + NOD_STRING, // "" NOD_DEREF, // [a] NOD_BLOCK_STMT, NOD_EXPR_STMT, @@ -291,6 +303,8 @@ static Node *primary(Token **rest, Token *tok); static Node *locals; static int locals_size; +static Node *strings; +static int strings_size; static Node * function(Token **rest, Token *tok) @@ -503,6 +517,14 @@ primary(Token **rest, Token *tok) return node; } + if (tok->type == TOK_STRING) { + Node *node = new_node(NOD_STRING); + node->loc = tok->loc; + node->len = tok->len; + *rest = tok->next; + return node; + } + if (tok->type == TOK_WORD && equal(tok->next, "(")) { /* function call */ Node *node = new_word(tok); @@ -676,29 +698,30 @@ static void gen_globaldec(Node *node); static void gen_fncall(Node *node); static void gen_variableget(Node *node); static void gen_deref(Node *node); +static void gen_string(Node *node); static void gen_expr(Node *node) { - if (node->type == NOD_NUM) { + switch (node->type) { + case NOD_NUM: printf("\tLIT %04x\n", node->val); depth += 1; return; - } - - if (node->type == NOD_FNCALL) { + case NOD_FNCALL: gen_fncall(node); return; - } - - if (node->type == NOD_WORD) { + case NOD_WORD: gen_variableget(node); return; - } - - if (node->type == NOD_DEREF) { + case NOD_DEREF: gen_deref(node); return; + case NOD_STRING: + gen_string(node); + return; + default: + break; } gen_expr(node->lhs); @@ -776,6 +799,18 @@ gen_deref(Node *node) printf("\tLDA\n"); } +static void +gen_string(Node *node) +{ + Node *store = new_node(0); + store->lhs = node; + store->next = strings; + strings = store; + strings_size += 1; + printf("\tLIT ,__str_%x\n", strings_size - 1); + depth += 1; +} + static void gen_assign_stmt(Node *node) { @@ -925,6 +960,9 @@ gen_function(Node *node) static void codegen(Node *node) { + printf("\tJRT ,__fn_main\n"); + printf("\tRET\n"); + while (node != NULL) { if (node->type == NOD_GLOBAL) gen_globaldec(node); @@ -932,6 +970,18 @@ codegen(Node *node) gen_function(node); node = node->next; } + + for (int i = 0; i < strings_size; i++) { + printf("@__str_%x\n", strings_size - i - 1); + for (int k = 0; k < strings->lhs->len; k++) + printf("\t%04x\n", (unsigned)strings->lhs->loc[k]); + printf("\t0000\n"); + strings = strings->next; + } + + printf("@__stack_ptr\n"); + printf("\t,__stack\n"); + printf("@__stack\n"); } // program = stmt* @@ -982,12 +1032,7 @@ main(int argc, char **argv) Node *node = parse(tok); - printf("\tJRT ,__fn_main\n"); - printf("\tRET\n"); codegen(node); - printf("@__stack_ptr\n"); - printf("\t,__stack\n"); - printf("@__stack\n"); assert(depth == 0); return 0; diff --git a/testing.sh b/testing.sh index e1889da..a7bd81b 100755 --- a/testing.sh +++ b/testing.sh @@ -35,4 +35,5 @@ test "$1" "global a[5] = 4; main() { wrt([a + 4] + '0'); wrt '\n'; }" test "$1" "global a[5] = 4; main() { wrt([a + 5] + '0'); wrt '\n'; }" test "$1" "global a[3]; main() { [a] = 'U'; [a+1] = 'w'; [a+2] = '\n'; wrt[a]; wrt[a+1]; wrt[a]; wrt[a+2]; }" test "$1" "main() { wrt('0' + div(6, 3)); wrt('\n'); } div(a, b) { return a / b; }" +test "$1" "main() { \"uwu\"; \"owo\"; }" rm -f build/tmp.* -- cgit v1.2.3