commit 4e89eae142309f7acf4f7b59212edfc7960abdce
parent 458aa029a8b9dce801f9818497560e95cab17bb3
Author: Sophie <info@soophie.de>
Date: Fri, 16 May 2025 12:34:36 +0000
feat: Added registers
Diffstat:
M | files/sample | | | 10 | +++++----- |
M | src/main.c | | | 295 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
2 files changed, 216 insertions(+), 89 deletions(-)
diff --git a/files/sample b/files/sample
@@ -1,5 +1,5 @@
-BTN---+
- |
- +---NOT---BULB
- |
-BTN---+
+REG(0)--->[x]---+
+ |
+ +---REG(2)---+---ADD---REG(3)
+ | |
+REG(1)--->[y]---+ +---<[x]---REG(4)
diff --git a/src/main.c b/src/main.c
@@ -1,12 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <ctype.h>
-#include <wctype.h>
#define BEEP_VALUE_HIGH 1
#define BEEP_VALUE_LOW 0
+#define BEEP_REGISTER_COUNT 50
+
typedef enum {
BEEP_OK = 0,
BEEP_ERROR = -1,
@@ -14,11 +16,13 @@ typedef enum {
typedef long beep_uid_t;
+typedef struct beep_board beep_board_t;
typedef struct beep_node beep_node_t;
typedef struct beep_element beep_element_t;
typedef enum {
BEEP_TYPE_NONE,
+ BEEP_TYPE_UNKNOWN,
BEEP_TYPE_WIRE_Y,
BEEP_TYPE_WIRE_X,
BEEP_TYPE_NODE,
@@ -30,6 +34,8 @@ typedef struct {
char *str;
size_t len;
size_t ref_idx;
+ char *var_str;
+ size_t var_len;
} beep_token_t;
typedef struct {
@@ -50,13 +56,16 @@ struct beep_node {
size_t nodes_len;
beep_channel_t *channels;
size_t channels_len;
+ bool is_dirty;
};
struct beep_element {
beep_uid_t uid;
+ char *type;
+ char *var;
beep_node_t *in;
beep_node_t *out;
- void (*update)(beep_element_t *self);
+ void (*update)(beep_board_t *self, beep_element_t *element);
};
typedef struct {
@@ -71,13 +80,38 @@ typedef struct {
size_t nodes_len;
} beep_state_t;
+typedef struct {
+ beep_value_t values[BEEP_REGISTER_COUNT];
+} beep_registry_t;
+
+struct beep_board {
+ char *buffer;
+ size_t rows;
+ size_t cols;
+ beep_cell_t *cells;
+ beep_token_t *tokens;
+ size_t len;
+ beep_state_t state;
+ beep_registry_t registry;
+};
+
static beep_uid_t _BEEP_UID_COUNT = 0;
-static beep_value_t _BEEP_BTN = BEEP_VALUE_LOW;
beep_uid_t beep_uid(void) {
return ++_BEEP_UID_COUNT;
}
+void beep_token_init(beep_token_t *self) {
+ *self = (beep_token_t) {
+ .type = BEEP_TYPE_UNKNOWN,
+ .str = NULL,
+ .len = 0,
+ .ref_idx = -1,
+ .var_str = NULL,
+ .var_len = 0,
+ };
+}
+
void beep_node_init(beep_node_t *self) {
*self = (beep_node_t) {
.uid = beep_uid(),
@@ -85,6 +119,7 @@ void beep_node_init(beep_node_t *self) {
.nodes_len = 0,
.channels = NULL,
.channels_len = 0,
+ .is_dirty = false,
};
}
@@ -121,6 +156,7 @@ void beep_node_update(beep_node_t *self, const beep_signal_t signal) {
return;
}
channel->value = signal.value;
+ self->is_dirty = true;
i = 0;
for (; i < self->nodes_len; i++) {
beep_node_t *node = self->nodes[i];
@@ -143,32 +179,110 @@ beep_value_t beep_node_value(beep_node_t *self) {
return BEEP_VALUE_HIGH;
}
}
+ self->is_dirty = false;
return BEEP_VALUE_LOW;
}
-void beep_element_init(beep_element_t *self, void (*update)(beep_element_t *self)) {
+void beep_registry_set(beep_board_t *self, size_t idx, beep_value_t value) {
+ if (idx >= BEEP_REGISTER_COUNT) {
+ return;
+ }
+ self->registry.values[idx] = value;
+}
+
+beep_value_t *beep_registry_get(beep_board_t *self, size_t idx) {
+ if (idx >= BEEP_REGISTER_COUNT) {
+ return NULL;
+ }
+ return &self->registry.values[idx];
+}
+
+void BEEP_REG_UPDATE(beep_board_t *self, beep_element_t *element) {
+ if (element->var == NULL) {
+ return;
+ }
+ size_t idx = atoi(element->var);
+ if (element->in->is_dirty) {
+ beep_value_t value_in = beep_node_value(element->in);
+ beep_registry_set(self, idx, value_in);
+ printf("[REG] %s --> [%zu]\n", value_in ? "HIGH" : "LOW", idx);
+ }
+ beep_value_t value_out = *beep_registry_get(self, idx);
+ beep_node_update(element->out, (beep_signal_t) { element->uid, value_out });
+ printf("[REG] [%zu] --> %s\n", idx, value_out ? "HIGH" : "LOW");
+}
+
+void BEEP_BTN_UPDATE(beep_board_t *self, beep_element_t *element) {
+ (void) self;
+ (void) element;
+}
+
+void BEEP_NOT_UPDATE(beep_board_t *self, beep_element_t *element) {
+ (void) self;
+ beep_value_t value_in = beep_node_value(element->in);
+ beep_value_t value_out = !value_in;
+ printf("[NOT] %s --> %s\n", value_in ? "HIGH" : "LOW", value_out ? "HIGH" : "LOW");
+ beep_node_update(element->out, (beep_signal_t) { element->uid, value_out });
+}
+
+void BEEP_ADD_UPDATE(beep_board_t *self, beep_element_t *element) {
+ (void) self;
+ (void) element;
+}
+
+void BEEP_BULB_UPDATE(beep_board_t *self, beep_element_t *element) {
+ (void) self;
+ beep_value_t value_in = beep_node_value(element->in);
+ printf("[BULB] %s\n", value_in ? "HIGH" : "LOW");
+}
+
+void beep_element_init(beep_element_t *self, beep_token_t *token) {
+ size_t i = 0;
+ for (; i < token->len; i++) {
+ if (i < token->len && token->str[i] == '(') {
+ break;
+ }
+ }
+ size_t type_len = i;
+ char *type = malloc(sizeof(char) * (type_len + 1));
+ memcpy(type, token->str, type_len);
+ type[type_len] = '\0';
+ char *var = NULL;
+ if (token->var_str != NULL) {
+ var = malloc(sizeof(char) * (type_len + 1));
+ memcpy(var, token->var_str, token->var_len);
+ var[token->var_len] = '\0';
+ }
+ void (*update)(beep_board_t *self, beep_element_t *element) = NULL;
+ if (strcmp(type, "REG") == 0) {
+ update = BEEP_REG_UPDATE;
+ }
+ if (strcmp(type, "BTN") == 0) {
+ update = BEEP_BTN_UPDATE;
+ }
+ if (strcmp(type, "NOT") == 0) {
+ update = BEEP_NOT_UPDATE;
+ }
+ if (strcmp(type, "ADD") == 0) {
+ update = BEEP_ADD_UPDATE;
+ }
+ if (strcmp(type, "BULB") == 0) {
+ update = BEEP_BULB_UPDATE;
+ }
beep_node_t *node_in = malloc(sizeof(beep_node_t));
beep_node_init(node_in);
beep_node_t *node_out = malloc(sizeof(beep_node_t));
beep_node_init(node_out);
*self = (beep_element_t) {
.uid = beep_uid(),
+ .type = type,
+ .var = var,
.in = node_in,
.out = node_out,
.update = update,
};
}
-typedef struct {
- char *buffer;
- size_t rows;
- size_t cols;
- beep_cell_t *cells;
- beep_token_t *tokens;
- size_t len;
- beep_state_t state;
-} beep_board_t;
-
beep_cell_t *beep_board_at(beep_board_t *self, size_t row, size_t col) {
if (self == NULL) {
return NULL;
@@ -262,6 +376,7 @@ beep_err_t beep_board_tokenize(beep_board_t *self) {
if (c == ' ' || c == '-' || c == '|' || c == '+') {
self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
beep_token_t *token = &self->tokens[self->len];
+ beep_token_init(token);
switch (c) {
case ' ':
token->type = BEEP_TYPE_NONE;
@@ -280,19 +395,49 @@ beep_err_t beep_board_tokenize(beep_board_t *self) {
token->len = 1;
self->len++;
}
- if (isalpha(c)) {
+ else if (isalpha(c)) {
size_t token_set = i;
+ char *var_str = NULL;
+ size_t var_len = -1;
while (i < len && isalpha(self->buffer[i])) {
i++;
}
+ if (i < len && self->buffer[i] == '(') {
+ size_t i_reset = i;
+ i++;
+ size_t var_set = i;
+ while (i < len && self->buffer[i] != ')') {
+ i++;
+ }
+ if (i < len && self->buffer[i] == ')') {
+ var_str = self->buffer + var_set;
+ var_len = i - var_set;
+ i++;
+ }
+ else {
+ i = i_reset;
+ }
+ }
self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
beep_token_t *token = &self->tokens[self->len];
token->type = BEEP_TYPE_ELEMENT;
token->str = self->buffer + token_set;
token->len = i - token_set;
+ if (var_str != NULL) {
+ token->var_str = var_str;
+ token->var_len = var_len;
+ }
self->len++;
i--;
}
+ else {
+ self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
+ beep_token_t *token = &self->tokens[self->len];
+ token->type = BEEP_TYPE_UNKNOWN;
+ token->str = self->buffer + i;
+ token->len = 1;
+ self->len++;
+ }
}
// create cells
self->cells = calloc(self->rows * self->cols, sizeof(beep_cell_t));
@@ -310,24 +455,6 @@ beep_err_t beep_board_tokenize(beep_board_t *self) {
return BEEP_OK;
}
-void BEEP_BTN_UPDATE(beep_element_t *self) {
- beep_value_t value_out = _BEEP_BTN;
- printf("[BTN] %s\n", value_out ? "HIGH" : "LOW");
- beep_node_update(self->out, (beep_signal_t) { self->uid, value_out });
-}
-
-void BEEP_NOT_UPDATE(beep_element_t *self) {
- beep_value_t value_in = beep_node_value(self->in);
- beep_value_t value_out = !value_in;
- printf("[NOT] %s --> %s\n", value_in ? "HIGH" : "LOW", value_out ? "HIGH" : "LOW");
- beep_node_update(self->out, (beep_signal_t) { self->uid, value_out });
-}
-
-void BEEP_BULB_UPDATE(beep_element_t *self) {
- beep_value_t value_in = beep_node_value(self->in);
- printf("[BULB] %s\n", value_in ? "HIGH" : "LOW");
-}
-
beep_err_t beep_board_construct(beep_board_t *self) {
if (self == NULL) {
return BEEP_ERROR;
@@ -340,20 +467,7 @@ beep_err_t beep_board_construct(beep_board_t *self) {
if (token->type == BEEP_TYPE_ELEMENT) {
state->elements = realloc(state->elements, sizeof(beep_element_t) * (state->elements_len + 1));
beep_element_t *element = &state->elements[state->elements_len];
- char element_type[token->len + 1];
- memcpy(element_type, token->str, token->len);
- element_type[token->len] = '\0';
- void (*update)(beep_element_t *self) = NULL;
- if (strcmp(element_type, "BTN") == 0) {
- update = BEEP_BTN_UPDATE;
- }
- if (strcmp(element_type, "NOT") == 0) {
- update = BEEP_NOT_UPDATE;
- }
- if (strcmp(element_type, "BULB") == 0) {
- update = BEEP_BULB_UPDATE;
- }
- beep_element_init(element, update);
+ beep_element_init(element, token);
token->ref_idx = state->elements_len;
state->elements_len++;
}
@@ -469,14 +583,53 @@ beep_err_t beep_board_init(beep_board_t *self, char *buffer) {
.tokens = NULL,
.len = 0,
.state = {0},
+ .registry = {
+ .values = {0},
+ },
};
+ memset(self->registry.values, BEEP_VALUE_LOW, sizeof(beep_value_t) * BEEP_REGISTER_COUNT);
beep_err_t ret;
if ((ret = beep_board_read(self, buffer)) == BEEP_ERROR) {
return ret;
}
+ for (size_t y = 0; y < self->rows; y++) {
+ for (size_t x = 0; x < self->cols; x++) {
+ printf("%c", self->buffer[y * self->cols + x]);
+ }
+ printf("\n");
+ }
+ printf("\n");
if ((ret = beep_board_tokenize(self)) == BEEP_ERROR) {
return ret;
}
+ for (size_t y = 0; y < self->rows; y++) {
+ for (size_t x = 0; x < self->cols; x++) {
+ size_t idx = y * self->cols + x;
+ beep_cell_t *cell = &self->cells[idx];
+ switch (cell->token->type) {
+ case BEEP_TYPE_NONE:
+ printf(".");
+ break;
+ case BEEP_TYPE_UNKNOWN:
+ printf("?");
+ break;
+ case BEEP_TYPE_WIRE_Y:
+ printf("Y");
+ break;
+ case BEEP_TYPE_WIRE_X:
+ printf("X");
+ break;
+ case BEEP_TYPE_NODE:
+ printf("N");
+ break;
+ case BEEP_TYPE_ELEMENT:
+ printf("E");
+ break;
+ }
+ }
+ printf("\n");
+ }
+ printf("\n");
if ((ret = beep_board_construct(self)) == BEEP_ERROR) {
return ret;
}
@@ -505,6 +658,10 @@ void beep_board_free(beep_board_t *self) {
size_t i = 0;
for (; i < state->elements_len; i++) {
beep_element_t *element = &state->elements[i];
+ free(element->type);
+ if (element->var != NULL) {
+ free(element->var);
+ }
free(element->in);
free(element->out);
}
@@ -531,52 +688,22 @@ void beep_update(beep_board_t *self) {
size_t i = 0;
for (; i < state->elements_len; i++) {
beep_element_t *element = &state->elements[i];
- element->update(element);
+ if (element->update == NULL) {
+ continue;
+ }
+ element->update(self, element);
}
}
int main(void) {
beep_board_t board;
- if (beep_board_load(&board, "./files/not") < 0) {
+ if (beep_board_load(&board, "./files/sample") < 0) {
return BEEP_ERROR;
}
- for (size_t y = 0; y < board.rows; y++) {
- for (size_t x = 0; x < board.cols; x++) {
- printf("%c", board.buffer[y * board.cols + x]);
- }
- printf("\n");
- }
- printf("\n");
- for (size_t y = 0; y < board.rows; y++) {
- for (size_t x = 0; x < board.cols; x++) {
- size_t idx = y * board.cols + x;
- beep_cell_t *cell = &board.cells[idx];
- switch (cell->token->type) {
- case BEEP_TYPE_NONE:
- printf(".");
- break;
- case BEEP_TYPE_WIRE_Y:
- printf("Y");
- break;
- case BEEP_TYPE_WIRE_X:
- printf("X");
- break;
- case BEEP_TYPE_NODE:
- printf("N");
- break;
- case BEEP_TYPE_ELEMENT:
- printf("E");
- break;
- }
- }
- printf("\n");
- }
- printf("\n");
- beep_update(&board);
- _BEEP_BTN = BEEP_VALUE_HIGH;
beep_update(&board);
- _BEEP_BTN = BEEP_VALUE_LOW;
+ beep_registry_set(&board, 0, BEEP_VALUE_HIGH);
beep_update(&board);
+ beep_registry_set(&board, 0, BEEP_VALUE_LOW);
beep_update(&board);
beep_board_free(&board);
return BEEP_OK;