summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kdx@42l.fr>2023-01-22 03:04:39 +0100
committerkdx <kdx@42l.fr>2023-01-22 03:04:39 +0100
commit39015226859b990a24ec2f1db2928c51e0430ee0 (patch)
treed726513067cc8a7ed1ff03a8fbf4ad97490b1575
parent3503755c31a5ab6054d7d27fec9e178c5b6f2be0 (diff)
downloadgolem-39015226859b990a24ec2f1db2928c51e0430ee0.tar.gz
parse begins on fn
-rw-r--r--Makefile6
-rw-r--r--Token.c3
-rw-r--r--baby.golem11
-rw-r--r--main.c3
-rw-r--r--parse.c53
-rw-r--r--ultimate.golem (renamed from test.golem)25
6 files changed, 85 insertions, 16 deletions
diff --git a/Makefile b/Makefile
index 557b4cb..9c3b944 100644
--- a/Makefile
+++ b/Makefile
@@ -9,11 +9,11 @@ LDFLAGS :=
all: $(NAME)
$(NAME): $(OBJ)
- @printf '[ld] *.o -> %s\n' "$(NAME)"
+ @printf '[ld] %-10s -> %s\n' '*.o' "$(NAME)"
@$(LD) -o $(NAME) $(OBJ) $(LDFLAGS)
%.o: %.c
- @printf '[cc] %s -> %s\n' "$<" "$@"
+ @printf '[cc] %-10s -> %s\n' "$<" "$@"
@$(CC) $(CFLAGS) -c -o $@ $<
clean:
@@ -22,7 +22,7 @@ clean:
run: $(NAME)
@printf '[run]\n'
- @./$(NAME) test.golem
+ @./$(NAME) baby.golem
re:
@printf '[re]\n'
diff --git a/Token.c b/Token.c
index 7f7fc27..3d273a2 100644
--- a/Token.c
+++ b/Token.c
@@ -10,7 +10,8 @@ void token_free(Token *tok)
void token_print(const Token *tok)
{
- printf("%u:%u\t%s ", tok->line, tok->column, token_type_str(tok->type));
+ fprintf(stderr, "%u:%u\t%s ",
+ tok->line, tok->column, token_type_str(tok->type));
switch (tok->type) {
case TOK_WORD: printf("%s", tok->s); break;
case TOK_STRING: printf("\"%s\"", tok->s); break;
diff --git a/baby.golem b/baby.golem
new file mode 100644
index 0000000..c5a9368
--- /dev/null
+++ b/baby.golem
@@ -0,0 +1,11 @@
+// simple comment
+/* multi
+ line
+ comment */
+
+var stack;
+var heap = 0;
+
+// prototypes
+fn hello();
+fn alloc(size);
diff --git a/main.c b/main.c
index 3d2cd3a..8869d3b 100644
--- a/main.c
+++ b/main.c
@@ -28,7 +28,8 @@ int main(int argc, char **argv)
fprintf(stderr, "lexer failed\n");
return 1;
}
- parse(toks);
+ if (parse(toks))
+ fprintf(stderr, "parse failed\n");
lexer_free(toks);
return 0;
}
diff --git a/parse.c b/parse.c
index ba1644f..d562b57 100644
--- a/parse.c
+++ b/parse.c
@@ -1,7 +1,8 @@
#include "parse.h"
+#include "Token.h"
#include <stdio.h>
-static void unexpected(const Token *tok);
+static void *unexpected(const Token *tok, int n);
static const Token *keyword_fn(const Token *tok);
static const Token *keyword_var(const Token *tok);
static const Token *keyword_const(const Token *tok);
@@ -11,43 +12,73 @@ int parse(const Token *tok)
while (tok != NULL && tok->type != TOK_NONE) {
switch (tok->type) {
case TOK_KW_FN:
- tok = keyword_fn(tok + 1);
+ tok = keyword_fn(tok);
break;
case TOK_KW_VAR:
- tok = keyword_var(tok + 1);
+ tok = keyword_var(tok);
break;
case TOK_KW_CONST:
- tok = keyword_const(tok + 1);
+ tok = keyword_const(tok);
break;
default:
- unexpected(tok);
+ unexpected(tok, -1);
return 1;
}
+ if (tok == NULL)
+ return 1;
}
return 0;
}
-static void unexpected(const Token *tok)
+static void *unexpected(const Token *tok, int n)
{
- fprintf(stderr, "unexpected %s %s%s%sat %u:%u\n",
- token_type_str(tok->type),
+ fprintf(stderr, "[%d] unexpected %s %s%s%sat %u:%u\n",
+ n, token_type_str(tok->type),
(tok->s != NULL) ? "(" : "",
(tok->s != NULL) ? tok->s : "",
(tok->s != NULL) ? ") " : "",
tok->line, tok->column);
+ return NULL;
}
static const Token *keyword_fn(const Token *tok)
{
- return tok;
+ tok += 1;
+ if (tok->type != TOK_WORD)
+ return unexpected(tok, 0);
+ const Token *name = tok;
+ tok += 1;
+ (void)name;
+ if (tok->type != TOK_PAREN_OPEN)
+ return unexpected(tok, 1);
+ tok += 1;
+ size_t args = 0;
+ while (tok->type == TOK_WORD) {
+ tok += 1;
+ args += 1;
+ if (tok->type == TOK_COMMA)
+ tok += 1;
+ }
+ if (tok->type != TOK_PAREN_CLOS)
+ return unexpected(tok, 2);
+ printf("%zu args\n", args);
+ return tok + 1;
}
static const Token *keyword_var(const Token *tok)
{
- return tok;
+ tok += 1;
+ if (tok->type != TOK_WORD)
+ return unexpected(tok, 10);
+ const Token *name = tok;
+ (void)name;
+ tok += 1;
+ if (tok->type != TOK_SEMICOLON)
+ return unexpected(tok, 11);
+ return tok + 1;
}
static const Token *keyword_const(const Token *tok)
{
- return tok;
+ return tok + 1;
}
diff --git a/test.golem b/ultimate.golem
index 8bb015a..5cff4fb 100644
--- a/test.golem
+++ b/ultimate.golem
@@ -51,3 +51,28 @@ fn strlen(s) {
}
return len;
}
+
+ft strlen(s) {
+ return s[0];
+}
+
+fn isdigit(c) {
+ return c >= '0' && c <= '9';
+}
+
+ft atoi(s) {
+ var ret;
+ var i;
+
+ ret = 0;
+ i = 1;
+ while i <= s[0] {
+ if !isdigit(s[i]) {
+ return ret;
+ }
+ ret *= 10;
+ ret += s[i] - '0';
+ i += 1;
+ }
+ return ret;
+}