Added optparsing, updated readme

This commit is contained in:
id101010
2016-11-15 03:53:42 +01:00
parent 4ca4a1389d
commit 4513d5e1d3
2 changed files with 90 additions and 25 deletions

View File

@@ -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
![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/logo-220x1601.png) ![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/logo-220x1601.png)

55
bfckr.c
View File

@@ -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);