#include #include #include #include "common.h" #include "error.h" #include "logic.h" #include "wire.h" enum STATEMENT_TYPE { DECL_EXPR, DECL_INPUT, DECL_OUTPUT, MODULE_NAME }; enum UNARY_OPERATOR { UOP_NOT }; enum BINARY_OPERATOR { BOP_AND, BOR_OR, BOP_NAND, BOP_NOR, BOP_XOR }; struct tok_lookup { char *str; int (*handler)(char*); }; struct bop_lookup { char *str; enum BINARY (*handler)(enum BINARY, enum BINARY); }; struct uop_lookup { char *str; enum BINARY (*handler)(enum BINARY); }; static struct uop_lookup uop_handlers[] = { {.str = "not", .handler = logic_not}, }; static struct bop_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} }; int expect(const char *expect, char *actual) { int min_len = 0; min_len = MIN(strlen(expect), strlen(actual)); if (strncmp(expect, actual, min_len) != 0) { emit_error("Expected '%s' at start of '%s'\n", expect, actual); return 1; } return 0; } int parse_uop(char *str, enum BINARY (*handler)(enum BINARY)) { /**/ (void)str; (void)handler; emit_error("uop unimplemented\n"); return 0; } int parse_bop(char *str, enum BINARY (*handler)(enum BINARY, enum BINARY)) { /**/ (void)str; (void)handler; emit_error("bop unimplemented\n"); return 0; } int parse_op(char *str) { int match = 0; size_t i = 0; strtok(str, " "); match = 0; for (i = 0; i < sizeof(bop_handlers)/sizeof(bop_handlers[0]); i++) { if (strcmp(bop_handlers[i].str, str) == 0) { match = 1; if (parse_bop("FIXME", bop_handlers[i].handler)) { return 1; } } } for (i = 0; i < sizeof(uop_handlers)/sizeof(uop_handlers[0]); i++) { if (strcmp(uop_handlers[i].str, str) == 0) { match = 1; if (parse_uop("FIXME", uop_handlers[i].handler)) { return 1; } } } if (match == 0) { emit_error("Invalid operator \"%s\"\n", str); return 1; } return 0; } int parse_expr(char *str) { const char *expr_sep = ": "; size_t ident_len = 0; char *ident = NULL; char *op = NULL; printf("expression %s\n", str); /* FIXME magic constant string */ ident_len = strspn(str, "abcdefghijklmnopqrstuvwxyz0123456789"); if (expect(expr_sep, str + ident_len)) { return -1; } str[ident_len] = '\0'; ident = str; op = str + ident_len + strlen(expr_sep); /* FIXME do something with the identifier */ return parse_op(op); } int parse_node(char *str) { enum NODE_TYPE type = NODE_OUTPUT; strtok(str, " "); if (strcmp(str, "output") == 0) { type = NODE_OUTPUT; } else if (strcmp(str, "input") == 0) { type = NODE_INPUT; } else { emit_error("'%s' is not a valid node type\n", str); return 1; } printf("FIXME need to add node of type %s\n", type == NODE_OUTPUT ? "oot" : "innnn"); return 0; } int parse_module(char *str) { printf("FIXME module name is \"%s\" but modules are not implemented\n", str); return 0; } static struct tok_lookup tok_handlers[] = { {.str = "node", .handler = parse_node}, {.str = "module", .handler = parse_module}, {.str = "expr", .handler = parse_expr} }; int parse_line(char *line) { size_t i = 0; char *tok = line; char *delim = " "; int match = 0; if ( strlen(line) == 0 || (strlen(line) == 1 && isspace(line[0]))) { return 0; } tok = strtok(line, delim); match = 0; for (i = 0; i < sizeof(tok_handlers)/sizeof(tok_handlers[0]); i++) { if (strcmp(tok_handlers[i].str, tok) == 0) { match = 1; if ((tok_handlers[i].handler)(&tok[strlen(tok)+1])) { return 1; } } } if (match == 0) { emit_error("invalid token \"%s\"", tok); return 1; } return 0; } int main(void) { char buf[4096]; FILE *fd = stdin; while (NULL != fgets(buf, sizeof(buf), fd)) { buf[strcspn(buf, "\r\n")] = '\0'; if (parse_line(buf)) { return 1; } } return 0; }