Added optparsing, updated readme
This commit is contained in:
40
README.md
40
README.md
@@ -7,6 +7,46 @@ A little brainfuck interpreter written in C.
|
|||||||
* Create your own brainfuck software
|
* Create your own brainfuck software
|
||||||
* ./bfckr "$yourstuff"
|
* ./bfckr "$yourstuff"
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
Usage: ./bfckr [OPTION] [FILE]
|
||||||
|
-h Show this help.
|
||||||
|
-d Enable debugger.
|
||||||
|
-f Execute brainfuck code given as file.
|
||||||
|
-e Execute brainfuck code given as argument.
|
||||||
|
|
||||||
|
## examples:
|
||||||
|
|
||||||
|
./bfckr -f examples/pi.bf
|
||||||
|
~~~~
|
||||||
|
3.14070455282885
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
./bfckr -d -f examples/pi.bf
|
||||||
|
~~~~
|
||||||
|
[ENTER]: single step [c]: continue
|
||||||
|
Source viewer:
|
||||||
|
------------------------------------------------------------
|
||||||
|
>+++++++++++++++[<+>>>>>>>>+++
|
||||||
|
^
|
||||||
|
ip=0
|
||||||
|
------------------------------------------------------------
|
||||||
|
|
||||||
|
Memory viewer:
|
||||||
|
------------------------------------------------------------
|
||||||
|
000 000 000 000 000 000 000 000 000 000 000 000 000 000 000
|
||||||
|
|
||||||
|
^
|
||||||
|
mp=1
|
||||||
|
000 000 000 000 000 000 001 002 003 004 005 006 007 008 009
|
||||||
|
------------------------------------------------------------
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Breakpoints
|
||||||
|
|
||||||
|
\# in the brainfuck source will be interpreted as breakpoints. You can use them if you want to stop the program flow at a specific point and start the debugger from there. If you are in debugger mode pressing c will get you back to executing the program.
|
||||||
|
|
||||||
# Licence
|
# Licence
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
55
bfckr.c
55
bfckr.c
@@ -10,9 +10,9 @@
|
|||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<errno.h>
|
#include<errno.h>
|
||||||
#include<assert.h>
|
|
||||||
#include<ctype.h>
|
#include<ctype.h>
|
||||||
#include<stdbool.h>
|
#include<stdbool.h>
|
||||||
|
#include<unistd.h>
|
||||||
|
|
||||||
// Defines
|
// Defines
|
||||||
#define MEMORY_SIZE 10000
|
#define MEMORY_SIZE 10000
|
||||||
@@ -35,6 +35,9 @@ void print_sourceviewer(bf_code_t *bf);
|
|||||||
void print_memoryviewer(bf_code_t *bf);
|
void print_memoryviewer(bf_code_t *bf);
|
||||||
void init_bf_object(bf_code_t *bf);
|
void init_bf_object(bf_code_t *bf);
|
||||||
bool is_brainfuck(char c);
|
bool is_brainfuck(char c);
|
||||||
|
int getopt(int argc, char * const argv[], const char *optstring);
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind, opterr, optopt;
|
||||||
|
|
||||||
/* initialize bf object */
|
/* initialize bf object */
|
||||||
void init_bf_object(bf_code_t *bf)
|
void init_bf_object(bf_code_t *bf)
|
||||||
@@ -54,7 +57,7 @@ void init_bf_object(bf_code_t *bf)
|
|||||||
|
|
||||||
bool is_brainfuck(char c)
|
bool is_brainfuck(char c)
|
||||||
{
|
{
|
||||||
return (c=='+') || (c=='-') || (c=='>') || (c=='<') || (c=='.') || (c==',') || (c=='[') || (c==']');
|
return (c=='+') || (c=='-') || (c=='>') || (c=='<') || (c=='.') || (c==',') || (c=='[') || (c==']' || (c=='#'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error handler */
|
/* Error handler */
|
||||||
@@ -82,8 +85,7 @@ void print_sourceviewer(bf_code_t *bf)
|
|||||||
putchar((i<0 || i>MAX_INPUT_SIZE) ? ' ' : bf->code[i]);
|
putchar((i<0 || i>MAX_INPUT_SIZE) ? ' ' : bf->code[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n ^ \n");
|
||||||
printf(" ^ \n");
|
|
||||||
printf(" ip=%d \n", ip);
|
printf(" ip=%d \n", ip);
|
||||||
printf("------------------------------------------------------------\n");
|
printf("------------------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
@@ -121,19 +123,19 @@ void bfuck_debugger(bf_code_t *bf) //char *bf_source_input, int instructionpoint
|
|||||||
{
|
{
|
||||||
clear(); // clear terminal
|
clear(); // clear terminal
|
||||||
|
|
||||||
printf("[s]: single step [c]: continue\n");
|
printf("[ENTER]: single step [c]: continue\n");
|
||||||
|
|
||||||
print_sourceviewer(bf);
|
print_sourceviewer(bf);
|
||||||
print_memoryviewer(bf);
|
print_memoryviewer(bf);
|
||||||
|
|
||||||
switch(getchar()) {
|
switch(getchar()) {
|
||||||
case 's':
|
|
||||||
// single step
|
|
||||||
break;
|
|
||||||
case 'c':
|
case 'c':
|
||||||
// continue
|
// continue
|
||||||
bf->debug = false;
|
bf->debug = false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// single step
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,39 +226,62 @@ void bfuck_execute(bf_code_t *bf)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bf->debug) {
|
||||||
bfuck_debugger(bf);
|
bfuck_debugger(bf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
// vars
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int c;
|
char c, option;
|
||||||
bf_code_t bf;
|
bf_code_t bf;
|
||||||
|
|
||||||
|
// initialize bf object
|
||||||
|
init_bf_object(&bf);
|
||||||
|
|
||||||
// check arguments
|
// check arguments
|
||||||
if(argc < 2) {
|
if(argc < 2) {
|
||||||
die("Need more arguments.");
|
die("Need more arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize bf object
|
// optparsing ahead
|
||||||
init_bf_object(&bf);
|
while((option = getopt(argc, argv, "hdef:")) >= 0) {
|
||||||
|
switch(option) {
|
||||||
|
case 'h': // show help
|
||||||
|
printf("Usage: %s [OPTION] [FILE]\n", argv[0]);
|
||||||
|
printf("-h\t Show this help.\n");
|
||||||
|
printf("-d\t Enable debugger.\n");
|
||||||
|
printf("-f\t Execute brainfuck code given as file.\n");
|
||||||
|
printf("-e\t Execute brainfuck code given as string.\n");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
break;
|
||||||
|
case 'e': // read input string
|
||||||
|
//printf ("Input code: \"%s\"\n", argv[2]);
|
||||||
|
sscanf(bf.code, "%s", argv[2]);
|
||||||
|
break;
|
||||||
|
case 'f': // file input
|
||||||
// try to open file
|
// try to open file
|
||||||
if((fp = fopen(argv[1], "rt")) == NULL) {
|
if((fp = fopen(optarg, "r")) == NULL) {
|
||||||
die("Couldn't open file.");
|
die("Couldn't open file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the file and store it in the input buffer
|
// read the file and store it in the input buffer
|
||||||
while((c = getc(fp)) != EOF) {
|
while((c = getc(fp)) != EOF) {
|
||||||
if(is_brainfuck(c)) {
|
if(is_brainfuck(c)) {
|
||||||
bf.code[i++] = c;
|
bf.code[i++] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// close file after reading
|
// close file after reading
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
break;
|
||||||
|
case 'd': // set to use debugger
|
||||||
|
bf.debug = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// try to interpret it
|
// try to interpret it
|
||||||
bfuck_execute(&bf);
|
bfuck_execute(&bf);
|
||||||
|
|||||||
Reference in New Issue
Block a user