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 <blt/std/loader.h>
|
||||
|
||||
class brainfuck
|
||||
{
|
||||
private:
|
||||
size_t _size;
|
||||
size_t _dp;
|
||||
char* _data;
|
||||
#include <bf_interpreter.h>
|
||||
|
||||
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)
|
||||
{
|
||||
std::string file{"../bf.bf"};
|
||||
std::string file{"../life.bf"};
|
||||
if (argc > 1)
|
||||
file = argv[1];
|
||||
auto program = blt::fs::loadBrainFuckFile(file);
|
||||
|
||||
brainfuck 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();
|
||||
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++;
|
||||
}
|
||||
interpret_bf(program);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue