#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_toplevel(Lexer *l) { switch (l->tok) { case TOK_PROC: parse_proc(l); break; default: lex_expected(l, TMASK(TOK_PROC)); break; } } void parse_unit(Lexer *l) { while (l->tok != TOK_EOF) { parse_toplevel(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; }