diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 161 |
1 files changed, 161 insertions, 0 deletions
@@ -0,0 +1,161 @@ +#include <stdio.h> +#include <stdint.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#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; +} |
