feat: Import project state of 2011-11-13
This commit is contained in:
commit
19110ce03f
6 changed files with 247 additions and 0 deletions
96
bf_interpreter.c
Normal file
96
bf_interpreter.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <error.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static unsigned char *data_start;
|
||||||
|
static unsigned char *data_ptr;
|
||||||
|
|
||||||
|
void process_command(char command, FILE *file) {
|
||||||
|
|
||||||
|
switch(command) {
|
||||||
|
case '>':
|
||||||
|
/* increment the data pointer (to point to the next cell to the right). */
|
||||||
|
++data_ptr;
|
||||||
|
/* TODO : Check if over allocated memory */
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
/* decrement the data pointer (to point to the next cell to the left). */
|
||||||
|
--data_ptr;
|
||||||
|
/* TODO : Check if under allocated memory */
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
/* increment (increase by one) the byte at the data pointer. */
|
||||||
|
++*data_ptr;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
/* decrement (decrease by one) the byte at the data pointer. */
|
||||||
|
--*data_ptr;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
/* output a character, the ASCII value of which being the byte at the
|
||||||
|
* data pointer. */
|
||||||
|
putchar(*data_ptr);
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
/* accept one byte of input, storing its value in the byte at the data
|
||||||
|
* pointer. */
|
||||||
|
*data_ptr = getchar();
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
/* [ : if the byte at the data pointer is zero, then instead of moving the
|
||||||
|
* instruction pointer forward to the next command, jump it forward to
|
||||||
|
* the command after the matching ] command.
|
||||||
|
* ] : if the byte at the data pointer is nonzero, then instead of moving
|
||||||
|
* the instruction pointer forward to the next command, jump it back to
|
||||||
|
* the command after the matching [ command. */
|
||||||
|
{
|
||||||
|
fpos_t position;
|
||||||
|
fgetpos(file, &position);
|
||||||
|
while(*data_ptr != 0) {
|
||||||
|
fsetpos(file, &position);
|
||||||
|
char c = getc(file);
|
||||||
|
while( c!= ']' && c != EOF) {
|
||||||
|
process_command(c, file);
|
||||||
|
c = getc(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
/* if we encounter one here, it means there are not balanced */
|
||||||
|
fprintf(stderr, "Error in the source file, unbalanced ']'\n");
|
||||||
|
exit(2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Brainfuck ignores all characters except the eight commands +-<>[],. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
data_start = calloc(30000, sizeof(char));
|
||||||
|
data_ptr = data_start;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
char command;
|
||||||
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
fprintf(stderr, "Error: No such file %s\n", argv[1]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while((command = getc(file)) != EOF) {
|
||||||
|
process_command(command, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Usage: %s source_file\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
127
bf_threaded.c
Normal file
127
bf_threaded.c
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <error.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static unsigned char *data_start;
|
||||||
|
static unsigned char *data_ptr;
|
||||||
|
|
||||||
|
#define MEM_SIZE 30000
|
||||||
|
#define GOTO_NEXT goto *labels[op_char]
|
||||||
|
|
||||||
|
void engine_run(FILE* file) {
|
||||||
|
void** labels[127]; /* We will address each char */
|
||||||
|
unsigned char op_char = 0;
|
||||||
|
fpos_t* loop_start_position = calloc(3000,sizeof(fpos_t));
|
||||||
|
|
||||||
|
for (int i = 0; i <= 127; i++) labels[i] = &&unknown_char;
|
||||||
|
|
||||||
|
labels['>'] = &&ptr_increment;
|
||||||
|
labels['<'] = &&ptr_decrement;
|
||||||
|
|
||||||
|
labels['+'] = &&value_increment;
|
||||||
|
labels['-'] = &&value_decrement;
|
||||||
|
|
||||||
|
labels['.'] = &&value_output;
|
||||||
|
labels[','] = &&value_input;
|
||||||
|
|
||||||
|
labels['['] = &&loop_start;
|
||||||
|
labels[']'] = &&loop_end;
|
||||||
|
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
|
||||||
|
ptr_increment: {
|
||||||
|
if (data_ptr + 1 > data_start + MEM_SIZE) data_ptr = data_start;
|
||||||
|
++data_ptr;
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_decrement: {
|
||||||
|
if (data_ptr - 1 < data_start) data_ptr = data_start + MEM_SIZE;
|
||||||
|
--data_ptr;
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_increment: {
|
||||||
|
++*data_ptr;
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_decrement: {
|
||||||
|
--*data_ptr;
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_output: {
|
||||||
|
putchar(*data_ptr);
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
value_input: {
|
||||||
|
*data_ptr = getchar();
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_start: {
|
||||||
|
fgetpos(file, loop_start_position);
|
||||||
|
loop_start_position++;
|
||||||
|
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_end: {
|
||||||
|
if (*data_ptr != 0) {
|
||||||
|
fsetpos(file, loop_start_position-1);
|
||||||
|
} else {
|
||||||
|
loop_start_position--;
|
||||||
|
}
|
||||||
|
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
unknown_char: {
|
||||||
|
op_char = getc(file);
|
||||||
|
if (op_char > 127) return;
|
||||||
|
GOTO_NEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
data_start = calloc(MEM_SIZE, sizeof(char));
|
||||||
|
data_ptr = data_start;
|
||||||
|
|
||||||
|
if (argc <= 1) {
|
||||||
|
fprintf(stderr, "Usage: %s source_file\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
fprintf(stderr, "Error: No such file %s\n", argv[1]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine_run(file);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return 0;
|
||||||
|
}
|
1
examples/cat.bf
Normal file
1
examples/cat.bf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
,[.,]
|
1
examples/helloworld.bf
Normal file
1
examples/helloworld.bf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
|
21
examples/helloworld_comments.bf
Normal file
21
examples/helloworld_comments.bf
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
+++++ +++++ initialize counter (cell #0) to 10
|
||||||
|
[ use loop to set the next four cells to 70/100/30/10
|
||||||
|
> +++++ ++ add 7 to cell #1
|
||||||
|
> +++++ +++++ add 10 to cell #2
|
||||||
|
> +++ add 3 to cell #3
|
||||||
|
> + add 1 to cell #4
|
||||||
|
<<<< - decrement counter (cell #0)
|
||||||
|
]
|
||||||
|
> ++ . print 'H'
|
||||||
|
> + . print 'e'
|
||||||
|
+++++ ++ . print 'l'
|
||||||
|
. print 'l'
|
||||||
|
+++ . print 'o'
|
||||||
|
> ++ . print ' '
|
||||||
|
<< +++++ +++++ +++++ . print 'W'
|
||||||
|
> . print 'o'
|
||||||
|
+++ . print 'r'
|
||||||
|
----- - . print 'l'
|
||||||
|
----- --- . print 'd'
|
||||||
|
> + . print '!'
|
||||||
|
> . print '\n'
|
1
examples/uppercase.bf
Normal file
1
examples/uppercase.bf
Normal file
|
@ -0,0 +1 @@
|
||||||
|
,----------[----------------------.,----------]
|
Reference in a new issue