Flobnar
MIRROR of https://codeberg.org/catseye/Flobnar : This is what happens when you get Befunge-93 drunk
Install / Use
/learn @catseye/FlobnarREADME
Flobnar
Version 0.1, Chris Pressey, Oct 28 2011
One day in September of 2011 -- though I'm not sure precisely which one -- marked Befunge-93's 18th birthday. That means that Befunge is now old enough to drink in its native land of Canada.
To celebrate this, I thought I'd get Befunge-93 drunk to see what would happen.
What happened was Flobnar, an esolang which is in many respects a functional dual of Befunge-93; most of the symbols have analogous meanings, but execution proceeds in a much more dataflow-like fashion.
This document describes Flobnar with a series of examples, presented in the format of Falderal 0.7 tests.
Concepts
A familiarity with Befunge-93 is assumed in this document. Also, some concepts need to be explained before the description of the examples will make much sense.
Like Befunge-93, Flobnar programs are held in a playfield -- a two-dimensional Cartesian grid of cells, each of which contains a symbol.
Any cell in a Flobnar playfield may be evaluated. The meaning of the evaluation of a cell depends on the symbol it contains. In the context of execution, this symbol is called a term.
Except for the first term to be evaluated, all terms are "evaluated from" one of the four cardinal directions: north, south, east, and west. The direction provides context: a term may evaluate to a different value depending on what direction it is evaluated from.
When we say something about "what the cell to the /d/ evaluates to", where /d/ is a direction, it is implied that that cell is evaluated from the direction opposite to /d/. So, "what the cell to the north evaluates to" means "what the cell to the north evaluates to, when evaluated from the south."
In addition, when we say "what the cell on the other side evaluates to", we mean this to be relative to the direction the current term was evaluated from. So, if the term was evaluated from the east, the "cell on the other side" refers to the cell to the west, as evaluated from the east.
Flobnar is not a purely functional language; it permits input and output, as well as self-modification, just like Befunge-93 does. For this reason, order of evaluation should be completely defined.
Flobnar Tests
-> Tests for functionality "Interpret Flobnar program"
-> Functionality "Interpret Flobnar program" is implemented by
-> shell command
-> "bin/flobnar %(test-body-file)"
Basics of Execution
Whereas in Befunge-93 @ indicates a stopping point of the program,
in Flobnar, @ indicates the starting point. The program evaluates
to whatever the @ it contains evaluates to. The @ evaluates to
whatever is west of it evaluates to.
| 4@
= Result: 4
The program must contain one and only one @.
| 4
? Program does not contain exactly one @
| 4@@
? Program does not contain exactly one @
Simple Constant Data
As in Befunge-93, single digits evaluate to the common decimal interpretation of themselves as numbers. You've already seen this for 4, but it's true for all of them.
| 0@
= Result: 0
| 1@
= Result: 1
| 2@
= Result: 2
| 3@
= Result: 3
| 5@
= Result: 5
| 6@
= Result: 6
| 7@
= Result: 7
| 8@
= Result: 8
| 9@
= Result: 9
Playfield Traversal
Whereas in Befunge-93 ><^v change the direction of the motion
of the IP, in Flobnar these characters evaluate to what the
appropriate adjacent cell evaluates to:
< evaluates to whatever is west of it evaluates to
> evaluates to whatever is east of it evaluates to
v evaluates to whatever is south of it evaluates to
^ evaluates to whatever is north of it evaluates to
| 4<<<<<@
= Result: 4
| >>>>>v
| ^ v
| ^ 4
| ^<<<<@
= Result: 4
Also, ' ' (blank space) evaluates to whatever the cell on the other side of it evaluates to. So, for example, if evaluated from the south, it evaluates to what the north of it evaluates to.
| 4 @
= Result: 4
| > v
|
| 4
| ^ @
= Result: 4
Cells which are not specified are considered to contain blank space. (In the example below, the two middle lines have nothing in them, not even blank space.)
| v@
|
|
| 4 <
= Result: 4
Like Befunge-93, there is toroidal wrapping of evaluation: if we try to evaluate something outside the bounds of the playfield, we end up evaluating whatever is directly on the other side of the playfield. Unlike Befunge-93, however, the bounds of the playfield are determined solely by the minimal bounding box that encompasses all the non-' ' terms in the playfield.
| @4
= Result: 4
| v@
| < v
| ^<
| 4
= Result: 4
There's a "Bridge" term, similar to Befunge's # instruction. It
evaluates to whatever is one cell past the other side of it.
| 5 6#@
= Result: 5
| 7v @
| v8#<
| >#9 v
| >^
| ^ <
= Result: 7
And # is compatible with wrapping.
| #@ 56
= Result: 5
And we were serious when we said that thing about how the bounds of the playfield are computed.
|
| v @
| #< 17
|
= Result: 1
Arithmetic
The + term evaluates whatever is to the north of it, then evaluates
whatever is to the south of it, and evaluates to the sum of those
two resulting values.
| 5
| +@
| 7
= Result: 12
| 5<<
| +<<
| 7<< +<@
| 6<
= Result: 18
The * term evaluates whatever is to the north of it, then evaluates
whatever is to the south of it, and evaluates to the product of those
two resulting values.
| 5
| *@
| 7
= Result: 35
The - term evaluates whatever is to the north of it (and we call that
/a/), then evaluates whatever is to the south of it (and we call that /b/).
It evaluates to the difference, /a/ - /b/.
| 7
| -@
| 5
= Result: 2
Subtraction resulting in a negative value.
| 1
| -@
| 9
= Result: -8
The / term evaluates whatever is to the north of it (and we call that
/a/), then evaluates whatever is to the south of it (and we call that /b/).
It evaluates to the quotient of dividing /a/ by /b/.
| 8
| /@
| 2
= Result: 4
Integer division rounds down.
| 9
| /@
| 2
= Result: 4
Division by zero evaluates to whatever the cell on the other side
of the / term evaluates to.
| 9
| 7/@
| 0
= Result: 7
| v9#@
| >/7
| 0
= Result: 7
The % term evaluates whatever is to the north of it (and we call that
/a/), then evaluates whatever is to the south of it (and we call that /b/).
It evaluates to the remainder of dividing /a/ by /b/. This operation is
called "modulo".
| 8
| %@
| 3
= Result: 2
Modulo of a negative value has the sign of the dividend.
| 7
| 0%@
| +<
| 3
= Result: 1
| 7
| 0%@
| -<
| 3
= Result: 1
Modulo by zero evaluates to whatever the cell on the other side evaluates to.
| 9
| 7%@
| 0
= Result: 7
| v9#@
| >%7
| 0
= Result: 7
Decision Making
'Horizontal if', denoted _, checks what the cell on the other side
of it evaluates to. If that value is nonzero, it evaluates to what
the cell west of it evaluates to; otherwise, it evaluates to what the
cell east of it evaluates to. In either case, at most two evaluations
are made.
| 0
| 5_9
| ^@
= Result: 9
| 7
|
| 5 _ 9
|
| ^@
= Result: 5
| v<
|
| 5 _ 9
|
| 7^@
= Result: 5
'Vertical if', denoted |, checks what the other side of it evaluates to.
If that value is nonzero, it evaluates to what the cell north of it
evaluates to; otherwise, it evaluates to what the cell south of it
evaluates to. In either case, at most two evaluations are made.
| 3
| 0|@
| 4
= Result: 4
| 3
|
| 9 | @
|
| 4
= Result: 3
| 3
| v @
| > | 9
|
| 4
= Result: 3
These "if"s can be used to evaluate a cell for its side-effects only. In the following, the sum is evaluated, but the result is effectively thrown out, in preference to the zero.
| 90 <
| +|@
| 9> ^
= Result: 0
Like Befunge-93, ! is logical negation: it evaluates to zero if the
cell on the other side evaluates to non-zero, and to one if the cell on
the other side evaluates to zero.
| 0!@
= Result: 1
| > v
| ^@ !
| 9
= Result: 0
We don't need greater than, because we can subtract one value from other, divide the result by itself (specifying a result of 0 if the division is by zero), then add one, and check if that is non-zero or not with a horizontal or vertical if.
But because Befunge-93 has it, we have it too. The <code>`</code> term evaluates whatever is to the north of it (and we call that /a/), then evaluates whatever is to the south of it (and we call that /b/). It evaluates to 1 if /a/ is greater than /b/, 0 otherwise.
| 8
| `@
| 7
= Result: 1
| 8
| `@
| 8
= Result: 0
| 8
| `@
| 9
= Result: 0
? picks one of the cardinal directions at random and evaluates
to whatever the cell in that direction evaluates to. ? should
use a fair distribution of the four possible choices, and should
be difficult to predict. We will not present this as a testable
example program, because the Falderal test framework doesn't
provide a way to test that, currently. (And it's not implemented
yet, but never mind that.) Instead, here is a plain example.
1
2?3#@
4
The above program should evaluate to 1 25% of the time, 2 25% of the time, 3 25% of the time, and 4 the rest of the time.
Introspection and Self-Modification
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
