Monky

From Esolang
Jump to navigation Jump to search
This is still a work in progress. It may be changed in the future.

Monky is yet another stack-based language developed over the course of a weekend by User:Menguinponky.

Overview

It draws inspiration from FORTH and FALSE, it also uses a data stack and reverse polish notation and is tailored for fast execution by a simple interpreter on a DIY 8-bit machine, while keeping the syntax somewhat readable.

  • All values on the stack are 8-bit
  • All keywords are single special characters
  • Numeric literals are signed 8-bit integers
  • ASCII chars and strings can also be pushed onto the stack
  • Input tokens are separated by spaces
  • Extra whitespaces and newline characters are ignored
  • Stack underflow will terminate the program
  • Named variables can be used through the letters a-z
  • An additional 128 byte data array is available
  • Subroutines can be defined and called using letters A-Z
  • Recursive function calls are not supported

Characteristics

Note that although most instructions in the table below have familiar equivalents in their predecessor languages, there are some important differences:

The comparison operations only consume the top item and leave the previous value on the stack, also the symbols for less < and greater > point to the mathematically correct direction, relative to the top value. It is often necessary to compare a value to a range of other values, for example in a switch/case structure, keeping the previous value on the stack easily allows that without having to duplicate it for every comparison.

Neither the instruction to print the top value as an integer . nor the instruction to store the top value into a variable : consume the top value, but the instruction to print the top as char , does consume it. Chars are most likely to be printed and will therefor be popped from the stack while integers stay there for further calculation.

The logical value false is represented by 0 while true is nominally represented by -1, so that the ~ instruction can be used for logical inversion, though all non-zero values are interpreted as true.

The instruction character choices are supposed to make the symbols more intuitive to understand:

$ looks like an S for swap

^ is above or over the other tokens

% shows two identical elements after duplication by dup

_ symbolizes the floor that we drop an item to

\ points back towards a value down in the stack to pick

Syntax

Stack effect notation, with the top to the right: (stack before execution -- stack after execution, C syntax)

Example notation: Input → Stack after execution ⇒ Output

Op Name Stack effect Meaning Example
n push int (-- n) Push signed integer value onto stack 1 → 1
c push char (-- c) Push ASCII character onto stack a → a
. put int (n -- n) Print top of stack as signed integer 3 . → 3 ⇒ 3
, pop char (c --) Pop top of stack and print as ASCII character a , → ⇒ a
' get char (-- c) Get char from user input and push onto stack, 0 if none ' → c
_ drop (n --) Pop and discard top of stack 2 3 _ → 2
+ add (n1 n2 -- n1+n2) Add two top items of stack 1 2 + → 3
- sub (n1 n2 -- n1-n2) Subtract top from previous item 3 1 - → 2
* mul (n1 n2 -- n1*n2) Multiply two top items 2 3 * → 6
/ div (n1 n2 -- n1/n2) Integer divide previous item by top 6 2 / → 3
% dup (n -- n n) Duplicate top of stack 3 % → 3 3
$ swap (n1 n2 -- n2 n1) Swap two top items 1 2 $ → 2 1
^ over (n1 n2 -- n1 n2 n1) Copy previous item to top 1 2 ^ → 1 2 1
@ rot (n1 n2 n3 -- n2 n3 n1) Rotate three top items to the left 1 2 3 @ → 2 3 1
\ pick (n2 n1 n0 i -- n2 n1 n0 s[i]) Pick n-th element out of stack 1 2 3 4 3 \ → 1
& and (n1 n2 -- n1&n2) Bitwise AND two top items 12 10 & → 8
| or (n1 n2 -- n1|n2) Bitwise OR two top items 12 10 | → 14
# xor (n1 n2 -- n1^n2) Bitwise XOR two top items 12 10 # → 6
~ not (n -- ~n) Apply bitwise NOT to top item 127 ~ → -128
= equal (n1 n2 -- n1 n1==n2) Replace top by true if equal to previous, false if not 1 2 = → 1 0, 3 3 = → 3 -1
< less (n1 n2 -- n1 n2<n1) Replace top by true if smaller than previous, false if not 1 2 < → 1 0, 2 1 < → 2 -1
> greater (n1 n2 -- n1 n2>n1) Replace top by true if greater than previous, false if not 1 2 > → 1 -1, 2 1 > → 2 0
: store (n i -- n) Store top value in variable a-z or array index -1..-128 4 a : → 4, 5 -10 : → 5
; load (i -- v[i]) Load variable a-z or array index -1..-128 to top a ; → 4, -10 ; → 5
" string (-- 0 c..c) Push 0-terminated string onto stack in reverse order "hi" → 0 105 104


The following instructions are unique to Monky and don't affect the stack directly (n -- n):

Op Name Meaning Example
? skip if true Skip next instruction if top is true 0 ? % → 0 0 , 1 ? % → 1
! skip if false Skip next instruction if top is false 0 ! % → 0, 1 ! % → 1 1
[ loop start Start of a loop, ] jumps to this symbol [ a , ] ⇒ aaaaa...
] loop end End of a loop, jumps back to [ unless skipped 3 [ 1 - ! ] → 0
( block start Start of a block, jumps to ) unless skipped 3 ( 2 ) → 3, 0 ? ( 2 ) → 0
) block end End of a block, ( jumps here 1 ? ( 2 ) → 1 2

Examples

Infinite loop

[ ]

Cat program

[ ' ! , ]

Looping counter

0 [ 1 + . ]

Truth-machine

' 48 - ? ( [ . ] ) .

Fibonacci sequence

0 . 1 . [ ^ ^ + . @ _ ]

Hello, world!

"hellorld" [ , ! ]

Comment

( "comments may not contain brackets" )

mod(12,5)12 % 5 / 5 * - → 2

if(a==5){foo}else{bar};a ; 5 = ? ( foo ) ! ( bar )

i=5;do{printf("%d ",i--);}while(i);5 [ . 1 - ! ]

Note that blocks and loops are allowed to overlap, we can for example move a string from the stack to the data array like this:

"hello" -100 [ $ ^ : ? ( _ 1 + ] )

Interpreter

An interpreter is under development and can be found in a public GitHub repository: https://github.com/0xCAFEAFFE/Monky

Missing Features

The language does not allow recursive function calls, this is by design because these structures are rarely really necessary in practical programs. The interpreter does not support nested loops or nested blocks but work is in progress to make that happen. An interactive / edit mode is also planned.