SkillAgentSearch skills...

Flobnar

MIRROR of https://codeberg.org/catseye/Flobnar : This is what happens when you get Befunge-93 drunk

Install / Use

/learn @catseye/Flobnar
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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

View on GitHub
GitHub Stars12
CategoryDevelopment
Updated6mo ago
Forks2

Languages

Haskell

Security Score

72/100

Audited on Sep 20, 2025

No findings