-
Notifications
You must be signed in to change notification settings - Fork 0
/
README.bf
447 lines (351 loc) · 17.4 KB
/
README.bf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
[BF.STYLE---THE ULTIMATE STYLE GUIDE FOR BRAINFUCK CODE
It is often the case when cooperating on big projects in any
programming language, including Brainfuck, that code chaos leads to
product degradation. Spaghetti code is increasingly dangerous for big
projects, and absolutely disastrous when it's a high-stakes situation
typical to Brainfuck Enterprise Solutions, delivering a high-quality
Brainfuck-based products to the world of software.
It is only natural that style guidelines emerge in the circumstances
of cooperating on code. If there are no style guidelines, the code
becomes unmaintainable by spiraling into a collections of
inconsistent code snippets that no one admits the ownership of.
If there are style guidelines like bf.style, it's easy to enforce
high standards of enterprise-worthy code. The code is consistent
across products, projects, blocks, and lines of code. All the
developers can cooperate and have reasonable expectations from their
colleagues. Products thrive. Flowers bloom. Illnesses are cured. Life
is perfect.
[1 BRAINFUCK CODE STYLE
There are different levels of complexity to manage with style
guidelines in Brainfuck projects. The scopes for proper style are:
- Lines.
- Blocks (loops).
- Control structures.
- Functions.
- Programs/libraries.
Each of these scopes has its own emerging complexities that should
be managed in a certain specific way. Thus, bf.style is structured
around these scopes and their respective styles.
Linux kernel coding style
(https://www.kernel.org/doc/html/v4.10/process/coding-style.html)
UNIX philosophy, and common sense are taken as an inspiration for
the commandments in this guide.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
RFC 2119 (https://datatracker.ietf.org/doc/html/rfc2119).
[1.1 LINES
[1.1.1 EVERY LINE SHOULD DO ONLY ONE THING (AND, PREFERABLY, DO IT WELL)
Every line of Brainfuck code SHOULD do exactly one thing. There
MAY be any number of characters in Brainfuck code lines, but there
is a clear limit on how much a line SHOULD do: only one thing.
This "one thing" could be
- Copying a value or a set of values.
- Moving to a certain cell.
- Searching for a beacon cell.
- Cleaning a memory segment.
- And other operations that are clearly restricted in scope and
side effects.
If the action is compound, like "move to the cell and empty it",
it MAY occupy one line, but only if it concerns one cell or a set
of cells that are clearly delineated.
An embedded algorithm taken from an algorithm library (as in 1.5.2
and https://github.com/bf-enterprise-solutions/str.bf) MAY occupy
one line too, because, to the program in question, it is indeed a
single opaque action that this algorithm performs.]
[1.1.2 ALL LINES SHOULD BE EXHAUSTIVELY COMMENTED
Even though the line does only one thing, this one thing may still
be opaque and confusing for the colleagues of the programmer
writing the line in question. Thus, every line SHOULD be
commented. The comment SHOULD clearly state what this line does.
All the comments MUST conform to bf.doc
(https://github.com/bf-enterprise-solutions/bf.doc).]]
[1.2 BLOCKS (LOOPS)
Given the universal character of Brainfuck loops, they are used for
many purposes, be it conditional execution, looping, data copying,
search, and validation. Given these multi-faceted purposes, the
style may vary. For the purposes where loops become full-fledged
control structures, see section 1.3 of this guide.
[1.2.1 LOOP INDENTATION
All the code inside the loop body MUST be indented one space more
than the code outside the loop. Recursively, if there's a loop
inside another loop, the outer loop MUST be indented one space
more than the code outside it, and the inner loop MUST be indented
two spaces more than the outer code.
Both opening and closing brackets SHOULD be aligned with the code
outside the loop. If there are commands before the opening
bracket, it MAY shift. If the closing bracket has commands before
it, it MAY also shift. However, the code inside the loop, if it's
a multi-line one, MUST always be indented one space deeper than
the code outside the loop.
Examples:
[bf:
regular code indentation
[ loop
code inside the loop
] closing bracket
outer code again]
[bf:
regular code indentation
>+[ loop with commands preceding it
code inside the loop indented the same
<<] closing bracket with commands preceding it (indented)
outer code again]
Tabs are not permitted for indentation in Brainfuck code.
Blank lines MAY be indented with the current spacing depth, or
they MAY stay all blank, up to the code writer. format.bf decides
to not indent the blank lines in an effort to stay compatible with
many Brainfuck linters highlighting the trailing whitespace as an
error.
You can use the bundled format.bf script to format your programs.]
[1.2.2 IF-LOOPS
When the block of code is a one-pass loop that runs based on a
certain condition, we can call this loop an "if-loop",
"when-loop", or "conditional-loop".
"If-loops" MUST be written with the opening bracket on its own
line and the intent of the loop clearly stated in the comment. For
example:
[bf:
[if the string is not zero
[[-]>]] delete it]
Note that the closing bracket of the if-loop MAY compound with the
preceding commands/loops, as an exception from the general rule of
loop formatting. This is because the intent and scope of the loop
is expressed clearly enough in the opening comment, and need no
clarification in the closing one.
If the loop is small enough, then it MAY be compacted to a single
line, with the block comment preceding it on a line by itself:
[bf:
delete the string if nonzero:
[[[-]>]]]]
[1.2.3 ITERATION LOOPS
If the loop follows its original purpose and is an iteration loop,
akin to C for loop, then opening and closing comments MUST clearly
state this. Both brackets (the opening and the closing ones) MUST
stand on a line of their own. The opening comment SHOULD state the
purpose of the loop, while the closing one SHOULD state the
condition for iteration. For example:
[bf:
[ go through every character in the string
+ add one
> to the next char
] until the end of the string]
A type of C while loops replicated in Brainfuck SHOULD also have
their iteration condition clearly stated in the closing comment.]
[1.2.4 COPY LOOPS
These are usually simple enough to belong to lines, but may grow
into block loops, when
- the values and distances are big enough,
- when the copying is actually iterative or multiplicative,
- or when there are several values being copied, instead of one.
Such loops SHOULD be commented as a single block of code (see
section 2.2 of bf.doc for exact comment conventions) either above
it or as a part of the opening comment. Closing comments MAY be
omitted in such cases.]
[1.2.5 OTHER CASES
In most other cases, loops stay with the iteration, but perform
some function that's not easy to anticipate. In such a case the
sanest rule to adopt is the one customary for namespaces and
macros in C/C++ world. Which is: opening bracket and closing
bracket MUST stand on the lines of their own, and both SHOULD be
commented with the same text, like "character search loop", but
the closing one SHOULD have " ends" appended to the text. For
example:
[bf:
----- ----- test first char for newline
[ newline search loop
+++++ +++++ restore previous char
> next char
----- ----- test for newline
] newline search loop ends]]]
[1.3 CONTROL STRUCTURES
In any and every programming language, the tools for abstraction
are imperfect. Functions, conditions, iteration constructs,
aliases, and macros---all of those routinely betray programmers and
leave them barehanded against the grotesque logic of real-world
applications. Brainfuck is no exception to the rule. The
switch-case constructs, the with-patterns, the iterators that
Brainfuck programmer routinely writes are control structures that
deserve a name and a bit of respect.
[1.3.1 NAMING OF CONTROL STRUCTURES
Whether it's a C-style switch-case of a nested break-able loop, it
MUST be named clearly, either as a block comment above the
expression starting it, or as an opening bracket comment in case
it's a loop-based structure. The name SHOULD be concise and
referring to a construct on some other language/library familiar
to the programmer and their colleagues.]
[1.3.2 INNER STRUCTURE OF CONTROL STRUCTURES
Control structures are rarely well off with just a header
comment. In most languages, control structures have a certain
inner structure that gets reproduced in Brainfuck code
too. Python's with-patterns:
[python:
with expression [as variable]:
with-block]
or C switch-case statement:
[c:
switch (c) {
case 'a':
break;
case 'b'
return;
default:
break;}]
The elements of the control structure SHOULD be properly marked in
comments to the code that mimics their logic.]
As a general example of the two rules above, here's a code snippet
slightly adapted from one of the BES products:
[bf:
+> set the case flag
switch:
[ if exists
'1'
----- ...
[...]
< to case flag
[ case '1':
do something
]
> back to the tested char]]]
[1.4 FUNCTIONS
Functions are not first-class constructs in Brainfuck, but that
doesn't mean those are unused. See, for example, Daniel
B. Cristofani's tutorial on functions
(https://brainfuck.org/function_tutorial.b), showing the
state-of-art functional programming style of Brainfuck, with all
its axiomatic advantages.
It is RECOMMENDED to use the notation that Daniel B. Cristofani
suggested, as is mostly compliant with bf.doc and represents the
purpose of the functions well enough. In case the notation does not
align with bf.doc, bf.doc should be used as a definitive style.]
[1.5 PROGRAMS/LIBRARIES
Brainfuck programs belong to files with .bf extension. Every file
is a self-contained program (because Brainfuck has not and need not
file inclusion mechanism or multi-file packages).
Most of Brainfuck programs are written with a certain goal in mind:
- To make a working Brainfuck-based end user application.
- To create a drop-in embeddable library.
- To write a literate programming research notebook.
- Or a mixture of the three.
Based on these types of programs, the coding style differs.
[1.5.1 EXECUTABLE PROGRAMS
Executables usually benefit from the presence of the exit flag
that aborts the event loop or another control structure central to
the executable. The central control structure SHOULD be clearly
delineated.
[1.5.1.1 EVENT LOOPS PROGRAMS
Event loop-based executables are those that run indefinitely
until stopped by the user, and process the user-supplied data
(maybe even in several interactions).
Event loops usually tend to be exit flag-dispatching loops, thus
having clear means of exiting the program. Keyboard interrupts
may also be a way to exit from those, but SHOULD be used
cautiously, because they destroy the memory state formed around
the event loop, especially if the event loop executable is
embedded into another Brainfuck program.
The examples of event loop programs are:
- Text editors (like
https://github.com/bf-enterprise-solutions/ed.bf)
- REPL programs (like REPL executable in
https://github.com/bf-enterprise-solutions/meta.bf).
- Poll apps.
- Games.
- And most other user-interacting programs.
[1.5.1.1.1 MEMORY USE AND TERMINATION
The memory used by event loop programs SHOULD be, preferably,
cleaned up after the event loop terminates. Event loop itself
SHOULD terminate at the cell semantically equal (not necessarily
the same index-wise) to the one it started on.
In case the event loop is expected to process some data and
leave processing results as a return value (in such cases, a
batch-processing program may be a better use), the memory MAY
stay as it is, but working memory with intermediate computations
MUST nonetheless be cleared.
Memory segments and cells SHOULD have clear names and MAY provide
memory layout diagrams (as per section 2.4 of bf.doc) in the
accompanying documentation. It's RECOMMENDED to have as little
memory states as possible, because having too many memory states
obstructs proper memory debugging and application maintenance.]]
[1.5.1.2 BATCH PROCESSING PROGRAMS
Batch processing programs tend to be mostly user-agnostic
programs that operate on the provided (read-only/read-once) data
and return processing results either
- as data in memory, or
- as printed text.
Some classes of batch processing programs are:
- ASCII art programs.
- Halting mathematical computations.
- One-shot programs requiring user input only once (like the
bundled format.bf and minify.bf).
The discipline for those is simple:
- Memory state MUST be preserved as it was before the computation.
- In case the input is processed to the data in memory, return
data MAY be retained, while working data MUST be cleaned up.]
[1.5.1.3 NON-TERMINATING PROGRAMS
Non-terminating programs, like
- digits of Pi calculation,
- transcendental number e computation (http://brainfuck.org/e.b),
- random data generation,
- or any other non-halting computation
MAY never terminate unless by user interruption, thus memory
management rules applicable to other program types are not
applicable to these.
The only rule concerning non-terminating programs is: the
computation MUST be exhaustively explained and MAY be proven to
calculate the expected data.]]
[1.5.2 EMBEDDABLE LIBRARIES
Given that Brainfuck as a language and ecosystem possesses the
original, zero-cost means of abstraction in the form of text
copy-pasting, all the libraries should be optimized for ease of
clipboard use.
Which means: the memory layout of those MUST be exhaustively
documented, SHOULD be easy to setup, and SHOULD only consume as
much memory as actually needed by the computation.
Return values layout and contents MUST also be documented and
SHOULD be checked for proper termination. It is RECOMMENDED that
embeddable library algorithms preserve as much of original data as
it meaningfully can.
The algorithms themselves should be easy to copy and paste, which
means that they MAY omit the header comment loops and SHOULD stay
compact. The build system (possibly Makefile, as in meta.bf and
str.bf) MAY minify the files for greater convenience, but, even
without this minification, algorithms themselves SHOULD be concise
enough to occupy less than a screenful of lines (less than 25
lines) in the code that uses them.
minify.bf bundled with bf.style is a canonical minification
implementation, and any result of other minification approach
MUST match the output of minify.bf.
Good example of embeddable library compliant with bf.style is
str.bf (https://github.com/bf-enterprise-solutions/str.bf).]
[1.5.3 LITERATE NOTEBOOKS
In case of literate programming notebooks in Brainfuck (like
https://github.com/maksimKorzh/dbfi/blob/master/cgbfi.b%28commented%29),
the writing/programming style of the author is the biggest
authority, so literate notebooks MAY ignore any of the rules
above.
However, most of the comment conventions stay, and in these cases
literate notebook authors MAY refer to bf.doc
(https://github.com/bf-enterprise-solutions/bf.doc) for the
best-practice documentation and commentary solutions.
Some RECOMMENDATION to the authors of notebooks could be:
- Results of the computations MAY be printed for greater
debuggability of the notebooks and for the halting guarantees of
those.
- The blocks of code that the notebook comments SHOULD be
self-sufficient algorithms, so most of the style restrictions
applicable to embeddable libraries MAY be applied to the code
blocks in literate notebooks.]
In all the other (rare) cases where these categories (executable,
library, notebook) don't apply, all the conditions SHOULD be
carefully considered, and one of these three categories MUST be
picked after all.]]
[2 CODE STYLE FOR LANGUAGES OTHER THAN BRAINFUCK
Given that all the other languages used alongside Brainfuck are
inferior in regards to security and simplicity, their use MUST be
minimized at all costs.
In case of using any language other than Brainfuck, it SHOULD be
brought as close to Brainfuck as possible. Long variable names,
helper functions, and structural/functional/object-oriented
programming MUST be avoided to not interfere with the
straightforward structure of the Brainfuck code they try to
augment.]]