QUOTE: Enjoy small things, cherish moments.

beep

A tiny terminal-based ASCII circuit simulator

main.c (18807B)


      1#include <stdio.h>
      2#include <stdlib.h>
      3#include <stdbool.h>
      4#include <string.h>
      5#include <ctype.h>
      6
      7#define BEEP_VALUE_HIGH 1
      8#define BEEP_VALUE_LOW  0
      9
     10#define BEEP_REGISTER_COUNT 50
     11
     12typedef enum {
     13  BEEP_OK = 0,
     14  BEEP_ERROR = -1,
     15} beep_err_t;
     16
     17typedef long beep_uid_t;
     18
     19typedef struct beep_board beep_board_t;
     20typedef struct beep_node beep_node_t;
     21typedef struct beep_element beep_element_t;
     22
     23typedef enum {
     24  BEEP_TYPE_NONE,
     25  BEEP_TYPE_UNKNOWN,
     26  BEEP_TYPE_WIRE_Y,
     27  BEEP_TYPE_WIRE_X,
     28  BEEP_TYPE_NODE,
     29  BEEP_TYPE_ELEMENT,
     30} beep_type_t;
     31
     32typedef struct {
     33  beep_type_t type;
     34  char *str;
     35  size_t len;
     36  size_t ref_idx;
     37  char *var_str;
     38  size_t var_len;
     39} beep_token_t;
     40
     41typedef struct {
     42  beep_token_t *token;
     43} beep_cell_t;
     44
     45typedef int beep_value_t;
     46
     47typedef struct {
     48  beep_uid_t element_uid;
     49  size_t idx;
     50  beep_value_t value;
     51} beep_channel_t;
     52
     53struct beep_node {
     54  beep_uid_t uid;
     55  beep_node_t **nodes;
     56  size_t nodes_len;
     57  beep_channel_t *channels;
     58  size_t channels_len;
     59  bool is_dirty;
     60};
     61
     62struct beep_element {
     63  beep_uid_t uid;
     64  char *type;
     65  char *var;
     66  beep_node_t *in;
     67  beep_node_t *out;
     68  void (*update)(beep_board_t *self, beep_element_t *element);
     69};
     70
     71typedef struct {
     72  beep_uid_t element_uid;
     73  beep_value_t value;
     74} beep_signal_t;
     75
     76typedef struct {
     77  beep_element_t *elements;
     78  size_t elements_len;
     79  beep_node_t *nodes;
     80  size_t nodes_len;
     81} beep_state_t;
     82
     83typedef struct {
     84  beep_value_t values[BEEP_REGISTER_COUNT];
     85} beep_registry_t;
     86
     87struct beep_board {
     88  char *buffer;
     89  size_t rows;
     90  size_t cols;
     91  beep_cell_t *cells;
     92  beep_token_t *tokens;
     93  size_t len;
     94  beep_state_t state;
     95  beep_registry_t registry;
     96};
     97
     98static beep_uid_t _BEEP_UID_COUNT = 0;
     99
    100beep_uid_t beep_uid(void) {
    101  return ++_BEEP_UID_COUNT;
    102}
    103
    104void beep_token_init(beep_token_t *self) {
    105  *self = (beep_token_t) {
    106    .type = BEEP_TYPE_UNKNOWN,
    107    .str = NULL,
    108    .len = 0,
    109    .ref_idx = -1,
    110    .var_str = NULL,
    111    .var_len = 0,
    112  };
    113}
    114
    115void beep_node_init(beep_node_t *self) {
    116  *self = (beep_node_t) {
    117    .uid = beep_uid(),
    118    .nodes = NULL,
    119    .nodes_len = 0,
    120    .channels = NULL,
    121    .channels_len = 0,
    122    .is_dirty = false,
    123  };
    124}
    125
    126void beep_node_index(beep_node_t *self, beep_uid_t element_uid, size_t idx) {
    127  size_t i = 0;
    128  for (; i < self->channels_len; i++) {
    129    if (self->channels[i].element_uid == element_uid) {
    130      return;
    131    }
    132  }
    133  self->channels = realloc(self->channels, sizeof(beep_channel_t) * (self->channels_len + 1));
    134  beep_channel_t *channel = &self->channels[self->channels_len];
    135  channel->element_uid = element_uid;
    136  channel->idx = idx;
    137  channel->value = 0;
    138  self->channels_len++;
    139  i = 0;
    140  for (; i < self->nodes_len; i++) {
    141    beep_node_t *node = self->nodes[i];
    142    beep_node_index(node, element_uid, idx + 1);
    143  }
    144}
    145
    146void beep_node_update(beep_node_t *self, const beep_signal_t signal) {
    147  size_t i = 0;
    148  beep_channel_t *channel = NULL;
    149  for (; i < self->channels_len; i++) {
    150    if (self->channels[i].element_uid == signal.element_uid) {
    151      channel = &self->channels[i];
    152      break;
    153    }
    154  }
    155  if (channel == NULL) {
    156    return;
    157  }
    158  channel->value = signal.value;
    159  self->is_dirty = true;
    160  i = 0;
    161  for (; i < self->nodes_len; i++) {
    162    beep_node_t *node = self->nodes[i];
    163    size_t j = 0;
    164    for (; j < node->channels_len; j++) {
    165      beep_channel_t *node_channel = &node->channels[j];
    166      if (node_channel->element_uid == channel->element_uid && node_channel->idx > channel->idx) {
    167        beep_node_update(node, signal);
    168        break;
    169      }
    170    }
    171  }
    172}
    173
    174beep_value_t beep_node_value(beep_node_t *self) {
    175  size_t i = 0;
    176  for (; i < self->channels_len; i++) {
    177    beep_channel_t *channel = &self->channels[i];
    178    if (channel->value == BEEP_VALUE_HIGH) {
    179      return BEEP_VALUE_HIGH;
    180    }
    181  }
    182  self->is_dirty = false;
    183  return BEEP_VALUE_LOW;
    184}
    185
    186void beep_registry_set(beep_board_t *self, size_t idx, beep_value_t value) {
    187  if (idx >= BEEP_REGISTER_COUNT) {
    188    return;
    189  }
    190  self->registry.values[idx] = value;
    191}
    192
    193beep_value_t *beep_registry_get(beep_board_t *self, size_t idx) {
    194  if (idx >= BEEP_REGISTER_COUNT) {
    195    return NULL;
    196  }
    197  return &self->registry.values[idx];
    198}
    199
    200void BEEP_REG_UPDATE(beep_board_t *self, beep_element_t *element) {
    201  if (element->var == NULL) {
    202    return;
    203  }
    204  size_t idx = atoi(element->var);
    205  if (element->in->is_dirty) {
    206    beep_value_t value_in = beep_node_value(element->in);
    207    beep_registry_set(self, idx, value_in);
    208    printf("[REG] %s --> [%zu]\n", value_in ? "HIGH" : "LOW", idx);
    209  }
    210  beep_value_t value_out = *beep_registry_get(self, idx);
    211  beep_node_update(element->out, (beep_signal_t) { element->uid, value_out });
    212  printf("[REG] [%zu] --> %s\n", idx, value_out ? "HIGH" : "LOW");
    213}
    214
    215void BEEP_BTN_UPDATE(beep_board_t *self, beep_element_t *element) {
    216  (void) self;
    217  (void) element;
    218}
    219
    220void BEEP_NOT_UPDATE(beep_board_t *self, beep_element_t *element) {
    221  (void) self;
    222  beep_value_t value_in = beep_node_value(element->in);
    223  beep_value_t value_out = !value_in;
    224  printf("[NOT] %s --> %s\n", value_in ? "HIGH" : "LOW", value_out ? "HIGH" : "LOW");
    225  beep_node_update(element->out, (beep_signal_t) { element->uid, value_out });
    226}
    227
    228void BEEP_ADD_UPDATE(beep_board_t *self, beep_element_t *element) {
    229  (void) self;
    230  (void) element;
    231}
    232
    233void BEEP_BULB_UPDATE(beep_board_t *self, beep_element_t *element) {
    234  (void) self;
    235  beep_value_t value_in = beep_node_value(element->in);
    236  printf("[BULB] %s\n", value_in ? "HIGH" : "LOW");
    237}
    238
    239void beep_element_init(beep_element_t *self, beep_token_t *token) {
    240  size_t i = 0;
    241  for (; i < token->len; i++) {
    242    if (i < token->len && token->str[i] == '(') {
    243      break;
    244    }
    245  }
    246  size_t type_len = i;
    247  char *type = malloc(sizeof(char) * (type_len + 1));
    248  memcpy(type, token->str, type_len);
    249  type[type_len] = '\0';
    250  char *var = NULL;
    251  if (token->var_str != NULL) {
    252    var = malloc(sizeof(char) * (type_len + 1));
    253    memcpy(var, token->var_str, token->var_len);
    254    var[token->var_len] = '\0';
    255  }
    256  void (*update)(beep_board_t *self, beep_element_t *element) = NULL;
    257  if (strcmp(type, "REG") == 0) {
    258    update = BEEP_REG_UPDATE;
    259  }
    260  if (strcmp(type, "BTN") == 0) {
    261    update = BEEP_BTN_UPDATE;
    262  }
    263  if (strcmp(type, "NOT") == 0) {
    264    update = BEEP_NOT_UPDATE;
    265  }
    266  if (strcmp(type, "ADD") == 0) {
    267    update = BEEP_ADD_UPDATE;
    268  }
    269  if (strcmp(type, "BULB") == 0) {
    270    update = BEEP_BULB_UPDATE;
    271  }
    272  beep_node_t *node_in = malloc(sizeof(beep_node_t));
    273  beep_node_init(node_in);
    274  beep_node_t *node_out = malloc(sizeof(beep_node_t));
    275  beep_node_init(node_out);
    276  *self = (beep_element_t) {
    277    .uid = beep_uid(),
    278    .type = type,
    279    .var = var,
    280    .in = node_in,
    281    .out = node_out,
    282    .update = update,
    283  };
    284}
    285
    286beep_cell_t *beep_board_at(beep_board_t *self, size_t row, size_t col) {
    287  if (self == NULL) {
    288    return NULL;
    289  }
    290  if (row >= self->rows || col >= self->cols) {
    291    return NULL;
    292  }
    293  return &self->cells[row * self->cols + col];
    294}
    295
    296beep_err_t beep_file_read(char *filename, char **buffer) {
    297  FILE *file = fopen(filename, "r");
    298  if (file == NULL) {
    299    return BEEP_ERROR;
    300  }
    301  fseek(file, 0, SEEK_END);
    302  size_t len = ftell(file);
    303  fseek(file, 0, SEEK_SET);
    304  *buffer = malloc(sizeof(char) * (len + 1));
    305  fread(*buffer, sizeof(char), len, file);
    306  (*buffer)[len] = '\0';
    307  fclose(file);
    308  return BEEP_OK;
    309}
    310
    311beep_err_t beep_board_read(beep_board_t *self, char *buffer) {
    312  if (self == NULL) {
    313    return BEEP_ERROR;
    314  }
    315  // read dimensions (rows, cols)
    316  size_t len = strlen(buffer);
    317  size_t i = 0;
    318  size_t ln_set = i;
    319  for (; i < len; i++) {
    320    char c = buffer[i];
    321    if (c == '\n') {
    322      size_t ln_len = i - ln_set;
    323      if (i > 0 && buffer[i - 1] == '\r') {
    324        ln_len--;
    325      }
    326      if (ln_len > self->cols) {
    327        self->cols = ln_len;
    328      }
    329      ln_set = i + 1;
    330      self->rows++;
    331    }
    332  }
    333  if (ln_set < len) {
    334    size_t ln_len = i - ln_set;
    335    if (i > 0 && buffer[i - 1] == '\r') {
    336      ln_len--;
    337    }
    338    if (ln_len > self->cols) {
    339      self->cols = ln_len;
    340    }
    341    self->rows++;
    342  }
    343  // fill board
    344  self->buffer = malloc(sizeof(char) * self->rows * self->cols);
    345  memset(self->buffer, ' ', self->rows * self->cols);
    346  i = 0;
    347  ln_set = i;
    348  size_t ln = i;
    349  for (; i < len; i++) {
    350    size_t ln_idx = i - ln_set;
    351    char c = buffer[i];
    352    if (c == '\r') {
    353      continue;
    354    }
    355    if (c == '\n') {
    356      ln_set = i + 1;
    357      ln++;
    358      continue;
    359    }
    360    if (ln_idx < self->cols) {
    361      self->buffer[ln * self->cols + ln_idx] = c;
    362    }
    363  }
    364  return BEEP_OK;
    365}
    366
    367beep_err_t beep_board_tokenize(beep_board_t *self) {
    368  if (self == NULL) {
    369    return BEEP_ERROR;
    370  }
    371  // read tokens
    372  size_t i = 0;
    373  size_t len = self->rows * self->cols;
    374  for (; i < len; i++) {
    375    char c = self->buffer[i];
    376    if (c == ' ' || c == '-' || c == '|' || c == '+') {
    377      self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
    378      beep_token_t *token = &self->tokens[self->len];
    379      beep_token_init(token);
    380      switch (c) {
    381        case ' ':
    382          token->type = BEEP_TYPE_NONE;
    383          break;
    384        case '-':
    385          token->type = BEEP_TYPE_WIRE_X;
    386          break;
    387        case '|':
    388          token->type = BEEP_TYPE_WIRE_Y;
    389          break;
    390        case '+':
    391          token->type = BEEP_TYPE_NODE;
    392          break;
    393      }
    394      token->str = self->buffer + i;
    395      token->len = 1;
    396      self->len++;
    397    }
    398    else if (isalpha(c)) {
    399      size_t token_set = i;
    400      char *var_str = NULL;
    401      size_t var_len = -1;
    402      while (i < len && isalpha(self->buffer[i])) {
    403        i++;
    404      }
    405      if (i < len && self->buffer[i] == '(') {
    406        size_t i_reset = i;
    407        i++;
    408        size_t var_set = i;
    409        while (i < len && self->buffer[i] != ')') {
    410          i++;
    411        }
    412        if (i < len && self->buffer[i] == ')') {
    413          var_str = self->buffer + var_set;
    414          var_len = i - var_set;
    415          i++;
    416        }
    417        else {
    418          i = i_reset;
    419        }
    420      }
    421      self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
    422      beep_token_t *token = &self->tokens[self->len];
    423      token->type = BEEP_TYPE_ELEMENT;
    424      token->str = self->buffer + token_set;
    425      token->len = i - token_set;
    426      if (var_str != NULL) {
    427        token->var_str = var_str;
    428        token->var_len = var_len;
    429      }
    430      self->len++;
    431      i--;
    432    }
    433    else {
    434      self->tokens = realloc(self->tokens, sizeof(beep_token_t) * (self->len + 1));
    435      beep_token_t *token = &self->tokens[self->len];
    436      token->type = BEEP_TYPE_UNKNOWN;
    437      token->str = self->buffer + i;
    438      token->len = 1;
    439      self->len++;
    440    }
    441  }
    442  // create cells
    443  self->cells = calloc(self->rows * self->cols, sizeof(beep_cell_t));
    444  i = 0;
    445  size_t cell_idx = i;
    446  for (; i < self->len; i++) {
    447    beep_token_t *token = &self->tokens[i];
    448    size_t j = 0;
    449    for (; j < token->len; j++) {
    450      beep_cell_t *cell = &self->cells[cell_idx + j];
    451      cell->token = token;
    452    }
    453    cell_idx += token->len;
    454  }
    455  return BEEP_OK;
    456}
    457
    458beep_err_t beep_board_construct(beep_board_t *self) {
    459  if (self == NULL) {
    460    return BEEP_ERROR;
    461  }
    462  beep_state_t *state = &self->state;
    463  // create elements/nodes
    464  size_t i = 0;
    465  for (; i < self->len; i++) {
    466    beep_token_t *token = &self->tokens[i];
    467    if (token->type == BEEP_TYPE_ELEMENT) {
    468      state->elements = realloc(state->elements, sizeof(beep_element_t) * (state->elements_len + 1));
    469      beep_element_t *element = &state->elements[state->elements_len];
    470      beep_element_init(element, token);
    471      token->ref_idx = state->elements_len;
    472      state->elements_len++;
    473    }
    474    if (token->type == BEEP_TYPE_NODE) {
    475      state->nodes = realloc(state->nodes, sizeof(beep_node_t) * (state->nodes_len + 1));
    476      beep_node_t *node = &state->nodes[state->nodes_len];
    477      beep_node_init(node);
    478      token->ref_idx = state->nodes_len;
    479      state->nodes_len++;
    480    }
    481  }
    482  // link all horizontal wires
    483  for (size_t y = 0; y < self->rows; y++) {
    484    size_t x = 0;
    485    beep_cell_t *cell_set = NULL;
    486    while (x < self->cols) {
    487      beep_cell_t *cell = beep_board_at(self, y, x);
    488      if (cell->token->type == BEEP_TYPE_WIRE_X) {
    489        if (x > 0) {
    490          cell_set = beep_board_at(self, y, x - 1);
    491        }
    492        while (x < self->cols && cell->token->type == BEEP_TYPE_WIRE_X) {
    493          cell = beep_board_at(self, y, ++x);
    494        }
    495        if (cell != NULL && cell_set != NULL) {
    496          beep_type_t type_set = cell_set->token->type;
    497          beep_type_t type_end = cell->token->type;
    498          if (
    499            (type_set == BEEP_TYPE_ELEMENT || type_set == BEEP_TYPE_NODE) &&
    500            (type_end == BEEP_TYPE_ELEMENT || type_end == BEEP_TYPE_NODE)
    501          ) {
    502            beep_node_t *node_set = NULL;
    503            beep_node_t *node_end = NULL;
    504            if (type_set == BEEP_TYPE_ELEMENT) {
    505              beep_element_t *element = &state->elements[cell_set->token->ref_idx];
    506              node_set = element->out;
    507            }
    508            if (type_set == BEEP_TYPE_NODE) {
    509              node_set = &state->nodes[cell_set->token->ref_idx];
    510            }
    511            if (type_end == BEEP_TYPE_ELEMENT) {
    512              beep_element_t *element = &state->elements[cell->token->ref_idx];
    513              node_end = element->in;
    514            }
    515            if (type_end == BEEP_TYPE_NODE) {
    516              node_end = &state->nodes[cell->token->ref_idx];
    517            }
    518            if (node_set != NULL && node_end != NULL) {
    519              node_set->nodes = realloc(node_set->nodes, sizeof(beep_node_t *) * (node_set->nodes_len + 1));
    520              node_set->nodes[node_set->nodes_len] = node_end;
    521              node_set->nodes_len++;
    522              node_end->nodes = realloc(node_end->nodes, sizeof(beep_node_t *) * (node_end->nodes_len + 1));
    523              node_end->nodes[node_end->nodes_len] = node_set;
    524              node_end->nodes_len++;
    525            }
    526          }
    527        }
    528        x--;
    529      }
    530      x++;
    531    }
    532  }
    533  // link all vertical wires
    534  for (size_t x = 0; x < self->cols; x++) {
    535    size_t y = 0;
    536    beep_cell_t *cell_set = NULL;
    537    while (y < self->rows) {
    538      beep_cell_t *cell = beep_board_at(self, y, x);
    539      if (cell->token->type == BEEP_TYPE_WIRE_Y) {
    540        if (y > 0) {
    541          cell_set = beep_board_at(self, y - 1, x);
    542        }
    543        while (y < self->rows && cell->token->type == BEEP_TYPE_WIRE_Y) {
    544          cell = beep_board_at(self, ++y, x);
    545        }
    546        if (cell != NULL && cell_set != NULL) {
    547          beep_type_t type_set = cell_set->token->type;
    548          beep_type_t type_end = cell->token->type;
    549          if (type_set == BEEP_TYPE_NODE && type_end == BEEP_TYPE_NODE) {
    550            beep_node_t *node_set = &state->nodes[cell_set->token->ref_idx];
    551            beep_node_t *node_end = &state->nodes[cell->token->ref_idx];
    552            node_set->nodes = realloc(node_set->nodes, sizeof(beep_node_t *) * (node_set->nodes_len + 1));
    553            node_set->nodes[node_set->nodes_len] = node_end;
    554            node_set->nodes_len++;
    555            node_end->nodes = realloc(node_end->nodes, sizeof(beep_node_t *) * (node_end->nodes_len + 1));
    556            node_end->nodes[node_end->nodes_len] = node_set;
    557            node_end->nodes_len++;
    558          }
    559        }
    560        y--;
    561      }
    562      y++;
    563    }
    564  }
    565  // channel indexing
    566  i = 0;
    567  for (; i < state->elements_len; i++) {
    568    beep_element_t *element = &state->elements[i];
    569    beep_node_index(element->out, element->uid, 0);
    570  }
    571  return BEEP_OK;
    572}
    573
    574beep_err_t beep_board_init(beep_board_t *self, char *buffer) {
    575  if (buffer == NULL) {
    576    return BEEP_ERROR;
    577  }
    578  *self = (beep_board_t) {
    579    .buffer = NULL,
    580    .rows = 0,
    581    .cols = 0,
    582    .cells = NULL,
    583    .tokens = NULL,
    584    .len = 0,
    585    .state = {0},
    586    .registry = {
    587      .values = {0},
    588    },
    589  };
    590  memset(self->registry.values, BEEP_VALUE_LOW, sizeof(beep_value_t) * BEEP_REGISTER_COUNT);
    591  beep_err_t ret;
    592  if ((ret = beep_board_read(self, buffer)) == BEEP_ERROR) {
    593    return ret;
    594  }
    595  for (size_t y = 0; y < self->rows; y++) {
    596    for (size_t x = 0; x < self->cols; x++) {
    597      printf("%c", self->buffer[y * self->cols + x]);
    598    }
    599    printf("\n");
    600  }
    601  printf("\n");
    602  if ((ret = beep_board_tokenize(self)) == BEEP_ERROR) {
    603    return ret;
    604  }
    605  for (size_t y = 0; y < self->rows; y++) {
    606    for (size_t x = 0; x < self->cols; x++) {
    607      size_t idx = y * self->cols + x;
    608      beep_cell_t *cell = &self->cells[idx];
    609      switch (cell->token->type) {
    610        case BEEP_TYPE_NONE:
    611          printf(".");
    612          break;
    613        case BEEP_TYPE_UNKNOWN:
    614          printf("?");
    615          break;
    616        case BEEP_TYPE_WIRE_Y:
    617          printf("Y");
    618          break;
    619        case BEEP_TYPE_WIRE_X:
    620          printf("X");
    621          break;
    622        case BEEP_TYPE_NODE:
    623          printf("N");
    624          break;
    625        case BEEP_TYPE_ELEMENT:
    626          printf("E");
    627          break;
    628      }
    629    }
    630    printf("\n");
    631  }
    632  printf("\n");
    633  if ((ret = beep_board_construct(self)) == BEEP_ERROR) {
    634    return ret;
    635  }
    636  return BEEP_OK;
    637}
    638
    639beep_err_t beep_board_load(beep_board_t *self, char *filename) {
    640  char *buffer = NULL;
    641  if (beep_file_read(filename, &buffer) < 0) {
    642    return BEEP_ERROR;
    643  }
    644  beep_err_t ret = beep_board_init(self, buffer);
    645  free(buffer);
    646  return ret;
    647}
    648
    649void beep_board_free(beep_board_t *self) {
    650  if (self == NULL) {
    651    return;
    652  }
    653  free(self->buffer);
    654  free(self->cells);
    655  free(self->tokens);
    656  beep_state_t *state = &self->state;
    657  if (state->elements_len > 0) {
    658    size_t i = 0;
    659    for (; i < state->elements_len; i++) {
    660      beep_element_t *element = &state->elements[i];
    661      free(element->type);
    662      if (element->var != NULL) {
    663        free(element->var);
    664      }
    665      free(element->in);
    666      free(element->out);
    667    }
    668    free(state->elements);
    669  }
    670  if (state->nodes_len > 0) {
    671    size_t i = 0;
    672    for (; i < state->nodes_len; i++) {
    673      beep_node_t *node = &state->nodes[i];
    674      if (node->nodes_len > 0) {
    675        free(node->nodes);
    676      }
    677      if (node->channels_len > 0) {
    678        free(node->channels);
    679      }
    680    }
    681    free(state->nodes);
    682  }
    683}
    684
    685void beep_update(beep_board_t *self) {
    686  printf("----- update -----\n");
    687  beep_state_t *state = &self->state;
    688  size_t i = 0;
    689  for (; i < state->elements_len; i++) {
    690    beep_element_t *element = &state->elements[i];
    691    if (element->update == NULL) {
    692      continue;
    693    }
    694    element->update(self, element);
    695  }
    696}
    697
    698int main(void) {
    699  beep_board_t board;
    700  if (beep_board_load(&board, "./files/sample") < 0) {
    701    return BEEP_ERROR;
    702  }
    703  beep_update(&board);
    704  beep_registry_set(&board, 0, BEEP_VALUE_HIGH);
    705  beep_update(&board);
    706  beep_registry_set(&board, 0, BEEP_VALUE_LOW);
    707  beep_update(&board);
    708  beep_board_free(&board);
    709  return BEEP_OK;
    710}