summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-06-10 19:06:23 +0200
committerkdx <kikoodx@paranoici.org>2023-06-10 19:06:23 +0200
commitb3e5203f6260cb400d7c73b56f91eddea6b24502 (patch)
tree74340c09ded42716147444de38eb7f1a43e6b310
parenta4a117871b56e72fc1638c6561d2d3670de929dc (diff)
downloadgolem-b3e5203f6260cb400d7c73b56f91eddea6b24502.tar.gz
string literal
-rw-r--r--samples/helloworld.golem15
-rw-r--r--src/main.c75
-rwxr-xr-xtesting.sh1
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);
@@ -777,6 +800,18 @@ gen_deref(Node *node)
}
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)
{
gen_expr(node->rhs);
@@ -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.*