Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- enum Token
- {
- LEFT, RIGHT,
- PLUS, MINUS,
- READ, WRITE,
- LLOOP, RLOOP,
- };
- struct TokenArray
- {
- enum Token *tokens;
- size_t len;
- size_t capacity;
- };
- int newtokenarray(struct TokenArray **out)
- {
- enum Token *mem = malloc(sizeof(enum Token)*8);
- if (mem == NULL) return 1;
- struct TokenArray *array = malloc(sizeof(struct TokenArray));
- if (array == NULL) return 1;
- array->tokens = mem;
- array->len = 0;
- array->capacity = 8;
- *out = array;
- return 0;
- }
- void pushtoken(struct TokenArray *array, enum Token token)
- {
- if (array->len + 1 > array->capacity)
- {
- void *new_ptr = realloc(array->tokens, array->capacity * 2); // Reallocate
- if (new_ptr == NULL)
- {
- printf("Panic: reallocation for TokenArray failed.");
- exit(1);
- }
- array->tokens = new_ptr;
- }
- array->tokens[array->len++] = token; // Add the token
- }
- void cleanuptokenarray(struct TokenArray *array)
- {
- free(array->tokens);
- }
- void tokenize(struct TokenArray **array, const char *input)
- {
- if (*array == NULL)
- newtokenarray(array);
- size_t len = strlen(input);
- for (size_t i = 0; i < len; i++)
- {
- switch (input[i])
- {
- case '>':
- pushtoken(*array, RIGHT);
- break;
- case '<':
- pushtoken(*array, LEFT);
- break;
- case '+':
- pushtoken(*array, PLUS);
- break;
- case '-':
- pushtoken(*array, MINUS);
- break;
- case ',':
- pushtoken(*array, READ);
- break;
- case '.':
- pushtoken(*array, WRITE);
- break;
- case '[':
- pushtoken(*array, LLOOP);
- break;
- case ']':
- pushtoken(*array, RLOOP);
- break;
- default:
- break;
- }
- }
- }
- void pushstr(char **dst, const char *src)
- {
- void *new_mem = realloc(*dst, strlen(*dst)+strlen(src)+2);
- if (new_mem == NULL)
- {
- printf("Panic: reallocation for pushstr failed.");
- exit(1);
- }
- *dst = new_mem;
- strcat(*dst, src);
- }
- static char *preface = "#include <stdio.h>\n\nint main() {\n char tape[30000] = {0};\n char *ptr = tape;\n";
- char *generatecode(const struct TokenArray *array)
- {
- char *output = malloc(sizeof(char)*(strlen(preface)+1));
- memcpy(output, preface, strlen(preface)+1);
- unsigned indents = 1;
- for (size_t i = 0; i < array->len; i++)
- {
- switch (array->tokens[i])
- {
- case RIGHT:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "++ptr;\n");
- break;
- case LEFT:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "--ptr;\n");
- break;
- case PLUS:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "*++ptr;\n");
- break;
- case MINUS:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "*--ptr;\n");
- break;
- case READ:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "*ptr=getchar();\n");
- break;
- case WRITE:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "putchar(*ptr);\n");
- break;
- case LLOOP:
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- ++indents;
- pushstr(&output, "while (*ptr) {\n");
- break;
- case RLOOP:
- --indents;
- for (unsigned t = 0; t < indents; t++)
- pushstr(&output, " ");
- pushstr(&output, "}\n");
- break;
- }
- }
- pushstr(&output, "}\n");
- return output;
- }
- int main(int argc, char const *argv[])
- {
- struct TokenArray *tokens;
- newtokenarray(&tokens);
- tokenize(&tokens, "<><>");
- char *code = generatecode(tokens);
- printf("%s", code);
- cleanuptokenarray(tokens);
- free(code);
- return 0;
- }
Add Comment
Please, Sign In to add comment