From 39015226859b990a24ec2f1db2928c51e0430ee0 Mon Sep 17 00:00:00 2001 From: kdx Date: Sun, 22 Jan 2023 03:04:39 +0100 Subject: parse begins on fn --- Makefile | 6 ++--- Token.c | 3 ++- baby.golem | 11 +++++++++ main.c | 3 ++- parse.c | 53 ++++++++++++++++++++++++++++++--------- test.golem | 53 --------------------------------------- ultimate.golem | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 138 insertions(+), 69 deletions(-) create mode 100644 baby.golem delete mode 100644 test.golem create mode 100644 ultimate.golem 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 -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/test.golem deleted file mode 100644 index 8bb015a..0000000 --- a/test.golem +++ /dev/null @@ -1,53 +0,0 @@ -fn strlen(s); - -// typeless language -// (i know, this stupid but me bad) - -const usage_str = "usage: %s \n"; - -fn main(argc, argv) { - var i; - var fp, data; - var toks; - - if argc != 2 { - fprintf(stderr, usage_str, argv[0]); - return 1; - } - i = 0; - while i < argc { - puts(argv[i]); - } - fp = fopen(argv[1], "rb"); - if fp == null { - perror("main"); - return 1; - } - data = drain(fp); - fclose(fp); - if data == 0 { - fprintf(stderr, "failed to drain '%s'\n", argv[1]); - return 1; - } - toks = lexer(data); - free(data); - if toks == 0 { - fprintf(stderr, "lexer failed\n"); - return 1; - } - lexer_print(toks); - lexer_free(toks); - return 0; -} - -fn strlen(s) { - var i, len; - - i = 0; - while s[i] { - len = len + ((s[i] & 0xFF) != 0); - len = len + ((s[i] & 0xFF00) != 0); - i += 1; - } - return len; -} diff --git a/ultimate.golem b/ultimate.golem new file mode 100644 index 0000000..5cff4fb --- /dev/null +++ b/ultimate.golem @@ -0,0 +1,78 @@ +fn strlen(s); + +// typeless language +// (i know, this stupid but me bad) + +const usage_str = "usage: %s \n"; + +fn main(argc, argv) { + var i; + var fp, data; + var toks; + + if argc != 2 { + fprintf(stderr, usage_str, argv[0]); + return 1; + } + i = 0; + while i < argc { + puts(argv[i]); + } + fp = fopen(argv[1], "rb"); + if fp == null { + perror("main"); + return 1; + } + data = drain(fp); + fclose(fp); + if data == 0 { + fprintf(stderr, "failed to drain '%s'\n", argv[1]); + return 1; + } + toks = lexer(data); + free(data); + if toks == 0 { + fprintf(stderr, "lexer failed\n"); + return 1; + } + lexer_print(toks); + lexer_free(toks); + return 0; +} + +fn strlen(s) { + var i, len; + + i = 0; + while s[i] { + len = len + ((s[i] & 0xFF) != 0); + len = len + ((s[i] & 0xFF00) != 0); + i += 1; + } + 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; +} -- cgit v1.2.3