summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
authorDavid Phillips <david@sighup.nz>2018-08-01 23:25:46 +1200
committerDavid Phillips <david@sighup.nz>2018-08-01 23:25:46 +1200
commiteee61ddbba165f772a0e720825dcf6810eaa2648 (patch)
treec9b238e386dfcf19f0c3244998efa8d2dc6d0a82 /parse.c
parente22abc4eaf4f1446c6ac31e4b709cb5206d4fe3b (diff)
downloadhence-eee61ddbba165f772a0e720825dcf6810eaa2648.tar.xz
Rename lexer and parser, fix compilation warnings
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/parse.c b/parse.c
new file mode 100644
index 0000000..668a700
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,155 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lex.h"
+#include "common.h"
+#include "error.h"
+#include "logic.h"
+#include "gate.h"
+
+
+static FILE* fd;
+static struct token *cursor;
+static const char *filename;
+
+#define EXPECT_AND_DISCARD_CRITICAL(type)\
+ do { \
+ EXPECT_CRITICAL(type) \
+ kerchunk(); \
+ } while (0);
+
+#define EXPECT_CRITICAL(type)\
+ do { \
+ if (expect(type)) { \
+ return 1; \
+ } \
+ } while (0);
+
+/* 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) {
+ const char *expected_desc = "(internal error)";
+ const 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_expr(void) {
+ /* FIXME write wrapper to exit on fail */
+ EXPECT_AND_DISCARD_CRITICAL(TOK_EXPR);
+ EXPECT_AND_DISCARD_CRITICAL(TOK_IDENT); /* FIXME do something, don't discard */
+ EXPECT_AND_DISCARD_CRITICAL(TOK_COLON);
+
+ switch(cursor->type) {
+ /* FIXME do some things */
+ case TOK_OR : /* fallthrough */
+ case TOK_AND: /* fallthrough */
+ case TOK_XOR:
+ kerchunk();
+ EXPECT_AND_DISCARD_CRITICAL(TOK_IDENT); /* FIXME don't discard */
+ EXPECT_AND_DISCARD_CRITICAL(TOK_IDENT); /* FIXME don't discard */
+ break;
+ case TOK_NOT:
+ kerchunk();
+ EXPECT_AND_DISCARD_CRITICAL(TOK_IDENT); /* FIXME don't discard */
+ break;
+ default:
+ emit("Error: Unexpected %s\n", get_token_description(cursor->type));
+ return 1;
+ }
+ return 0;
+}
+
+
+int
+parse(const char *fname, FILE *f, struct token *t) {
+ fd = f;
+ filename = fname;
+ cursor = t;
+
+ /* Eat leading EOL tokens */
+ while (cursor && cursor->type == TOK_EOL) {
+ kerchunk();
+ }
+
+ EXPECT_AND_DISCARD_CRITICAL(TOK_MODULE);
+
+ EXPECT_CRITICAL(TOK_IDENT);
+ emit("Debug: module is named %s\n", cursor->value);
+ /* FIXME do something */
+ kerchunk();
+
+ EXPECT_AND_DISCARD_CRITICAL(TOK_EOL);
+
+ while (cursor) {
+ switch(cursor->type) {
+ case TOK_EOL:
+ kerchunk();
+ break;
+ case TOK_INPUT:
+ kerchunk();
+ expect(TOK_IDENT);
+ emit("Debug: input is named %s\n", cursor->value);
+ /* FIXME do something */
+ kerchunk();
+ break;
+ case TOK_EXPR:
+ parse_expr();
+ break;
+ default:
+ emit("Error: Unexpected %s\n", get_token_description(cursor->type));
+ return 1;
+ }
+ }
+ return 0;
+}