Created
August 18, 2018 04:21
-
-
Save lukewilson2002/34264e49d0d65487db7fd4f2fe75a441 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment