From c26a76a39a93656b547886acbc96147fe779cffc Mon Sep 17 00:00:00 2001 From: kdx Date: Mon, 12 Jun 2023 13:05:55 +0200 Subject: =?UTF-8?q?=F0=9F=97=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/helloworld.golem | 13 +++++----- samples/malloc.golem | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 38 +++++++++++++++++----------- testing.sh | 1 + 4 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 samples/malloc.golem diff --git a/samples/helloworld.golem b/samples/helloworld.golem index 473331f..2e0d82c 100644 --- a/samples/helloworld.golem +++ b/samples/helloworld.golem @@ -19,14 +19,13 @@ main() { } strcpy(dst, src) { - local rv; - rv = dst; + local i; + i = 0; loop { - [dst] = [src]; - src = src + 1; - if ([src] == 0) - return rv; - dst = dst + 1; + [dst + i] = [src + i]; + i = i + 1; + if ([src + i] == 0) + return dst; } } diff --git a/samples/malloc.golem b/samples/malloc.golem new file mode 100644 index 0000000..762f78f --- /dev/null +++ b/samples/malloc.golem @@ -0,0 +1,65 @@ +main() { + local s; + s = strdup("coucou le monde"); + puts(s); + stoupper(s); + puts(s); +} + +puts(s) { + loop { + if ([s] == 0) { + wrt '\n'; + return 0; + } + wrt [s]; + s = s + 1; + } +} + +strlen(s) { + local len; + len = 0; + loop { + if ([s + len] == 0) { + return len; + } + len = len + 1; + } +} + +strdup(s) { + return strcpy(malloc(strlen(s) + 1), s); +} + +strcpy(dst, src) { + local i; + i = 0; + loop { + [dst + i] = [src + i]; + i = i + 1; + if ([src + i] == 0) + return dst; + } +} + +stoupper(s) { + loop { + if ([s] == 0) return 0; + [s] = [s] - ([s] >= 'a' & [s] <= 'z') * 32; + s = s + 1; + } +} + +global heap[4096] = 0x69; +global heap_size = 0; +malloc(n) { + local p; + p = heap + heap_size; + heap_size = heap_size + n; + if (heap_size > 4096) { + puts("malloc error: heap is full"); + return 0; + } + return p; +} diff --git a/src/main.c b/src/main.c index 4c8ace0..9951685 100644 --- a/src/main.c +++ b/src/main.c @@ -32,8 +32,8 @@ struct Token { }; static void -error(const char *fmt, ...) { - fprintf(stderr, "error: "); +_error(const char *fmt, ...) { + fprintf(stderr, "error:"); va_list va; va_start(va, fmt); vfprintf(stderr, fmt, va); @@ -42,6 +42,8 @@ error(const char *fmt, ...) { exit(1); } +#define error(fmt, ...) _error("%d: " fmt, __LINE__, __VA_ARGS__); + static void expect(const Token *tok, TokenType type) { @@ -76,7 +78,7 @@ new_token(TokenType type, char *start, char *end) { Token *tok = calloc(1, sizeof(Token)); if (tok == NULL) - error("calloc failed"); + error("calloc failed", 0); tok->type = type; tok->loc = start; tok->len = end - start; @@ -99,6 +101,12 @@ tokenize(char *p) Token *cur = &head; while (*p != '\0') { + if (*p == '/' && p[1] == '/') { + while (*p != '\0' && *p != '\n') + p++; + continue; + } + if (isspace(*p)) { p++; continue; @@ -115,7 +123,7 @@ tokenize(char *p) if (*p == '"') { char *end = strchr(p + 1, '"'); if (end == NULL) - error("unclosed double quotes"); + error("unclosed double quotes", 0); cur = cur->next = new_token(TOK_STRING, p + 1, end); p = end + 1; continue; @@ -256,7 +264,7 @@ new_node(NodeType type) { Node *const node = calloc(1, sizeof(Node)); if (node == NULL) - error("calloc failed"); + error("calloc failed", 0); node->type = type; return node; } @@ -595,8 +603,10 @@ primary(Token **rest, Token *tok) return node; } - printf("'%.*s'\n", tok->len, tok->loc); - error("expected an expression"); + fprintf(stderr, "'%.*s'\n", tok->len, tok->loc); + if (tok->next != NULL) + fprintf(stderr, "'%.*s'\n", tok->next->len, tok->next->loc); + error("expected an expression", 0); return NULL; } @@ -628,7 +638,7 @@ stmt(Token **rest, Token *tok) cur = cur->next; } if (cur->type == TOK_EOF) - error("unexpected EOF"); + error("unexpected EOF", 0); if (equal(cur, "=")) return assign_stmt(rest, tok); } @@ -947,7 +957,7 @@ gen_stmt(Node *node, Node *fname, int break_lbl) break; case NOD_BREAK_STMT: if (break_lbl == -1) - error("break statement outside of loop"); + error("break statement outside of loop", 0); printf("\tJMP ,__lbl_%x\n", break_lbl); break; case NOD_SLP_STMT: @@ -1104,15 +1114,15 @@ static char * drain(FILE *fp) { if (fseek(fp, 0, SEEK_END) < 0) - error("fseek failed"); + error("fseek failed", 0); const size_t size = ftell(fp); if (fseek(fp, 0, SEEK_SET) < 0) - error("fseek failed"); + error("fseek failed", 0); char *data = malloc(size + 1); if (data == NULL) - error("malloc failed"); + error("malloc failed", 0); if (fread(data, 1, size, fp) != size) - error("fread failed"); + error("fread failed", 0); data[size] = '\0'; return data; } @@ -1125,7 +1135,7 @@ main(int argc, char **argv) FILE *const fp = fopen(argv[1], "rb"); if (fp == NULL) - error("fopen failed"); + error("fopen failed", 0); Token *const tok = tokenize(drain(fp)); fclose(fp); diff --git a/testing.sh b/testing.sh index 532d054..142103b 100755 --- a/testing.sh +++ b/testing.sh @@ -50,4 +50,5 @@ test "$1" "main() { wrt('0' + (7 >= 7)); wrt '\n'; }" test "$1" "main() { wrt('0' + (9 >= 7)); wrt '\n'; }" test "$1" "main() { local a; dbg a; inc(&a); dbg a; } inc(p) { [p] = [p] + 1; }" test "$1" "global a; main() { dbg a; inc(&a); dbg a; } inc(p) { [p] = [p] + 1; }" +test "$1" "main() 0; //ayayayayayayaya comment" rm -f build/tmp.* -- cgit v1.2.3