diff options
author | thing1 <thing1@seacrossedlovers.xyz> | 2025-03-10 21:23:22 +0000 |
---|---|---|
committer | thing1 <thing1@seacrossedlovers.xyz> | 2025-03-10 21:23:22 +0000 |
commit | f5792e081d90979bf3cdbbdbe7f08af98e35a27e (patch) | |
tree | 35c87db65bae80f1b722e6d0189e5e3607447a92 /turing.c |
Diffstat (limited to 'turing.c')
-rw-r--r-- | turing.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/turing.c b/turing.c new file mode 100644 index 0000000..4061a39 --- /dev/null +++ b/turing.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +typedef struct node { + int id; + bool end; +} node; + +typedef struct connection { + node *parrent; + char input; + char output; + int offset; + node *result; +} connection; + +node nodes[128]; +int nodecount = 0; + +connection connections[1024]; +int connectioncount = 0; + +void perror(const char *msg) { + fprintf(stderr, "%s\n", msg); + exit(1); +} + +node *findnode(int id) { + for (int i = 0; i < nodecount; i++) + if (nodes[i].id == id) return &nodes[i]; + return NULL; +} + +int main(int argc, char **argv) { + if (argc <= 1) perror("no file given"); + + FILE *f = fopen(argv[1], "r"); + if (f == NULL) perror("failed to open file"); + + /* define nodes */ + char *line = malloc(128); + while (fgets(line, 128, f)[0] == '#') continue; /* handles comments */ + + char *tok = strtok(line, " "); + while (tok != NULL) { + if (tok[0] == 'e') { + nodes[nodecount].end = true; + tok++; + } + nodes[nodecount].id = atoi(tok); + nodecount++; + tok = strtok(NULL, " "); + } + + /* define connections */ + node *parrent, *result; +comment: + while (fgets(line, 128, f) != NULL) { + if (line[0] == '#' || line[0] == '\n') goto comment; + + char *tok = strtok(line, " "); + if ((parrent = findnode(atoi(tok))) == NULL) perror("unknown node specified"); + connections[connectioncount].parrent = parrent; + + tok = strtok(NULL, " "); + if (tok[0] == '#') connections[connectioncount].input = 0; + else connections[connectioncount].input = tok[0]; + + tok = strtok(NULL, " "); + if (tok[0] == '#') connections[connectioncount].output = 0; + else connections[connectioncount].output = tok[0]; + + tok = strtok(NULL, " "); + connections[connectioncount].offset = atoi(tok); + + tok = strtok(NULL, " "); + if ((result = findnode(atoi(tok))) == NULL) perror("unknown node specified"); + connections[connectioncount].result = result; + + connectioncount++; + } + + char tape[4096] = {0}; + if (argc >= 3) strcat(tape, argv[2]); /* fill the tape with user input, if they give it */ + + char *head = tape; + node *current = &nodes[0]; + + for (;;) { +success: + for (int i = 0; i < connectioncount; i++) { + if (connections[i].parrent == current && connections[i].input == *head){ + *head = connections[i].output; + current = connections[i].result; + head += connections[i].offset; + goto success; + } + } + printf("%s\n", tape); + printf("%s\n", (current->end) ? "accept" : "reject"); /* did it end in a valid location */ + break; + } + + return 0; +} |