From 842e22e9eb0f3dff7dabdaa41bcc2133e8f015f5 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Thu, 31 Jul 2025 22:37:38 -0400 Subject: initial commit --- main.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 main.c (limited to 'main.c') diff --git a/main.c b/main.c new file mode 100644 index 0000000..59a41a2 --- /dev/null +++ b/main.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include + +#include "lex.h" + +/* node graph */ + +typedef enum { + N_START, + N_STOP, + N_LIT_INT, + N_OP_ADD, + N_OP_SUB, + N_OP_MUL, + N_OP_DIV, + N_OP_NEG, +} NodeType; + +typedef struct Node { + NodeType type; + struct Node **inputs, **outputs; +} Node; + +typedef struct { + Node *start, *stop; +} ProcGraph; + +/* parsing */ + +void parse_expr(Lexer *l); + +void parse_stmt_let(Lexer *l) { + lex_expect(l, TMASK(TOK_IDENT)); + Str name = l->ident; + lex_expect(l, TMASK(TOK_EQUALS) | TMASK(TOK_COLON)); + lex_next(l); + parse_expr(l); + printf("name_bind %.*s\n", (int)name.n, name.s); +} + +void parse_stmt(Lexer *l) { + /* TODO */ + (void)l; + switch (l->tok) { + case TOK_LET: + parse_stmt_let(l); + break; + case TOK_RETURN: + lex_next(l); + parse_expr(l); + puts("return"); + break; + default: + lex_expected(l, TMASK(TOK_RBRACE)); + } +} + +void parse_proc(Lexer *l) { + lex_expect(l, TMASK(TOK_IDENT)); + lex_expect(l, TMASK(TOK_LBRACE)); + lex_next(l); + while (l->tok != TOK_RBRACE) { + lex_expected_not(l, TMASK(TOK_EOF)); + parse_stmt(l); + } + lex_expected(l, TMASK(TOK_RBRACE)); + lex_next(l); +} + +void parse_term(Lexer *l) { + int negate_after = l->tok == TOK_MINUS; + if (TMASK(l->tok) & (TMASK(TOK_MINUS) | TMASK(TOK_PLUS))) { + lex_next(l); + } + if (l->tok == TOK_LPAREN) { + lex_next(l); + parse_expr(l); + lex_expected(l, TMASK(TOK_RPAREN)); + lex_next(l); + } else { + lex_expected(l, TMASK(TOK_LIT_NUM) | TMASK(TOK_LIT_STR) | TMASK(TOK_LIT_CHAR) | TMASK(TOK_IDENT)); + switch (l->tok) { + case TOK_IDENT: + printf("var %.*s\n", (int)l->ident.n, l->ident.s); + break; + case TOK_LIT_STR: + printf("lit_str %.*s\n", (int)l->ident.n, l->ident.s); + break; + case TOK_LIT_CHAR: + printf("lit_char %.*s\n", (int)l->ident.n, l->ident.s); + break; + case TOK_LIT_NUM: + printf("lit_num %.*s\n", (int)l->ident.n, l->ident.s); + break; + default: + break; + } + lex_next(l); + } + if (negate_after) puts("negate"); +} + +void parse_expr(Lexer *l) { + parse_term(l); + if (l->tok == TOK_LPAREN) { + lex_next(l); + puts("args_start"); + for (;;) { + parse_expr(l); + lex_expected(l, TMASK(TOK_COMMA) | TMASK(TOK_RPAREN)); + if (l->tok == TOK_RPAREN) break; + lex_next(l); + } + lex_next(l); + puts("args_end"); + puts("func_call"); + } + if (TMASK(l->tok) & (TMASK(TOK_PLUS) | TMASK(TOK_MINUS) | TMASK(TOK_ASTERISK) | TMASK(TOK_SLASH))) { + Token t = l->tok; + lex_next(l); + parse_expr(l); + switch (t) { + case TOK_PLUS: puts("add"); break; + case TOK_MINUS: puts("subtract"); break; + case TOK_ASTERISK: puts("multiply"); break; + case TOK_SLASH: puts("divide"); break; + default: break; + } + } +} + +void parse_decl(Lexer *l) { + switch (l->tok) { + case TOK_PROC: + parse_proc(l); + break; + default: + lex_error(l, LE_ERROR, S("Invalid declaration statement")); + } +} + +void parse_unit(Lexer *l) { + while (l->tok != TOK_EOF) { + parse_decl(l); + } +} + +int main(int argc, const char **argv) { + if (argc != 2) { + fprintf(stderr, "Usage: %s FILE\n", argv[0]); + return 1; + } + Lexer l = { 0 }; + lex_start(&l, argv[1]); + parse_unit(&l); + lex_free(&l); + return 0; +} -- cgit v1.2.3