diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | Token.c | 3 | ||||
-rw-r--r-- | baby.golem | 11 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | parse.c | 53 | ||||
-rw-r--r-- | ultimate.golem (renamed from test.golem) | 25 |
6 files changed, 85 insertions, 16 deletions
@@ -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' @@ -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); @@ -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; } @@ -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; +} |