Looks like the brainfuck is working. It can do a hello world program.
This commit is contained in:
parent
5b18849ddc
commit
38104f60f3
3 changed files with 78 additions and 4 deletions
|
@ -1,5 +1,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <fmt/color.h>
|
#include <fmt/color.h>
|
||||||
#include "game_engine.hpp"
|
#include "game_engine.hpp"
|
||||||
|
@ -51,6 +52,53 @@ Brainfucker::Brainfucker() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Just a jank way to use a counter to find
|
||||||
|
* the previous matching brace rather than
|
||||||
|
* using a stack. Should work for now.
|
||||||
|
*/
|
||||||
|
void Brainfucker::jump_forward() {
|
||||||
|
int counter = 1;
|
||||||
|
|
||||||
|
for(++ip; // when counter hits 0 we found it
|
||||||
|
counter > 0 && ip < code.size();
|
||||||
|
++ip)
|
||||||
|
{
|
||||||
|
char op = code.at(ip);
|
||||||
|
if(op == '[') {
|
||||||
|
// new branch so increment
|
||||||
|
++counter;
|
||||||
|
} else if(op == ']') {
|
||||||
|
// close branch so decrement
|
||||||
|
--counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++ip; // need to go 1 after
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same jank style of using a counter to
|
||||||
|
* jump back.
|
||||||
|
*/
|
||||||
|
void Brainfucker::jump_backward() {
|
||||||
|
int counter = 1;
|
||||||
|
|
||||||
|
for(--ip; // when counter hits 0 we found it
|
||||||
|
counter > 0 && ip > 0;
|
||||||
|
--ip)
|
||||||
|
{
|
||||||
|
char op = code.at(ip);
|
||||||
|
if(op == '[') {
|
||||||
|
// close branch so decrement
|
||||||
|
--counter;
|
||||||
|
} else if(op == ']') {
|
||||||
|
// new branch so increment
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Totally fragile but it seems to be working
|
* Totally fragile but it seems to be working
|
||||||
* enough to test the idea.
|
* enough to test the idea.
|
||||||
|
@ -67,17 +115,31 @@ void Brainfucker::run(int ticks) {
|
||||||
--dp;
|
--dp;
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
data[dp] = 1;
|
data[dp] = data[dp] + 1;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
data[dp] = 0;
|
data[dp] = data[dp] - 1;
|
||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
print("{}", data.at(dp));
|
cout << (char)data.at(dp);
|
||||||
break;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
print(ERROR, "Not implemented.\n");
|
print(ERROR, "Not implemented.\n");
|
||||||
break;
|
break;
|
||||||
|
case '[': {
|
||||||
|
// [ - if 0 jump to after ]
|
||||||
|
if(data.at(dp) == 0) {
|
||||||
|
jump_forward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ']': {
|
||||||
|
// ] if not 0 jump to after [
|
||||||
|
if(data.at(dp) != 0) {
|
||||||
|
jump_backward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print(ERROR, "Unknown operation {}\n", op);
|
print(ERROR, "Unknown operation {}\n", op);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ class Brainfucker {
|
||||||
void run(int count);
|
void run(int count);
|
||||||
void set_code(string &code);
|
void set_code(string &code);
|
||||||
void reset();
|
void reset();
|
||||||
|
void jump_backward();
|
||||||
|
void jump_forward();
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameEngine {
|
class GameEngine {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
#include "../game_engine.hpp"
|
#include "../game_engine.hpp"
|
||||||
|
|
||||||
TEST_CASE("brainfuck test", "[brainfuck]") {
|
TEST_CASE("basic brainfuck test", "[brainfuck]") {
|
||||||
Brainfucker bf;
|
Brainfucker bf;
|
||||||
string code{"+.>+.>+.>"};
|
string code{"+.>+.>+.>"};
|
||||||
|
|
||||||
|
@ -23,6 +23,16 @@ TEST_CASE("brainfuck test", "[brainfuck]") {
|
||||||
REQUIRE(bf.code.empty());
|
REQUIRE(bf.code.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("brainfuck loop test", "[brainfuck]") {
|
||||||
|
Brainfucker bf;
|
||||||
|
// this is a hello world program from wikipedia
|
||||||
|
string code{"++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."};
|
||||||
|
|
||||||
|
bf.set_code(code);
|
||||||
|
bf.run(code.size());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("game engine can start and take hit", "[brainfuck]") {
|
TEST_CASE("game engine can start and take hit", "[brainfuck]") {
|
||||||
// test fails on purpose right now
|
// test fails on purpose right now
|
||||||
GameEngine game{4};
|
GameEngine game{4};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue