summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-06-12 13:05:55 +0200
committerkdx <kikoodx@paranoici.org>2023-06-12 13:05:55 +0200
commitc26a76a39a93656b547886acbc96147fe779cffc (patch)
tree557b48546ad02a4705cf1c035be8cf8c384c2bab
parentacb633cc836a3068b597c89d4f160c5ab6e22fa7 (diff)
downloadgolem-c26a76a39a93656b547886acbc96147fe779cffc.tar.gz
🗿
-rw-r--r--samples/helloworld.golem13
-rw-r--r--samples/malloc.golem65
-rw-r--r--src/main.c38
-rwxr-xr-xtesting.sh1
4 files changed, 96 insertions, 21 deletions
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.*