diff options
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | brainfuck.c | 330 |
2 files changed, 215 insertions, 124 deletions
@@ -3,6 +3,11 @@ BF = brainfuck CC = gcc CFLAGS = -ansi -pedantic -Wall -Wextra -Werror +INDENT_OPT = -bap -bad -bbb -bl -bli0 -bls \ + -c2 -cli2 -cdb -sc -ncs -npcs \ + -nhnl -i4 -l80 -saf -sai -saw \ + -nprs -sob -nut -nbc -ppi2 -nbbo + all: $(BF) README $(BF): $(BF).c @@ -11,3 +16,7 @@ $(BF): $(BF).c README: $(BF) ./$(BF) -h > $@ +indent: $(BF).c + indent $(INDENT_OPT) $? + +.PHONY: indent diff --git a/brainfuck.c b/brainfuck.c index 47bc60e..a4fd7b6 100644 --- a/brainfuck.c +++ b/brainfuck.c @@ -1,3 +1,4 @@ + /* * gcc -ansi -pedantic -Wall -Wextra -Werror -o brainfuck brainfuck.c */ @@ -10,38 +11,47 @@ #define DATATYPE int -FILE * prog; +FILE *prog; + +char *code = NULL; + +DATATYPE *data = NULL; -char * code = NULL; -DATATYPE * data = NULL; -unsigned int * stack = NULL; +unsigned int *stack = NULL; + +unsigned int data_size = 30000; -unsigned int data_size = 30000; unsigned int stack_size = 128; char fmt = 'u'; -char format [9] = "%u"; -int trace = 0; + +char format[9] = "%u"; + +int trace = 0; unsigned int cp = 0; + unsigned int dp = 0; + unsigned int max_dp = 0; + unsigned int sp = 0; -char commands [] = "+-<>,.[]cioux"; +char commands[] = "+-<>,.[]cioux"; -void read_code() +void +read_code() { int allocated, n, c, comment; allocated = 1000; n = 0; - code = (char*) malloc(allocated * sizeof(char)); + code = (char *)malloc(allocated * sizeof(char)); comment = 0; while (EOF != (c = getc(prog))) { - if (c == ';') /* end of code */ + if (c == ';') /* end of code */ break; else if (c == '#') comment = 1; @@ -54,36 +64,39 @@ void read_code() if (n >= allocated) { allocated <<= 1; - code = (char*) realloc(code, allocated * sizeof(char)); + code = (char *)realloc(code, allocated * sizeof(char)); } - code[n++] = (char) c; + code[n++] = (char)c; } - + if (n >= allocated) { allocated <<= 1; - code = (char*) realloc(code, allocated * sizeof(char)); + code = (char *)realloc(code, allocated * sizeof(char)); } code[n++] = '\0'; } -void init_data() +void +init_data() { - data = (DATATYPE*) calloc(data_size, sizeof(DATATYPE)); + data = (DATATYPE *) calloc(data_size, sizeof(DATATYPE)); } -void init_stack() +void +init_stack() { - stack = (unsigned int*) malloc(stack_size); + stack = (unsigned int *)malloc(stack_size); } - -int inc_dp() +int +inc_dp() { if (dp < data_size) { ++dp; - if (dp > max_dp) max_dp = dp; + if (dp > max_dp) + max_dp = dp; return 1; } else @@ -93,7 +106,8 @@ int inc_dp() } } -void dec_dp() +void +dec_dp() { if (dp > 0) --dp; @@ -101,8 +115,8 @@ void dec_dp() fprintf(stderr, "Data underflow\n"); } - -void push_cp() +void +push_cp() { if (sp < stack_size) stack[sp++] = cp; @@ -110,7 +124,8 @@ void push_cp() fprintf(stderr, "Stack overflow\n"); } -void pop_cp() +void +pop_cp() { if (sp > 0) cp = stack[--sp]; @@ -118,68 +133,99 @@ void pop_cp() fprintf(stderr, "Stack underflow\n"); } -int skip() +int +skip() { int ob = 0; + while (code[cp] != '\0') { switch (code[cp]) { - case '[': ++ob; break; - case ']': --ob; if (0 == ob) return 1; + case '[': + ++ob; + break; + case ']': + --ob; + if (0 == ob) + return 1; } ++cp; } return 0; } - -void input() +void +input() { switch (fmt) { - case 'i': scanf(format, (signed int*) &(data[dp])); break; - case 'u': scanf(format, (unsigned int*) &(data[dp])); break; - case 'c': scanf(format, (char*) &(data[dp])); break; - case 'o': scanf(format, (unsigned int*) &(data[dp])); break; - case 'x': scanf(format, (unsigned int*) &(data[dp])); break; + case 'i': + scanf(format, (signed int *)&(data[dp])); + break; + case 'u': + scanf(format, (unsigned int *)&(data[dp])); + break; + case 'c': + scanf(format, (char *)&(data[dp])); + break; + case 'o': + scanf(format, (unsigned int *)&(data[dp])); + break; + case 'x': + scanf(format, (unsigned int *)&(data[dp])); + break; } } -void print_data() +void +print_data() { unsigned int i; + for (i = 0; i < dp; i++) { - fprintf(stderr, " "); - fprintf(stderr, format, data[i]); + printf(" "); + printf(format, data[i]); } - fprintf(stderr, " ["); - fprintf(stderr, format, data[dp]); - fprintf(stderr, "]"); + printf(" ["); + printf(format, data[dp]); + printf("]"); - for (i = dp+1; i <= max_dp; i++) + for (i = dp + 1; i <= max_dp; i++) { - fprintf(stderr, " "); - fprintf(stderr, format, data[i]); + printf(" "); + printf(format, data[i]); } - fprintf(stderr, "\n"); + printf("\n"); } -void switch_format() +void +switch_format() { switch (fmt) { - case 'i': sprintf(format, "%%%c", fmt); break; - case 'u': sprintf(format, "%%%c", fmt); break; - case 'c': sprintf(format, "%%%c", fmt); break; - case 'o': sprintf(format, "0%%%c", fmt); break; - case 'x': sprintf(format, "0x%%%c", fmt); break; + case 'i': + sprintf(format, "%%%c", fmt); + break; + case 'u': + sprintf(format, "%%%c", fmt); + break; + case 'c': + sprintf(format, "%%%c", fmt); + break; + case 'o': + sprintf(format, "0%%%c", fmt); + break; + case 'x': + sprintf(format, "0x%%%c", fmt); + break; } } -void run_code() +void +run_code() { char cmd; @@ -187,40 +233,61 @@ void run_code() { switch (cmd) { - case '[': if (data[dp]) - { - push_cp(); ++cp; - } - else - { - skip(); ++cp; - } - break; - case ']': pop_cp(); break; - case '+': ++(data[dp]); ++cp; break; - case '-': --(data[dp]); ++cp; break; - case '>': inc_dp(); ++cp; break; - case '<': dec_dp(); ++cp; break; - case '.': if (!trace) - { - printf(format, data[dp]); - if (fmt != 'c') - printf(" "); - } - ++cp; - break; - case ',': input(); ++cp; break; - - case 'i': - case 'u': - case 'c': - case 'o': - case 'x': - fmt = cmd; - switch_format(); - ++cp; - break; - default: ++cp; + case '[': + if (data[dp]) + { + push_cp(); + ++cp; + } + else + { + skip(); + ++cp; + } + break; + case ']': + pop_cp(); + break; + case '+': + ++(data[dp]); + ++cp; + break; + case '-': + --(data[dp]); + ++cp; + break; + case '>': + inc_dp(); + ++cp; + break; + case '<': + dec_dp(); + ++cp; + break; + case ',': + input(); + ++cp; + break; + case '.': + if (!trace) + { + printf(format, data[dp]); + if (fmt != 'c') + printf(" "); + } + ++cp; + break; + case 'i': + case 'u': + case 'c': + case 'o': + case 'x': + fmt = cmd; + switch_format(); + ++cp; + break; + default: + ++cp; } if (trace) { @@ -230,14 +297,19 @@ void run_code() } } -void free_all() +void +free_all() { - if (code != NULL) free(code); - if (data != NULL) free(data); - if (stack != NULL) free(stack); + if (code != NULL) + free(code); + if (data != NULL) + free(data); + if (stack != NULL) + free(stack); } -void usage(char * self) +void +usage(char *self) { printf("%s: Brainfuck programming language interpreter\n", self); printf("See <http://en.wikipedia.org/wiki/Brainfuck> for more details\n\n"); @@ -252,8 +324,10 @@ void usage(char * self) printf(" -t trace execution for debugging\n"); printf("\n"); printf("Formats for operators '.' and ',' (output and input):\n"); - printf(" -c, -i, -u, -o, -x char, signed int, unsigned int, octal, hexadecimal\n"); - printf(" octal number must be prepended by '0' (zero),\n"); + printf + (" -c, -i, -u, -o, -x char, signed int, unsigned int, octal, hexadecimal\n"); + printf + (" octal number must be prepended by '0' (zero),\n"); printf(" and hexadecimal - by '0x'\n"); printf("Default i/o format -%c\n", fmt); printf("\n"); @@ -264,9 +338,11 @@ void usage(char * self) printf("\n"); printf("Standard operators: <>+-[].,\n"); printf("Extensions:\n"); - printf(" ciuox - change i/o format (same as -c & others above)\n"); + printf + (" ciuox - change i/o format (same as -c & others above)\n"); printf(" ; - end of code (useful when reading stdin)\n"); - printf(" # - comment to the end of line (useful when reading files)\n"); + printf + (" # - comment to the end of line (useful when reading files)\n"); printf("\n"); printf("Examples:\n"); printf(" echo '+++[.-]' | %s # count down from 3 to 1\n", self); @@ -274,40 +350,46 @@ void usage(char * self) printf(" echo ',>,<[->+<]>.;4 5' | %s # shows 4+5=9\n", self); printf(" echo 'c,u.;h' | %s # shows 104 (ASCII code for 'h')\n", self); printf(" echo ', [-[->+<]>];4' | %s -t # move data pointer by 4 \n", self); - printf(" echo ',>,< [> [->+<] < -[->+<]> ]; 3 7' | %s -t # move '7' by 3 \n\n", self); + printf + (" echo ',>,< [> [->+<] < -[->+<]> ]; 3 7' | %s -t # move '7' by 3 \n\n", + self); exit(EXIT_SUCCESS); } -int main(int argc, char ** argv) +int +main(int argc, char **argv) { - char * filename; - char * self = argv[0]; + char *filename; + + char *self = argv[0]; + int opt; while (-1 != (opt = getopt(argc, argv, "ts:d:h?iucox"))) { - switch (opt) - { - case 's': - sscanf(optarg, "%u", &stack_size); - break; - case 'd': - sscanf(optarg, "%u", &data_size); - break; - case 't': - trace = 1; - break; - case 'i': - case 'u': - case 'c': - case 'o': - case 'x': - fmt = opt; - switch_format(); - break; - default: usage(self); - } + switch (opt) + { + case 's': + sscanf(optarg, "%u", &stack_size); + break; + case 'd': + sscanf(optarg, "%u", &data_size); + break; + case 't': + trace = 1; + break; + case 'i': + case 'u': + case 'c': + case 'o': + case 'x': + fmt = opt; + switch_format(); + break; + default: + usage(self); + } } if (optind < argc) @@ -315,7 +397,8 @@ int main(int argc, char ** argv) filename = argv[optind]; if (NULL == (prog = fopen(filename, "r"))) { - fprintf(stderr, "%s: open '%s': %s\n", self, filename, strerror(errno)); + fprintf(stderr, "%s: open '%s': %s\n", self, filename, + strerror(errno)); exit(EXIT_FAILURE); } } @@ -333,6 +416,5 @@ int main(int argc, char ** argv) run_code(); free_all(); - return 0; + return EXIT_SUCCESS; } - |