#include #include #include #include #include "lexer.h" #include "common.h" #include "error.h" #include "logic.h" #include "gate.h" static FILE* fd; static struct token *cursor; static const char *filename; /* FIXME change to varadic fuction */ #define emit(...) \ if (cursor) { \ fprintf(stderr, "%s at (%zd,%zd): ", filename, cursor->loc.line, cursor->loc.column); \ fprintf(stderr, __VA_ARGS__); \ indicate_file_area(fd, cursor->loc.line, cursor->loc.column - cursor->loc.leading_whitespace_len, cursor->span); \ } else { \ fprintf(stderr, "%s: ", filename); \ fprintf(stderr, __VA_ARGS__); \ } //static struct op_lookup uop_handlers[] = { // {.str = "not", .handler = logic_nand}, //}; // //static struct op_lookup bop_handlers[] = { // {.str = "and", .handler = logic_and}, // {.str = "or", .handler = logic_or}, // {.str = "nand", .handler = logic_nand}, // {.str = "nor", .handler = logic_nor}, // {.str = "xor", .handler = logic_xor} //}; // //static struct tok_lookup tok_handlers[] = { // {.str = "input", .handler = parse_input}, // {.str = "module", .handler = parse_module}, // {.str = "expr", .handler = parse_expr} //}; static int expect(enum TOKEN_TYPE e) { char *expected_desc = "(internal error)"; char *observed_desc = "(internal error)"; if (!cursor || cursor->type != e) { expected_desc = get_token_description(e); if (cursor) { observed_desc = get_token_description(cursor->type); } else { observed_desc = "end of file"; } emit("Error: Expected %s, got %s\n", expected_desc, observed_desc); return 1; } return 0; } static void kerchunk() { if (cursor) { cursor = cursor->next; } } int parse(const char *fname, FILE *f, struct token *t) { char *token_desc = "(internal error)"; fd = f; filename = fname; cursor = t; /* Eat leading EOL tokens */ while (cursor && cursor->type == TOK_EOL) { kerchunk(); } if (expect(TOK_MODULE)) { return 1; } kerchunk(); if (expect(TOK_IDENT)) { return 1; } emit("Debug: module is named %s\n", cursor->value); kerchunk(); if (expect(TOK_EOL)) { return 1; } kerchunk(); while (cursor) { switch(cursor->type) { case TOK_EOL: kerchunk(); break; /* FIXME implement everything */ default: token_desc = get_token_description(cursor->type); emit("Error: Unexpected %s\n", token_desc); return 1; } } return 0; }