diff --git a/src/main.cpp b/src/main.cpp index 14906c6..db45dd1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,70 +1,56 @@ #include #include +#include +#include -int main() +#define USAGE_RETURN_ERROR 1 +#define FILE_RETURN_ERROR 2 +#define RETURN_SUCCESS 1 + +void printUsage() +{ + std::cout << "Usage: bf " << std::endl; +} + +int main(int argc, char **argv) { BFMachine machine; - const char* instructions = - "[ This program prints \"Hello World!\" and a newline to the screen, its\n" - " length is 106 active command characters. [It is not the shortest.]\n" - "\n" - " This loop is an \"initial comment loop\", a simple way of adding a comment\n" - " to a BF program such that you don't have to worry about any command\n" - " characters. Any \".\", \",\", \"+\", \"-\", \"<\" and \">\" characters are simply\n" - " ignored, the \"[\" and \"]\" characters just have to be balanced. This\n" - " loop and the commands it contains are ignored because the current cell\n" - " defaults to a value of 0; the 0 value causes this loop to be skipped.\n" - "]\n" - "++++++++ Set Cell #0 to 8\n" - "[\n" - " >++++ Add 4 to Cell #1; this will always set Cell #1 to 4\n" - " [ as the cell will be cleared by the loop\n" - " >++ Add 2 to Cell #2\n" - " >+++ Add 3 to Cell #3\n" - " >+++ Add 3 to Cell #4\n" - " >+ Add 1 to Cell #5\n" - " <<<<- Decrement the loop counter in Cell #1\n" - " ] Loop until Cell #1 is zero; number of iterations is 4\n" - " >+ Add 1 to Cell #2\n" - " >+ Add 1 to Cell #3\n" - " >- Subtract 1 from Cell #4\n" - " >>+ Add 1 to Cell #6\n" - " [<] Move back to the first zero cell you find; this will\n" - " be Cell #1 which was cleared by the previous loop\n" - " <- Decrement the loop Counter in Cell #0\n" - "] Loop until Cell #0 is zero; number of iterations is 8\n" - "\n" - "The result of this is:\n" - "Cell no : 0 1 2 3 4 5 6\n" - "Contents: 0 0 72 104 88 32 8\n" - "Pointer : ^\n" - "\n" - ">>. Cell #2 has value 72 which is 'H'\n" - ">---. Subtract 3 from Cell #3 to get 101 which is 'e'\n" - "+++++++..+++. Likewise for 'llo' from Cell #3\n" - ">>. Cell #5 is 32 for the space\n" - "<-. Subtract 1 from Cell #4 for 87 to give a 'W'\n" - "<. Cell #3 was set to 'o' from the end of 'Hello'\n" - "+++.------.--------. Cell #3 for 'rl' and 'd'\n" - ">>+. Add 1 to Cell #5 gives us an exclamation point\n" - ">++. And finally a newline from Cell #6"; - machine.load(instructions); - int ret = machine.execute(); - if(ret != 0) + if(argc != 2) { - std::cout << "An error occurred. Error is: "; - switch(ret) - { - case RETURN_INVALID_INSTRUCTION: - std::cout << "Invalid Instruction"; break; - case RETURN_INVALID_MEMORY_ADDRESS: - std::cout << "Invalid Memory Access"; break; - default: - std::cout << "Unknown Error"; break; - } - std::cout << std::endl; - std::cout.flush(); + printUsage(); + return USAGE_RETURN_ERROR; + } + + char *filename = argv[1]; + std::ifstream file(filename); + if(file) + { + std::stringstream text; + text << file.rdbuf(); + file.close(); + + machine.load(text.str().c_str()); + int ret = machine.execute(); + if(ret != 0) + { + std::cout << "An error occurred. Error is: "; + switch(ret) + { + case BF_RETURN_INVALID_INSTRUCTION: + std::cout << "Invalid Instruction"; break; + case BF_RETURN_INVALID_MEMORY_ADDRESS: + std::cout << "Invalid Memory Access"; break; + default: + std::cout << "Unknown Error"; break; + } + std::cout << std::endl; + } + return ret; + } + else + { + std::cerr << "There was an error reading from the file." << std::endl; + return FILE_RETURN_ERROR; } - return ret; } diff --git a/test/hello.bf b/test/hello.bf new file mode 100644 index 0000000..1b8ceb3 --- /dev/null +++ b/test/hello.bf @@ -0,0 +1,43 @@ +[ This program prints "Hello World!" and a newline to the screen, its + length is 106 active command characters. [It is not the shortest.] + + This loop is an "initial comment loop", a simple way of adding a comment + to a BF program such that you don't have to worry about any command + characters. Any ".", ",", "+", "-", "<" and ">" characters are simply + ignored, the "[" and "]" characters just have to be balanced. This + loop and the commands it contains are ignored because the current cell + defaults to a value of 0; the 0 value causes this loop to be skipped. +] +++++++++ Set Cell #0 to 8 +[ + >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 + [ as the cell will be cleared by the loop + >++ Add 2 to Cell #2 + >+++ Add 3 to Cell #3 + >+++ Add 3 to Cell #4 + >+ Add 1 to Cell #5 + <<<<- Decrement the loop counter in Cell #1 + ] Loop until Cell #1 is zero; number of iterations is 4 + >+ Add 1 to Cell #2 + >+ Add 1 to Cell #3 + >- Subtract 1 from Cell #4 + >>+ Add 1 to Cell #6 + [<] Move back to the first zero cell you find; this will + be Cell #1 which was cleared by the previous loop + <- Decrement the loop Counter in Cell #0 +] Loop until Cell #0 is zero; number of iterations is 8 + +The result of this is: +Cell no : 0 1 2 3 4 5 6 +Contents: 0 0 72 104 88 32 8 +Pointer : ^ + +>>. Cell #2 has value 72 which is 'H' +>---. Subtract 3 from Cell #3 to get 101 which is 'e' ++++++++..+++. Likewise for 'llo' from Cell #3 +>>. Cell #5 is 32 for the space +<-. Subtract 1 from Cell #4 for 87 to give a 'W' +<. Cell #3 was set to 'o' from the end of 'Hello' ++++.------.--------. Cell #3 for 'rl' and 'd' +>>+. Add 1 to Cell #5 gives us an exclamation point +>++. And finally a newline from Cell #6 \ No newline at end of file diff --git a/test/life.bf b/test/life.bf new file mode 100644 index 0000000..e068233 --- /dev/null +++ b/test/life.bf @@ -0,0 +1,38 @@ +[life.b -- John Horton Conway's Game of Life +(c) 2021 Daniel B. Cristofani +http://brainfuck.org/] + +>>>->+>+++++>(++++++++++)[[>>>+<<<-]>+++++>+>>+[<<+>>>>>+<<<-]<-]>>>>[ + [>>>+>+<<<<-]+++>>+[<+>>>+>+<<<-]>>[>[[>>>+<<<-]<]<<++>+>>>>>>-]<- +]+++>+>[[-]<+<[>+++++++++++++++++<-]<+]>>[ + [+++++++++.-------->>>]+[-<<<]>>>[>>,----------[>]<]<<[ + <<<[ + >--[<->>+>-<<-]<[[>>>]+>-[+>>+>-]+[<<<]<-]>++>[<+>-] + >[[>>>]+[<<<]>>>-]+[->>>]<-[++>]>[------<]>+++[<<<]> + ]< + ]>[ + -[+>>+>-]+>>+>>>+>[<<<]>->+>[ + >[->+>+++>>++[>>>]+++<<<++<<<++[>>>]>>>]<<<[>[>>>]+>>>] + <<<<<<<[<<++<+[-<<<+]->++>>>++>>>++<<<<]<<<+[-<<<+]+>->>->> + ]<<+<<+<<<+<<-[+<+<<-]+<+[ + ->+>[-<-<<[<<<]>[>>[>>>]<<+<[<<<]>-]] + <[<[<[<<<]>+>>[>>>]<<-]<[<<<]]>>>->>>[>>>]+> + ]>+[-<<[-]<]-[ + [>>>]<[<<[<<<]>>>>>+>[>>>]<-]>>>[>[>>>]<<<<+>[<<<]>>-]> + ]<<<<<<[---<-----[-[-[<->>+++<+++++++[-]]]]<+<+]> + ]>> +] + +[This program simulates the Game of Life cellular automaton. + +It duplicates the interface of the classic program at +http://www.linusakesson.net/programming/brainfuck/index.php, +but this program was written from scratch. + +Type e.g. "be" to toggle the fifth cell in the second row, "q" to quit, +or a bare linefeed to advance one generation. + +Grid wraps toroidally. Board size in parentheses in first line (2-166 work). + +This program is licensed under a Creative Commons Attribution-ShareAlike 4.0 +International License (http://creativecommons.org/licenses/by-sa/4.0/).] diff --git a/test/tictactoe.bf b/test/tictactoe.bf new file mode 100644 index 0000000..b2d8fc7 --- /dev/null +++ b/test/tictactoe.bf @@ -0,0 +1,51 @@ +[tictactoe.b -- play tic-tac-toe +(c) 2020 Daniel B. Cristofani +http://brainfuck.org/ +This program is licensed under a Creative Commons Attribution-ShareAlike 4.0 +International License (http://creativecommons.org/licenses/by-sa/4.0/).] + +--->--->>>>->->->>>>>-->>>>>>>>>>>>>>>>>>+>>++++++++++[ + <<++[ + --<+<<+<<+>>>>[ + >[<->>+++>>[-]+++<<<+[<++>>+<--]]+>+++++[>>+++++++++<<-] + >>++++.[-]>>+[<<<<+>>+>>-]<<<<<<[>+<-]<< + ]++++++++++.[-]>++ + ]-->>[-->[-]>]<<[ + >>--[ + -[ + -[ + -----[>+>+++++++<<+]-->>-.----->,[<->-]<[[<]+[->>]<-]<[<<,[-]]>>>> + ]> + ]<[ + >-[+<+++]+<+++[+[---->]+<<<<<<[>>]<[-]] + >[<+[---->]++[<]<[>]>[[>]+>+++++++++<<-[<]]]>[>>>>] + ]<[ + -[[>+>+<<-]>[<+>-]++>+>>]<[<<++[-->>[-]]>[[-]>[<<+>>-]>]] + ]<[ + [[<<]-[>>]<+<-]>[-<+]<<[<<]-<[>[+>>]>[>]>[-]] + >[[+>>]<-->>[>]+>>>] + ]<[ + -[ + --[+<<<<--[+>[-]>[<<+>+>-]<<[>>+<<-]]++[>]] + <<[>+>+<<-]>--[<+>-]++>>> + ]<[<<<[-]+++>[-]>[<+>>>+<<-]+>>>] + ]<[ + +[[<]<<[<<]-<->>+>[>>]>[>]<-]+[-<+]<++[[>+<-]++<[<<->>+]<++]< + <<<<<< +> > >+> > >+[ + <<< ->+>+>+[ + <<<<<<< +>->+> > >->->+[ + <<<<< ->+>+> >+>+[ + <<<< ->->+>->+[ + <<<<<<<<+>-> >+> > >->+>+[ + <<<<< -> >+> >->+[ + <<<< +>->+> >+]]]]]]] + +++[[>+<-]<+++]--->>[-[<->-]<++>>]++[[<->-]>>]>[>] + ]< + ] + ]< +] + +[This program plays tic-tac-toe. I've given it the first move. It needs +interactive i/o, e.g. a command-line brainfuck interpreter or a brainfuck +compiler that produces command-line executables. At the '>' prompt, enter +the number of an empty space, followed by a linefeed, to play a move there.]