diff options
Diffstat (limited to 'gate.c')
-rw-r--r-- | gate.c | 104 |
1 files changed, 94 insertions, 10 deletions
@@ -1,37 +1,110 @@ #include <string.h> +#include <stdlib.h> #include "gate.h" #include "error.h" -#define GATE_MAX 1024 +#define GATE_MAX 1024 +#define INPUT_MAX 1024 +#define OUTPUT_MAX 1024 static size_t gate_count; +static size_t input_count; +static size_t output_count; static struct gate gates[GATE_MAX]; +static struct gate inputs[INPUT_MAX]; +static struct gate outputs[OUTPUT_MAX]; + int -gate_count_guard(void) { - if (gate_count >= GATE_MAX) { - emit_error("Internal: too many gates\n"); +count_guard(int c, int max, char *desc) { + if (c >= max) { + emit_error("Internal: too many %s\n", desc); + return 1; } - return 1; + return 0; } int -gate_add(struct gate *in1, struct gate *in2) { +gate_add_generic(struct gate *array, size_t array_index, char *name, enum BINARY (*operation)(enum BINARY, enum BINARY), struct gate *in1, struct gate *in2) { struct gate g = {0}; - if (gate_count_guard()) { - return 1; + if (name == NULL) { + g.name = NULL; + } else { + g.name = strdup(name); + if (g.name == NULL) { + emit_error("strdup failed"); + return 1; + } } - + g.operation = operation; g.in1 = in1; g.in2 = in2; - gates[gate_count++] = g; + array[array_index] = g; + + return 0; +} + +struct gate* +gate_get_input_by_name(char *name) { + struct gate *res = NULL; + size_t i = 0; + + for (i = 0; i < input_count; i++) { + if (inputs[i].name == NULL) { + emit_error("input at index %zd has NULL name, ignoring", i); + continue; + } + if (strcmp(inputs[i].name, name) == 0) { + res = &inputs[i]; + break; + } + } + + return res; +} + +int +gate_input_add(char *name) { + int res = 0; + if (count_guard(input_count, INPUT_MAX, "inputs")) { + return 1; + } + + if (gate_get_input_by_name(name) != NULL) { + emit_error("Already an input called \"%s\"!\n", name); + return 1; + } + + res = gate_add_generic(inputs, input_count, name, logic_and, NULL, NULL); + input_count++; + return res; +} + +int +gate_add(char *name, enum BINARY (*operation)(enum BINARY, enum BINARY), struct gate *in1, struct gate *in2) { + if (count_guard(gate_count, GATE_MAX, "gates")) { + return 1; + } + + gate_add_generic(gates, gate_count, name, operation, in1, in2); + gate_count++; return 0; } +void +gate_free_all() { + size_t i = 0; + for (i = 0; i < gate_count; i++) { + if (gates[i].name != NULL) { + free(gates[i].name); + } + } +} + int tick(void) { /* FIXME */ @@ -41,6 +114,17 @@ tick(void) { void gate_init(void) { gate_count = 0; + input_count = 0; memset(gates, 0, sizeof(gates)); + memset(inputs, 0, sizeof(inputs)); } +void +gate_dump(void) { + size_t i = 0; + + emit_info("Gates:\n"); + for (i = 0; i < gate_count; i++) { + emit_info("gate '%s'\n", gates[i].name); + } +} |