aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--brainfuck.c330
2 files changed, 215 insertions, 124 deletions
diff --git a/Makefile b/Makefile
index 02871ab..a11d880 100644
--- a/Makefile
+++ b/Makefile
@@ -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;
}
-