Minimalist Joy language derivative.

Eric Bavier 7fbc7b7650 doc: Add programming guide to README. 7 gadi atpakaļ
Makefile 6704819bba Initial commit 7 gadi atpakaļ
README.md 7fbc7b7650 doc: Add programming guide to README. 7 gadi atpakaļ
build 0300fb70b7 Add simple build script. 7 gadi atpakaļ
mirth.c d70d954940 mirth: Fix "stack" and "unstack" operators. 7 gadi atpakaļ
prelude.mrth 6704819bba Initial commit 7 gadi atpakaļ

README.md

Mirth

A minimalistic interpreter for a Joy-like esoteric language.

Running

If you have a make installed, simply type make to build the executable. Otherwise you can run the ./build script. Then run ./mirth.

Programming in Mirth

Mirth programs consist of a sequences of ASCII characters and [- and ]-quoted sequences of characters (aka. "quotes").

Mirth passes intermediate computations on an implicit "data stack", much like Joy, Forth, and other stack-based languages. Operations may push values to the stack, pop values from the stack, reorder stack items, or a combination of the above.

Alphabetic characters in a program cause the ASCII codepoint of that character to be pushed to the top of the stack.

Digit characters in a program are recognized as such and cause the corresponding digit to be pushed to the data stack. Consecutive digits are treated as separate numbers. E.g. the input 123 causes first the number 1 to be pushed onto the stack, followed by the number 2, then the number 3.

Most of the ASCII symbol characters are "primitive" operators that perform some action, perhaps consuming values from or producing values on the stack. Some of these operators are overloaded: the specific action they perform depends on whether the stack items they operate on are integers or quotes.

Whitespace is insignificant and ignored in Mirth programs.

Stack operators

The value at the Top Of the Stack is referred to as "TOS", and the value Second On the Stack is referred to as "SOS".

  • $ duplicates the TOS ("dup")
  • > duplicates the SOS and pushes it on top ("over")
  • % discards the TOS ("drop"/"pop")
  • \ swaps the TOS and SOS ("swap")
  • ( pushes a quoted copy of the contents of the data stack. ("stack")
  • ) replaces the stack with the contents of the quoted TOS ("unstack")
  • @ reorders stack values according to quoted indices at TOS ("shuffle")

E.g.

13$
=> 1 3 3
13>
=> 1 3 1
13%
=> 1
13\
=> 3 1
13(
=> 1 3 [3 1]
hello[[world]])
=> [world]
helo[32110]@
=> o l l e h

The @ operator possibly needs some more explaining. It expects a quote at TOS that contains zero-based character indices, where the index 0 refers to the top of the stack and indices increase as you head towards the bottom of the stack. The maximum index indicates the extent of the shuffle operation, or how many stack items are dropped from the stack. Those stack items are replaced with the indexed stack items given in the list, where the front of the list becomes the TOS. E.g. the classic "rot" operation from Forth could be expressed as [201]@, and $ is equivalent to [00]@. The "nip" operation from Forth could be expressed as [20]@ assuming there is a stack item at index 2 to work with, but it could be better expressed as \%.

Arithmetic

Multi-digit integers must be formed on the stack using the primitive arithmetic primitives +, -, *, and / applied to two integers. E.g.

48*
=> 32
25*
=> 10
19+
=> 10
1356*$**+
=> 2701

Since there are many ways in which a single number can be represented in this way, Mirth encourages the programmer to express their own numeric individuality.

Note, however, that alphabetic character input causes the ASCII codepoint of that character to be pushed to the stack, so one could use those for inputing larger numbers if desired. E.g. d leaves 100 on top of the stack, which may be more intuitive than 455**, depending on how comfortable you are with ASCII codepoints.

Logic and Control Operators

In Mirth true is represented as the integer -1, and false as 0.

  • < pops TOS and SOS, pushes -1 if SOS is less than TOS, otherwise 0
  • = pops TOS and SOS, pushes -1 if SOS is equal to TOS, otherwise 0
  • ~ pops TOS, pushes the binary complement of TOS
  • ` pushes -1 if TOS is a quote ("quote?")

Quote manipulation

Some of the arithmetic and logic operators' behavior is overloaded when one of the operands is a quote:

  • + conses SOS onto the front of TOS, if TOS is a quote ("cons")
  • - pops TOS, pushes the first element of TOS, then the rest, if TOS is a quote ("uncons")
  • * concatenates SOS and TOS, if TOS is a quote, assuming SOS is a quote ("concat")
  • | pops TOS, pushes the reverse of TOS, if TOS is a quote ("reverse")

E.g.

h[ello]+
=>[hello]
[135][246]+
=>[[135]246]
[135]--
=>1 3 [5]
[0]-3\+
=>0 [3]
[hello][, world!]*
=>[hello, world!]
[12345]|
=>[54321]

Input and Output

  • , prints a quote as a flat sequence of characters, or prints the single character at TOS.
  • . prints TOS as a signed integer.
  • ^ pushes a single character read from standard input to the stack

E.g.

hello,,,,,
=|olleh
[hello, world!],
=|hello, world!
[digit: ],^68*-.
=|digit: 3

Recall from the "Arithmetic" section that multi-digit integers cannot be formed on the stack without performing arithmetic. However, "integers" can be printed using a quote without limitation, of course, since they're just interpreted as characters:

[2049],
=|2049

Limitations and Future Work

  • Currently Mirth has no garbage collection. Long running programs that use a lot of quotes and quote-manipulating operators may exhaust Mirth's fixed-size cons-pool.

  • One cannot currently enter a literal [] since the code interprets this synonymously with EOF. This should be fixed to that the ' operator can be repurposed, in favor of using []+ to effect a "unit" operation.

Mirth may have bugs. If you encounter any, please email the author.


Author: Eric Bavier bavier@member.fsf.org

License: GPL3+