move interpter to own file
parent
64619f4325
commit
2670e34e25
|
@ -0,0 +1,245 @@
|
||||||
|
# pongff="/tmp/pongff"; [ ! -p "$pongff" ] && mkfifo "$pongff";
|
||||||
|
# rm -f /tmp/p; python3 bfponggen.py >/tmp/p.bf && python2.7 ~/bfc.py /tmp/p.bf && <"$pongff" ../pipevm.py | /tmp/p >"$pongff"
|
||||||
|
|
||||||
|
import struct
|
||||||
|
|
||||||
|
class BfGen():
|
||||||
|
def __init__(self, generators):
|
||||||
|
self.labels = {}
|
||||||
|
for i in range(len(generators)):
|
||||||
|
self.labels[generators[i][0]] = i
|
||||||
|
print(generators[i][1])
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
self.curPos = len(generators) - 9 # FIXME
|
||||||
|
|
||||||
|
def moveToPos(self, goalPos):
|
||||||
|
d = self.curPos - goalPos
|
||||||
|
self.curPos -= d
|
||||||
|
|
||||||
|
if d >= 0:
|
||||||
|
return "<" * d
|
||||||
|
|
||||||
|
return ">" * -d
|
||||||
|
|
||||||
|
def output(self, s):
|
||||||
|
result = ""
|
||||||
|
label = ""
|
||||||
|
|
||||||
|
for c in s:
|
||||||
|
if c in '[]<>{}+-.,':
|
||||||
|
if label:
|
||||||
|
label = label.strip()
|
||||||
|
v = self.moveToPos(self.labels[label])
|
||||||
|
result += v
|
||||||
|
label = ""
|
||||||
|
result += c
|
||||||
|
else:
|
||||||
|
label += c
|
||||||
|
|
||||||
|
if label:
|
||||||
|
label = label.strip()
|
||||||
|
v = self.moveToPos(self.labels[label])
|
||||||
|
result += v
|
||||||
|
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
generators = [
|
||||||
|
('00', ">"), # 0
|
||||||
|
('01', "+>"), # 1
|
||||||
|
('05', "+++++>"), # 5
|
||||||
|
('paddle_size', ">+++++[<++++++>-]"), # 30
|
||||||
|
('paddle_right_x', ">++++++++[<++++++++>-]"), # 64
|
||||||
|
('paddle_right_y', ">>+>+>+[+>++[-<+++>]<<]>-[-<+<+>>]"), # 103
|
||||||
|
('paddle_left_y', ""), # 103
|
||||||
|
('ball_x0', ""), # 0
|
||||||
|
('ball_x1', ">+>+>+++[+>+[-<++++>]<<]>>"), # 158
|
||||||
|
('ball_y0', ">"), # 0
|
||||||
|
('ball_y1', ">+++++++++[<+++++++++++++>-]"), # 117
|
||||||
|
('ff', ">+>+>+>+[++>[-<++++>]<<]>[-<+>]"), # 255
|
||||||
|
('device', "++++[>++++<-]>[<++++++++>-]<+>"), # 129
|
||||||
|
('f0', ">+>+>+>+[++>+[-<+++>]<<]>[-<+>]"), # 240
|
||||||
|
('ball_direction_x', ""), # 0 (left)
|
||||||
|
('ball_direction_y', ">"), # 0 (top)
|
||||||
|
('mem0', ""), # 0
|
||||||
|
('mem1', ""), # 0
|
||||||
|
('mem2', ""), # 0
|
||||||
|
('mem3', ""), # 0
|
||||||
|
('mem4', ""), # 0
|
||||||
|
('mem5', ""), # 0
|
||||||
|
('mem6', ""), # 0
|
||||||
|
('mem7', ""), # 0
|
||||||
|
]
|
||||||
|
|
||||||
|
bfgen = BfGen(generators)
|
||||||
|
|
||||||
|
bfgen.output("ff.device.")
|
||||||
|
|
||||||
|
# black screen # struct.pack(">BHHHHBBB", command, x, y, w, h, r, g, b)
|
||||||
|
# paddle_right_x starts with [320 (width) - 256 (overflow)], but will later have 10 subtracted from it
|
||||||
|
bfgen.output("05.00.00.00.00.01.paddle_right_x.00.f0.00.00.00.")
|
||||||
|
|
||||||
|
# we don't need to save "320" anymore, decrease by 10 so it can be used as paddle_right_x
|
||||||
|
bfgen.output("paddle_right_x----------")
|
||||||
|
|
||||||
|
# draw left paddle
|
||||||
|
bfgen.output("05.00.05.00.paddle_left_y.00.05.00.paddle_size.f0.f0.f0.")
|
||||||
|
|
||||||
|
# draw right paddle
|
||||||
|
bfgen.output("05.01.paddle_right_x.00.paddle_right_y.00.05.00.paddle_size.f0.f0.f0.")
|
||||||
|
|
||||||
|
bfgen.output("05")
|
||||||
|
|
||||||
|
bfgen.output("[") # main loop [
|
||||||
|
|
||||||
|
# delete ball
|
||||||
|
bfgen.output("05.ball_x0.ball_x1.ball_y0.ball_y1.00.05.00.05.00.00.00.")
|
||||||
|
|
||||||
|
# moves ball_x, handling over/underflow
|
||||||
|
bfgen.output("ball_direction_x[-mem0+mem1+ball_direction_x]mem1[-ball_direction_x+mem1]+ball_x1-----[-mem0+ball_x1]mem0+++[mem1-]>")
|
||||||
|
bfgen.output("[ball_y0+ball_x0[-ball_y0-ball_x0]ball_y0[-ball_x0+ball_y0]ball_x1+ball_x0[mem0+++++ball_x1-]>")
|
||||||
|
bfgen.output("[mem0-----ball_x1-ball_y0]mem1-mem2]")
|
||||||
|
bfgen.output("mem0---[-ball_x1+mem0]")
|
||||||
|
|
||||||
|
bfgen.output("ball_direction_y[-mem0+ball_y1+ball_direction_y]mem0[-ball_direction_y+mem0]ball_y1-----")
|
||||||
|
|
||||||
|
# reverse direction of ball_y if ball_y1 == 2
|
||||||
|
bfgen.output("ball_y1[-mem0+mem2+ball_y1]mem1+")
|
||||||
|
bfgen.output("mem2--[mem1-mem2[-]]")
|
||||||
|
bfgen.output("mem1[-ball_direction_y++++++++++mem1]")
|
||||||
|
bfgen.output("mem0[-ball_y1+mem0]")
|
||||||
|
|
||||||
|
# reverse direction of ball_y if ball_y1 == 237
|
||||||
|
bfgen.output("ball_y1[-mem0+mem2+ball_y1]mem1+")
|
||||||
|
bfgen.output("mem2+++++++++++++++++++[mem1-mem2[-]]")
|
||||||
|
bfgen.output("mem1[-ball_direction_y----------mem1]")
|
||||||
|
bfgen.output("mem0[-ball_y1+mem0]")
|
||||||
|
|
||||||
|
# check ball boundaries
|
||||||
|
# mem0 = ball_x0-ball_x1, using ball_y0 as a buffer
|
||||||
|
print("start boundaries check")
|
||||||
|
bfgen.output("ball_x0[-ball_y0+mem1+ball_x0]ball_y0[-ball_x0+ball_y0]")
|
||||||
|
bfgen.output("ball_x1[-ball_y0+mem5+ball_x1]ball_y0[-ball_x1+ball_y0]")
|
||||||
|
bfgen.output("mem1+mem5[-mem6+mem7+mem5]mem6[-mem3+mem6]")
|
||||||
|
print("check left boundary")
|
||||||
|
# if mem0 == 13, reached left boundary
|
||||||
|
bfgen.output("mem4+mem3-------------[mem4-]>")
|
||||||
|
|
||||||
|
# algorithm (done in debugger, not converted here) to
|
||||||
|
# bounce the ball if it hits the paddle or to reset
|
||||||
|
# ball_x and ball_y to the center otherwise
|
||||||
|
print("""
|
||||||
|
[
|
||||||
|
-
|
||||||
|
copy ball_y to mem3 and paddle_left_y to mem4
|
||||||
|
<<<<<<<<<<[-<+>>>>>>>>>>+<<<<<<<<<]<[->+<]
|
||||||
|
<<<[->>>+>>>>>>>>>>>+<<<<<<<<<<<<<<]>>>[-<<<+>>>]
|
||||||
|
>>>>>>>>>>
|
||||||
|
if mem3 ge mem4
|
||||||
|
[->-[>]<<]< (mem3 ends up = mem4 minus men3)
|
||||||
|
[
|
||||||
|
then if mem3 ge 31
|
||||||
|
>>>>+++++[<++++++>-]<+
|
||||||
|
<[->-[>]<<]<
|
||||||
|
[then just clean up ->]<
|
||||||
|
[else set mem0=1 ><<+>-]>
|
||||||
|
]
|
||||||
|
>>[-]<<<[-]+<
|
||||||
|
if mem0 eq 1 (ball hit left paddle)
|
||||||
|
[
|
||||||
|
then change direction of the ball
|
||||||
|
<<++++++++++>>-
|
||||||
|
>-]>
|
||||||
|
|
||||||
|
[< else reset ball_y
|
||||||
|
>>[-]>>[-]<<<<
|
||||||
|
<<<<<<[-]<<[-]
|
||||||
|
+>+++[++>++[-<++++++>]<<]> 117
|
||||||
|
[->+>+<<]
|
||||||
|
<++++++++++[->++++<]>+>[-<+>] 158
|
||||||
|
|
||||||
|
request a random char (ff 03 01 01 ff 01)
|
||||||
|
>>.>++.>>[-]+..<<<.>--.
|
||||||
|
>>->[-]>+>[-]>+>[-]>+>>
|
||||||
|
read random char (mem6) and set mem1 and mem2 to (mem6 % 4) (in binary)
|
||||||
|
,[
|
||||||
|
-
|
||||||
|
<<<<
|
||||||
|
[-[<[-<->]<[->+<]+>>-->]>>[-]]<[<]>[-]<<++
|
||||||
|
>>+>>
|
||||||
|
]<<-<<-<<->>
|
||||||
|
set the ball (x and y) directions based on mem1 and mem2
|
||||||
|
[-<<<++++++++++>>>]<[-<<<++++++++++>>>]
|
||||||
|
>
|
||||||
|
]
|
||||||
|
>>>
|
||||||
|
]
|
||||||
|
<<[-]<<[-]<
|
||||||
|
""")
|
||||||
|
|
||||||
|
bfgen.curPos = bfgen.labels["mem0"]
|
||||||
|
|
||||||
|
# now repeat the check for mem0 = 47 (+256=303) (reached right boundary)
|
||||||
|
bfgen.output("mem7[-mem0+mem7]")
|
||||||
|
bfgen.output("mem1+mem0-----------------------------------------------[mem1-]>")
|
||||||
|
bfgen.output("[ball_direction_x----------mem1-mem2]mem0[-]")
|
||||||
|
bfgen.output("mem1[-]mem2[-]mem3[-]")
|
||||||
|
print("end boundaries check")
|
||||||
|
|
||||||
|
# draw new ball
|
||||||
|
bfgen.output("05.ball_x0.ball_x1.ball_y0.ball_y1.00.05.00.05.f0.f0.00.")
|
||||||
|
|
||||||
|
print("move right paddle (computer)")
|
||||||
|
# move paddle_right_x
|
||||||
|
bfgen.output("mem0+ball_direction_x[") # if ball_direction_x != 0
|
||||||
|
|
||||||
|
bfgen.output("05.01.paddle_right_x.00.paddle_right_y.00.05.00.paddle_size.00.00.00.")
|
||||||
|
|
||||||
|
# use ball_y0 as buffer to copy ball_y1 to mem2 and paddle_right_y to mem3
|
||||||
|
bfgen.output("ball_y1[-ball_y0+mem2+ball_y1]ball_y0[-ball_y1+ball_y0]")
|
||||||
|
bfgen.output("paddle_right_y[-ball_y0+mem3+paddle_right_y]ball_y0[-paddle_right_y+ball_y0]")
|
||||||
|
# compare mem2 and mem3
|
||||||
|
bfgen.output("mem5+mem3+++++++++++++++mem2[-mem3-[mem4]mem2]mem5")
|
||||||
|
bfgen.curPos = bfgen.labels["mem4"]
|
||||||
|
bfgen.output("[-")
|
||||||
|
# mem2 >= mem3
|
||||||
|
bfgen.output("paddle_right_x-----mem3") # must be 1 position before paddle_right_y
|
||||||
|
bfgen.curPos = bfgen.labels["mem4"]
|
||||||
|
|
||||||
|
bfgen.output("]mem5")
|
||||||
|
|
||||||
|
# mem2 < mem3
|
||||||
|
bfgen.output("[-")
|
||||||
|
bfgen.output("paddle_right_y+++++mem5")
|
||||||
|
|
||||||
|
bfgen.output("]mem3[-]mem2[-]")
|
||||||
|
|
||||||
|
bfgen.output("05.01.paddle_right_x.00.paddle_right_y.00.05.00.paddle_size.f0.f0.f0.")
|
||||||
|
bfgen.output("mem0-ball_direction_x[mem1+ball_direction_x-]")
|
||||||
|
bfgen.output("]mem1[ball_direction_x+mem1-]mem0[-]")
|
||||||
|
|
||||||
|
print("move left paddle (user input)")
|
||||||
|
bfgen.output("ff.device+.-01.") # ff 02 01 (ff device command)
|
||||||
|
bfgen.output("mem0,") # read char
|
||||||
|
bfgen.output("mem0[,mem2+mem3+mem4+++[mem5[-mem4++++++mem5]mem3]") # if mem0 != 0, read another char and generate 115 ('s')
|
||||||
|
bfgen.curPos = bfgen.labels["mem1"]
|
||||||
|
bfgen.output("mem2[-mem0-mem2]mem1+mem0")
|
||||||
|
bfgen.output("[----[>-]mem1[mem3+++++mem5+mem1-mem2]mem1[-]]")
|
||||||
|
bfgen.output("mem2[mem5+++++>+<mem2->]mem0[-]]")
|
||||||
|
|
||||||
|
bfgen.output("ff.device.")
|
||||||
|
|
||||||
|
bfgen.output("mem5[05.00.05.00.paddle_left_y.00.05.00.paddle_size.00.00.00.mem5[-]]") # delete left paddle
|
||||||
|
bfgen.output("mem3[-paddle_left_y-mem2+mem3]") # paddle_left_y += mem3, set mem2
|
||||||
|
bfgen.output("mem4[-paddle_left_y+mem2+mem4]") # paddle_left_y -= mem4, set mem2
|
||||||
|
bfgen.output("mem2[05.00.05.00.paddle_left_y.00.05.00.paddle_size.f0.f0.f0.mem2[-]]") # redraw left paddle
|
||||||
|
|
||||||
|
# draw right paddle
|
||||||
|
bfgen.output("05.01.paddle_right_x.00.paddle_right_y.00.05.00.paddle_size.f0.f0.f0.")
|
||||||
|
|
||||||
|
# return to initial position of the loop
|
||||||
|
bfgen.output("05")
|
||||||
|
|
||||||
|
bfgen.output("]")
|
|
@ -1,2 +1 @@
|
||||||
~../hellobf.bf
|
|
||||||
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
|
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
|
|
@ -0,0 +1,88 @@
|
||||||
|
#pragma once
|
||||||
|
/*
|
||||||
|
* Created by Brett on 17/11/23.
|
||||||
|
* Licensed under GNU General Public License V3.0
|
||||||
|
* See LICENSE file for license detail
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BRAINFUCK_MISC_BF_INTERPRETER_H
|
||||||
|
#define BRAINFUCK_MISC_BF_INTERPRETER_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class brainfuck_interpreter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
size_t _size;
|
||||||
|
size_t _dp;
|
||||||
|
char* _data;
|
||||||
|
|
||||||
|
void check_size();
|
||||||
|
|
||||||
|
public:
|
||||||
|
brainfuck_interpreter(): _size(30000), _dp(0), _data(new char[_size])
|
||||||
|
{std::memset(_data, 0, _size);}
|
||||||
|
|
||||||
|
void increment_dp()
|
||||||
|
{
|
||||||
|
_dp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement_dp()
|
||||||
|
{
|
||||||
|
if (_dp != 0)
|
||||||
|
_dp--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
check_size();
|
||||||
|
_data[_dp]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
check_size();
|
||||||
|
_data[_dp]--;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OutStream>
|
||||||
|
void print(OutStream& stream)
|
||||||
|
{
|
||||||
|
stream << _data[_dp];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename InStream>
|
||||||
|
void read(InStream& stream)
|
||||||
|
{
|
||||||
|
_data[_dp] = stream.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
char is()
|
||||||
|
{
|
||||||
|
return _data[_dp];
|
||||||
|
}
|
||||||
|
|
||||||
|
~brainfuck_interpreter()
|
||||||
|
{ delete[] _data; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename functor>
|
||||||
|
static inline void match(functor f, int sp, size_t& index, const std::string& program)
|
||||||
|
{
|
||||||
|
while (f(index) < program.size())
|
||||||
|
{
|
||||||
|
if (program[index] == '[')
|
||||||
|
sp++;
|
||||||
|
if (program[index] == ']')
|
||||||
|
sp--;
|
||||||
|
if (sp == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void interpret_bf(const std::string& program);
|
||||||
|
|
||||||
|
#endif //BRAINFUCK_MISC_BF_INTERPRETER_H
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5472783bd7194cfc844da81bfa696e7761bd2047
|
Subproject commit fd9fa5454d47c60e41792c65beccf3988f3f2225
|
|
@ -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/).]
|
|
@ -0,0 +1,127 @@
|
||||||
|
>
|
||||||
|
+>
|
||||||
|
+++++>
|
||||||
|
>+++++[<++++++>-]
|
||||||
|
>++++++++[<++++++++>-]
|
||||||
|
>>+>+>+[+>++[-<+++>]<<]>-[-<+<+>>]
|
||||||
|
|
||||||
|
|
||||||
|
>+>+>+++[+>+[-<++++>]<<]>>
|
||||||
|
>
|
||||||
|
>+++++++++[<+++++++++++++>-]
|
||||||
|
>+>+>+>+[++>[-<++++>]<<]>[-<+>]
|
||||||
|
++++[>++++<-]>[<++++++++>-]<+>
|
||||||
|
>+>+>+>+[++>+[-<+++>]<<]>[-<+>]
|
||||||
|
|
||||||
|
>
|
||||||
|
<<<<.>.
|
||||||
|
<<<<<<<<<<.<<....>.>>>.<<<<.>>>>>>>>>>>>>.<<<<<<<<<<<<<...
|
||||||
|
>>>>----------
|
||||||
|
<<.<<.>>.<<.>>>>>>.<<<<<<.>>.<<.>>>.>>>>>>>>>>...
|
||||||
|
<<<<<<<<<<<.<.>>>.<<<<.>>>>>.<<<<<.>>.<<.>>>.>>>>>>>>>>...
|
||||||
|
<<<<<<<<<<<
|
||||||
|
[
|
||||||
|
.>>>>>.>.>.>.<<<<<<<<<<.>>.<<.>>.<<...
|
||||||
|
>>>>>>>>>>>>>>[->>+>+<<<]>>>[-<<<+>>>]+<<<<<<<<<-----[->>>>>>>>+<<<<<<<<]>>>>>>>>+++[>-]>
|
||||||
|
[<<<<<<<<+<<[->>-<<]>>[-<<+>>]<+<[>>>>>>>>>+++++<<<<<<<<-]>
|
||||||
|
[>>>>>>>>-----<<<<<<<<->]>>>>>>>>->]
|
||||||
|
<<---[-<<<<<<<<+>>>>>>>>]
|
||||||
|
<[->+<<<<<<+>>>>>]>[-<+>]<<<<<<-----
|
||||||
|
[->>>>>>+>>+<<<<<<<<]>>>>>>>+
|
||||||
|
>--[<->[-]]
|
||||||
|
<[-<<++++++++++>>]
|
||||||
|
<[-<<<<<<+>>>>>>]
|
||||||
|
<<<<<<[->>>>>>+>>+<<<<<<<<]>>>>>>>+
|
||||||
|
>+++++++++++++++++++[<->[-]]
|
||||||
|
<[-<<---------->>]
|
||||||
|
<[-<<<<<<+>>>>>>]
|
||||||
|
start boundaries check
|
||||||
|
<<<<<<<<<[->>+>>>>>>>>+<<<<<<<<<<]>>[-<<+>>]
|
||||||
|
<[->+>>>>>>>>>>>>+<<<<<<<<<<<<<]>[-<+>]
|
||||||
|
>>>>>>>>+>>>>[->+>+<<]>[-<<<+>>>]
|
||||||
|
check left boundary
|
||||||
|
<<+<-------------[>-]>
|
||||||
|
|
||||||
|
[
|
||||||
|
-
|
||||||
|
copy ball_y to mem3 and paddle_left_y to mem4
|
||||||
|
<<<<<<<<<<[-<+>>>>>>>>>>+<<<<<<<<<]<[->+<]
|
||||||
|
<<<[->>>+>>>>>>>>>>>+<<<<<<<<<<<<<<]>>>[-<<<+>>>]
|
||||||
|
>>>>>>>>>>
|
||||||
|
if mem3 ge mem4
|
||||||
|
[->-[>]<<]< (mem3 ends up = mem4 minus men3)
|
||||||
|
[
|
||||||
|
then if mem3 ge 31
|
||||||
|
>>>>+++++[<++++++>-]<+
|
||||||
|
<[->-[>]<<]<
|
||||||
|
[then just clean up ->]<
|
||||||
|
[else set mem0=1 ><<+>-]>
|
||||||
|
]
|
||||||
|
>>[-]<<<[-]+<
|
||||||
|
if mem0 eq 1 (ball hit left paddle)
|
||||||
|
[
|
||||||
|
then change direction of the ball
|
||||||
|
<<++++++++++>>-
|
||||||
|
>-]>
|
||||||
|
|
||||||
|
[< else reset ball_y
|
||||||
|
>>[-]>>[-]<<<<
|
||||||
|
<<<<<<[-]<<[-]
|
||||||
|
+>+++[++>++[-<++++++>]<<]> 117
|
||||||
|
[->+>+<<]
|
||||||
|
<++++++++++[->++++<]>+>[-<+>] 158
|
||||||
|
|
||||||
|
request a random char (ff 03 01 01 ff 01)
|
||||||
|
>>.>++.>>[-]+..<<<.>--.
|
||||||
|
>>->[-]>+>[-]>+>[-]>+>>
|
||||||
|
read random char (mem6) and set mem1 and mem2 to (mem6 % 4) (in binary)
|
||||||
|
,[
|
||||||
|
-
|
||||||
|
<<<<
|
||||||
|
[-[<[-<->]<[->+<]+>>-->]>>[-]]<[<]>[-]<<++
|
||||||
|
>>+>>
|
||||||
|
]<<-<<-<<->>
|
||||||
|
set the ball (x and y) directions based on mem1 and mem2
|
||||||
|
[-<<<++++++++++>>>]<[-<<<++++++++++>>>]
|
||||||
|
>
|
||||||
|
]
|
||||||
|
>>>
|
||||||
|
]
|
||||||
|
<<[-]<<[-]<
|
||||||
|
|
||||||
|
>>>>>>>[-<<<<<<<+>>>>>>>]
|
||||||
|
<<<<<<+<-----------------------------------------------[>-]>
|
||||||
|
[<<<---------->>>->]<<[-]
|
||||||
|
>[-]>[-]>[-]
|
||||||
|
end boundaries check
|
||||||
|
<<<<<<<<<<<<<<<<<.>>>>>.>.>.>.<<<<<<<<<<.>>.<<.>>.>>>>>>>>>>>..<<<<<<<<<<<<<.
|
||||||
|
move right paddle (computer)
|
||||||
|
>>>>>>>>>>>>>>>>+<<[
|
||||||
|
<<<<<<<<<<<<.<.>>>.<<<<.>>>>>.<<<<<.>>.<<.>>>.<<<...
|
||||||
|
>>>>>>>>>>[-<+>>>>>>>>>+<<<<<<<<]<[->+<]
|
||||||
|
<<<<[->>>>+>>>>>>>>>>+<<<<<<<<<<<<<<]>>>>[-<<<<+>>>>]
|
||||||
|
>>>>>>>>>>>>+<<+++++++++++++++<[->-[>]<<]>>>
|
||||||
|
[-
|
||||||
|
<<<<<<<<<<<<<<<<----->>>>>>>>>>>>>>>
|
||||||
|
]>
|
||||||
|
[-
|
||||||
|
<<<<<<<<<<<<<<<<+++++>>>>>>>>>>>>>>>>
|
||||||
|
]<<[-]<[-]
|
||||||
|
<<<<<<<<<<<<<<<<.<.>>>.<<<<.>>>>>.<<<<<.>>.<<.>>>.>>>>>>>>>>...
|
||||||
|
>>>-<<[>>>+<<<-]
|
||||||
|
]>>>[<<<+>>>-]<[-]
|
||||||
|
move left paddle (user input)
|
||||||
|
<<<<<.>+.-<<<<<<<<<<<.
|
||||||
|
>>>>>>>>>>>>>>>,
|
||||||
|
[,>>+>+>+++[>[-<++++++>]<<]
|
||||||
|
>[-<<->>]<+<
|
||||||
|
[----[>-]>[>>+++++>>+<<<<->]<[-]]
|
||||||
|
>[>>>+++++>+<<<<->]<<[-]]
|
||||||
|
<<<<<.>.
|
||||||
|
>>>>>>>>>[<<<<<<<<<<<<<<<<<<<.<<.>>.<<.>>>>>>.<<<<<<.>>.<<.>>>.<<<...>>>>>>>>>>>>>>>>>>>>>[-]]
|
||||||
|
<<[-<<<<<<<<<<<<<->>>>>>>>>>>>+>]
|
||||||
|
>[-<<<<<<<<<<<<<<+>>>>>>>>>>>>+>>]
|
||||||
|
<<[<<<<<<<<<<<<<<<<.<<.>>.<<.>>>>>>.<<<<<<.>>.<<.>>>.>>>>>>>>>>...>>>>>[-]]
|
||||||
|
<<<<<<<<<<<<<<<<.<.>>>.<<<<.>>>>>.<<<<<.>>.<<.>>>.>>>>>>>>>>...
|
||||||
|
<<<<<<<<<<<
|
||||||
|
]
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Created by Brett on 17/11/23.
|
||||||
|
* Licensed under GNU General Public License V3.0
|
||||||
|
* See LICENSE file for license detail
|
||||||
|
*/
|
||||||
|
#include <bf_interpreter.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void interpret_bf(const std::string& program)
|
||||||
|
{
|
||||||
|
brainfuck_interpreter fuck;
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
while (index < program.size())
|
||||||
|
{
|
||||||
|
auto c = program[index];
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '>':
|
||||||
|
fuck.increment_dp();
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
fuck.decrement_dp();
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
fuck.increment();
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
fuck.decrement();
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
fuck.print(std::cout);
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
fuck.read(std::cin);
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if (fuck.is() == 0)
|
||||||
|
match([](size_t& idx) { return ++idx; }, 1, index, program);
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
if (fuck.is() != 0)
|
||||||
|
match([](size_t& idx) { return --idx; }, -1, index, program);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void brainfuck_interpreter::check_size()
|
||||||
|
{
|
||||||
|
if (_dp >= _size)
|
||||||
|
{
|
||||||
|
char* tmp = new char[_size * 2];
|
||||||
|
std::memset(&tmp[_size], 0, _size);
|
||||||
|
std::memcpy(tmp, _data, _size);
|
||||||
|
_size = _size * 2;
|
||||||
|
delete[] _data;
|
||||||
|
_data = tmp;
|
||||||
|
}
|
||||||
|
}
|
121
src/main.cpp
121
src/main.cpp
|
@ -4,132 +4,17 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <blt/std/loader.h>
|
#include <blt/std/loader.h>
|
||||||
|
|
||||||
class brainfuck
|
#include <bf_interpreter.h>
|
||||||
{
|
|
||||||
private:
|
|
||||||
size_t _size;
|
|
||||||
size_t _dp;
|
|
||||||
char* _data;
|
|
||||||
|
|
||||||
void check_size()
|
|
||||||
{
|
|
||||||
if (_dp >= _size)
|
|
||||||
{
|
|
||||||
char* tmp = new char[_size * 2];
|
|
||||||
std::memset(&tmp[_size], 0, _size);
|
|
||||||
std::memcpy(tmp, _data, _size);
|
|
||||||
_size = _size * 2;
|
|
||||||
delete[] _data;
|
|
||||||
_data = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
brainfuck(): _size(2), _dp(0), _data(new char[_size])
|
|
||||||
{std::memset(_data, 0, _size);}
|
|
||||||
|
|
||||||
void increment_dp()
|
|
||||||
{
|
|
||||||
_dp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement_dp()
|
|
||||||
{
|
|
||||||
if (_dp != 0)
|
|
||||||
_dp--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
check_size();
|
|
||||||
_data[_dp]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement()
|
|
||||||
{
|
|
||||||
check_size();
|
|
||||||
_data[_dp]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print()
|
|
||||||
{
|
|
||||||
std::cout << _data[_dp];
|
|
||||||
}
|
|
||||||
|
|
||||||
void read()
|
|
||||||
{
|
|
||||||
std::cin >> _data[_dp];
|
|
||||||
}
|
|
||||||
|
|
||||||
char is()
|
|
||||||
{
|
|
||||||
return _data[_dp];
|
|
||||||
}
|
|
||||||
|
|
||||||
~brainfuck()
|
|
||||||
{ delete[] _data; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename functor>
|
|
||||||
void match(functor f, int sp, size_t& index, const std::string& program)
|
|
||||||
{
|
|
||||||
while (f(index) < program.size())
|
|
||||||
{
|
|
||||||
if (program[index] == '[')
|
|
||||||
sp++;
|
|
||||||
if (program[index] == ']')
|
|
||||||
sp--;
|
|
||||||
if (sp == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
std::string file{"../bf.bf"};
|
std::string file{"../life.bf"};
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
file = argv[1];
|
file = argv[1];
|
||||||
auto program = blt::fs::loadBrainFuckFile(file);
|
auto program = blt::fs::loadBrainFuckFile(file);
|
||||||
|
|
||||||
brainfuck fuck;
|
interpret_bf(program);
|
||||||
|
|
||||||
size_t index = 0;
|
|
||||||
while (index < program.size())
|
|
||||||
{
|
|
||||||
auto c = program[index];
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '>':
|
|
||||||
fuck.increment_dp();
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
fuck.decrement_dp();
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
fuck.increment();
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
fuck.decrement();
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
fuck.print();
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
fuck.read();
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
if (fuck.is() == 0)
|
|
||||||
match([](size_t& idx) { return ++idx; }, 1, index, program);
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
if (fuck.is() != 0)
|
|
||||||
match([](size_t& idx) { return --idx; }, -1, index, program);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue