В прошлый раз данные на домашних ПеКа захренакались, настало время их расхренакать обратно с помощью квинтэссенции говнокода, обычно все хвалятся что пишут brainfuck
интерпретатор там в 200
байт, а то и меньше, но у инвалидов мозга типа меня своя олимпиада, поэтому размер интерпретатора 1200+ строк и 45+ килобайт весом. И это я ещё сократил, оставив попытки раскручивать циклы поняв что это глупая затея лишь тогда когда сделал действительно корректную раскрутку циклов во время исполнения через собственно генерацию раскрученных трасс циклов. Ну и ладно.
Собственно вот зачем интерпретатор
Для возможности непрерывно исполнять код который генерируется через Браинфакалка данных вашего ПеКа по мере его генерации , а не просто загрузить всё и потом выполнять.
Конечно Lua
не для этого и тормоза, но в режиме исполнения под Luajit
вполне себе терпимо
- https://www.youtube.com/watch?v=aqr2PlJh4Vw
mandelbrot.b
-10.9
s кодgolden.b
-0.25
s кодnahoi.b
-1.6
s код
Да, это в режиме тупой транcляции в Lua
код и его исполнения.
Всё вроде бы я наигрался, эксперимент закончен. Может кому надо, есть утилита и модуль который можно использовать самостоятельно, дебаг, трассировка исполнения, возможность отключать часть или все оптимизации, и запускать из под разных реализаций Lua
не через правку исходника, а через ключик. Всякая хрень с учётом типа конца строк EOL
,\r
,\r\n
,\n
и поведения окончания данных EOF
ибо некоторые браинфук программы хотят специфичных вещей.
Описание параметров
Usage: braintractor -i [FILE] -o [FILE]
braintractor -e ',+.+.+.+.+.+.+'
cat mandelbrot.bf | braintractor
Execute input brainfuck code with or without
different optimisations like transplitter to
lua code and execute him, repeated operations
optimisation and cycles jump optimisation.
Cheking brainfuck syntax is correct.
Handle debug symbol `#` and allow trace all code
in execution time with trace lua function.
This brainfuck language interpretor not very faster but flexibly.
Arguments:
-h --help This help information
- Execute brainfuck source code from stdin
-i [FILE] Execute filename with brainfuck source code
-e [TEXT] Execute brainfuck source code from string
-o [FILE] Output filename for write execution output
if output not set out writed to stdout
-fi [FILE] Send data to brainfuck programm from file
-si [TEXT] Send data to brainfuck programm from string
-dj Disable cycles jump optimisation
-dr Disable repeated operations optimisation
-dt Disable transplitter to lua optimisation
-dz Disable zero cell [+] [-] [<] [>] optimisations
-da Disable all optimisations
-ds Disable stream execution
-dl Disable set newline after terminal ouput
-dd Disable '#' symbol in brainfuck source code
-do Disable (force) any output (tracer worked)
-sb [NUMBER] Source buffer size for stream execution
minimum=1, maximum=2^31. (Default:100)
If posible braintractor execute this
chunks size or load more source code
-tr [TEXT] Lua function for trace brainfuck execution
-dn Disable check newline in input reader.
By default enabled checking '\n' if
input data ended but no have '\n' force
add this EOL LF symbol as last input symbol
this useful for varian set input as string
like -s 'someinput' -> 'someinput\n' you
can set other variant for EOL not '\n'
-l [TEXT] Select lua implementation for execute
lua5.1, lua5.2, lua5.3, lua5.4, luajit
By default used system '#!/usr/bin/env lua'
Some brainfuck programs expect different behavior for
end of line. Setting bottom transparent fix input for
different behavior end of line. LF , CR, CRLF. You can
enable only one variant. If set more last disable other
By default enabled -eof_lf if input no have '\n' in line end
force added '\n' in last input data. Use -dn for disable it
-eol_lf Enable check end of line and force set LF == '\n'
if input have '\r' or '\r\n' this option
change it to single '\n'. (nix way)
-eol_cr Enable check end of line and force set CR == '\r'
if input have '\n' or '\r\n' this option
change it to single '\r'. (old osx way)
-eol_crlf Enable check end of line and force set CRLF == '\r\n'
if input have '\n' or '\r' this option change
it to two end of line symbols '\r\n'. (windows way)
Some brainfuck programs expect different behavior for end of file
some expect write '0' in memory cell, some need save cell value
and skip write other value in cell and some needed write -1 in cell
Options bottom can enable one of varians. By default enabled -eol_zero
You can enable only one varian. If set more last disable other.
-eof_zero If no have data to read, write 0 in memory cell m[i]=0
-eof_eof If no have data to read, write -1 in memory cell m[i]=-1
-eof_skip if no have data save cell value m[i]=m[i] (it like clamp)
-eof_same same as -eof_skip, just alias, it's easier to remember :)
Notice about default execution mode and configuration:
By default execute source maked in strem mode, brainfuck
source load in small chunck, chunck optimised and executed
this makes it possible to execute code as it is received,
without waiting for it to be fully loaded. Also, this is
only possible if it is possible to isolate independent parts
from the flow that are not included in the body of any loop
You can set minimal buffer for load or disable stream mode
By default debug symbol '#' executed, you can disable it
No cell memory limit, you can use over 30000 cells
No memory position limit, brainfuck code can use
negative cell indexes. If you need check memory limit
or check index allowed ranges you can use tracer -tr
Notice about optimisations:
By default all optimisations is enabled.
You can disable some one or all. The more
you disable, the slower the code will run
Notice about input data variants:
If input data taked from PIPE and brainfuck
have read ',' command need use -fi or -si options
for send data in brainfuck reader ',' command.
If input data from file -i or string -e
brainfuck read from stdin. Imposible
use PIPE for load source code and for
take input for brainfuck code. Or or.
braintractor -e ',..' # ok - you take interactive input
braintractor -i code.b # ok - you take interactive input
echo ',..' | braintractor -fi /dev/tty # ok - you take interactive input
echo ',..' | braintractor -fi input.txt # ok - input from file
echo ',..' | braintractor -si 'a' # ok - input from string
echo ',..' | braintractor # error, stdin empty after PIPE
# need direct send input data
# need directly use -f or -s
About trace function:
If you set trace function, this function be executed
in brainfuck execution loop for any operations. But
if you no disable repeater optimisation -dr, tracer miss
some repeated operations, for example this code
'+++.+++' in tracer show 3 trace becouse +++ combine
to single '+' next one '.' and again single '+'
if you set -dr tracer show full 7 operations per symbol.
Example tracer:
c - brainfuck code symbol
i - brainfuck cell memory index
v - brainfuck cell memory value
r - repeated counter after operations or 1
p - source code position, depend of optimisations, set -da -ds for correct
-tr 'function(c,i,v,r,p) print(c,i,v,r,p) end'
For example you can disable output -do and all optimisations
and just use custom tracer debugger for you brainfuck code
For example check memory usage no more 10 cells, and check negative index
-tr 'function(_,i) if i > 10 then error('MEM OVERFLOW!') end end'
-tr 'function(_,i) if i < 0 then error('NEGATIVE INDEX!') end end'
Warning: tracer execute any lua code, ANY LUA CODE! This mean
you need set correct code, no use copypaste code from internet.
If tracer function incorrect this application crashed.
Код и документация тут:
Запускать можно прям из каталога, модуль подхватится который рядом лежит.
Локальные установка и удаление в $HOME/.local/
#Установка
make PREFIX=$HOME/.local install install-cli
#Удаление
make PREFIX=$HOME/.local uninstall uninstall-cli
Баги и чиcтка кода, оооой всё потом. Потому что нет времени очередная поделочка в процессе. Так и живём, тяп ляп и готово :)
Досвиданья.