https://github.com/systemfw/befunge-93
Purely Functional, Final Tagless interpreter for the Befunge-93 esolang
https://github.com/systemfw/befunge-93
Last synced: about 1 year ago
JSON representation
Purely Functional, Final Tagless interpreter for the Befunge-93 esolang
- Host: GitHub
- URL: https://github.com/systemfw/befunge-93
- Owner: SystemFw
- Created: 2018-01-24T16:49:55.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2018-02-14T19:53:45.000Z (about 8 years ago)
- Last Synced: 2025-02-28T16:00:31.088Z (about 1 year ago)
- Language: Scala
- Homepage:
- Size: 29.3 KB
- Stars: 36
- Watchers: 4
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Befunge-93
A purely functional Befunge-93 interpreter, written in final tagless style.
Showcasing the beauty and power of compositional design.
## The interpreter
Given a Befunge-93 program, usually expressed as a multiline string
``` scala
val helloWorld =
"""
> v
v ,,,,,"Hello"<
>48*, v
v,,,,,,"World!"<
>25*,@
"""
```
you can run it to completion by calling `befunge.run(helloWorld)`, or
step through it in debug mode with `befunge.debug(helloWorld)`. Note
that both return a `cats.effect.IO]`, which describes their behaviour
in a purely functional manner. You can compose the `IO` computations
in a larger program, or, if you want to actually trigger their
execution because you are in `main` or in the `repl`, call
`.unsafeRunSync` on them.
The `befunge` object also contains some example programs for you to
try out.
## The language
Befunge-93 is a stack-based, reflective, bidimensional esoteric programming language.
The spec is [here](Befunge-93_spec.md)
A short table of the commands is as follows:
### Command Summary ###
COMMAND INITIAL STACK (bot->top)RESULT (STACK)
------- ------------- -----------------
+ (add)
- (subtract)
* (multiply)
/ (divide) (nb. integer)
% (modulo)
! (not) <0 if value non-zero, 1 otherwise>
` (greater) <1 if value1 > value2, 0 otherwise>
> (right) PC -> right
< (left) PC -> left
^ (up) PC -> up
v (down) PC -> down
? (random) PC -> right? left? up? down? ???
_ (horizontal if) PC->left if , else PC->right
| (vertical if) PC->up if , else PC->down
" (stringmode) Toggles 'stringmode'
: (dup)
\ (swap)
$ (pop) pops but does nothing
. (pop) outputs as integer
, (pop) outputs as ASCII
# (bridge) 'jumps' PC one farther; skips
over next command
g (get)
p (put) puts at (x,y)
& (input value)
~ (input character)
@ (end) ends program