From 85f635bf6c0e19bc984dfb8576165e7f527bb2bf Mon Sep 17 00:00:00 2001 From: Igor Date: Wed, 20 Jan 2010 22:49:40 +0300 Subject: Basic, non-optimizing compiler --- README | 3 +- brainfuck.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/README b/README index f7de6a6..dad62b2 100644 --- a/README +++ b/README @@ -8,8 +8,9 @@ All data cells are zeros initially Options (defaults are in brackets): -s num stack size (128) - -d num data size (30000) + -d num data size (1024) -t trace execution for debugging + -C translate into C (to stdout) Formats for operators '.' and ',' (output and input): -c, -i, -u, -o, -x char, signed int, unsigned int, octal, hexadecimal diff --git a/brainfuck.c b/brainfuck.c index a4fd7b6..1ddfed1 100644 --- a/brainfuck.c +++ b/brainfuck.c @@ -10,6 +10,7 @@ #include #define DATATYPE int +#define DATATYPE_STR "int" FILE *prog; @@ -19,7 +20,7 @@ DATATYPE *data = NULL; unsigned int *stack = NULL; -unsigned int data_size = 30000; +unsigned int data_size = 1024; unsigned int stack_size = 128; @@ -28,6 +29,7 @@ char fmt = 'u'; char format[9] = "%u"; int trace = 0; +int compile = 0; unsigned int cp = 0; @@ -297,6 +299,78 @@ run_code() } } +void +bf2c() +{ + char cmd; + + printf("#include \n#include \n\n"); + printf("%s data[%u];\n", DATATYPE_STR, data_size); + printf("unsigned int dp = 0;\n\n"); + printf("int main()\n{\n"); + + while ('\0' != (cmd = code[cp])) + { + switch (cmd) + { + case '[': + printf("while (data[dp])\n{\n"); + ++cp; + break; + case ']': + printf("}\n"); + ++cp; + break; + case '+': + printf("++(data[dp]);\n"); + ++cp; + break; + case '-': + printf("--(data[dp]);\n"); + ++cp; + break; + case '>': + printf("++dp;\n"); + ++cp; + break; + case '<': + printf("--dp;\n"); + ++cp; + break; + case ',': + switch (fmt) + { + case 'i': printf("scanf(\"%s\", (signed int *)&(data[dp]));\n", format); break; + case 'u': printf("scanf(\"%s\", (unsigned int *)&(data[dp]));\n", format); break; + case 'c': printf("scanf(\"%s\", (char *)&(data[dp]));\n", format); break; + case 'o': printf("scanf(\"%s\", (unsigned int *)&(data[dp]));\n", format); break; + case 'x': printf("scanf(\"%s\", (unsigned int *)&(data[dp]));\n", format); break; + } + ++cp; + break; + case '.': + if (fmt == 'c') + printf("printf(\"%s\", data[dp]);\n", format); + else + printf("printf(\"%s \", data[dp]);\n", format); + ++cp; + break; + case 'i': + case 'u': + case 'c': + case 'o': + case 'x': + fmt = cmd; + switch_format(); + ++cp; + break; + default: + ++cp; + } + } + printf("}\n"); +} + void free_all() { @@ -322,6 +396,7 @@ usage(char *self) printf(" -s num stack size (%u)\n", stack_size); printf(" -d num data size (%u)\n", data_size); printf(" -t trace execution for debugging\n"); + printf(" -C translate into C (to stdout)\n"); printf("\n"); printf("Formats for operators '.' and ',' (output and input):\n"); printf @@ -366,7 +441,7 @@ main(int argc, char **argv) int opt; - while (-1 != (opt = getopt(argc, argv, "ts:d:h?iucox"))) + while (-1 != (opt = getopt(argc, argv, "Cts:d:h?iucox"))) { switch (opt) { @@ -379,6 +454,9 @@ main(int argc, char **argv) case 't': trace = 1; break; + case 'C': + compile = 1; + break; case 'i': case 'u': case 'c': @@ -410,10 +488,15 @@ main(int argc, char **argv) if (prog != stdin) fclose(prog); - init_data(); - init_stack(); - run_code(); + if (compile) + bf2c(); + else + { + init_data(); + init_stack(); + run_code(); + } free_all(); return EXIT_SUCCESS; -- cgit v1.2.3