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, FALSE and C, 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
  • All printable ASCII characters have a function
  • Numeric literals are signed 8-bit integers covering -128 to +127
  • Single characters 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
  • Functions can be defined and called using letters A-Z
  • An additional 128 byte data array is available

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 the letter S that swap starts with

^ is above or over the other tokens

% shows two circles after duplication by dup

_ symbolizes the floor that we drop an item to

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

@ symbolizes the rotation of the rot instruction

# is used to count the number of elements on the stack

Syntax

Stack effect notation, top of stack to the right:

stack before -- 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
. print int n -- n Print top of stack as signed integer 3 . → 3 ⇒ 3
, pop char c -- Pop and print top of stack 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
# count -- n Count and push number of elements on stack 4 5 6 # → 4 5 6 3
\ pick n2 n1 i -- n2 n1 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
~ 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
{ function start Start definition of a function { 1 + } I :
} function end End definition of a function { 1 - } D :

Examples

Infinite loop

[ ]

Cat program

[ ' , ]

Looping counter

0 [ 1 + . ]

Truth-machine

' 48 - ? ( [ . ] ) .

Fibonacci sequence

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

Hello, world!

"hellorld" [ , ! ]

Comment

( "this is a comment" )

Other examples:

modulo(12,5) → 12 % 5 / 5 * - → 2
if(a==5){foo}else{bar} → a ; 5 = ? ( foo ) ! ( bar )
i=5; do{print(i--)}while(i) → 5 [ . 1 - ! ]
i=5; while(i){print(i—-)} → 5 [ ? ( . 1 - ] )

Note that blocks and loops are allowed to overlap, like in the last example above.

Interpreter

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

Limitations

The language does not allow recursive function calls, this is by design because these structures are rarely indispensable in practical programs. The interpreter does currently not support nested loops or nested blocks but work is underway to implement that.