|Computational class||Turing complete|
RASEL (Random Access Stack Esoteric Language) is a fungeoid esoteric programming language. The main goals of making another fungeoid were:
- to simplify implementation (compared to funge-98)
- to simplify specification (compared to both funge-98 and funge-93)
- to clarify specification (compared to both)
- to reduce the instruction set (19+digits compared to 26+digits in 93 and 52+digits in 98)
RASEL code is laid out on a two-dimensional, rectangular (and effectively toroidal) program space of instructions, each represented by a single ASCII character, lines separated by newlines. Unlike Befunge, RASEL is not self-modifying, that is, the instructions cannot change after the program is loaded. The additional ability of random access to the stack is added instead via the "swapn" -- modified `\` instruction that is now popping a depth parameter first. Stack data type is Rational while numerators and denominators are bignums. That means precision is limited only by the available memory of the host system, and there should be no rounding errors. Program space size also does not have any predefined limits and is calculated during the initial source code load.
||exit with code popped from the stack|
||push single Base36 digit value onto the stack|
||toggle "stringmode" (by default is off)|
||"discard" -- pop a value and do nothing with it|
||"duplicate" -- pop a value and add it back to the stack twice|
||set instruction pointer direction|
||"trampoline" -- the character under the next instruction pointer position will be ignored|
||"jump forward" -- pop a value from the stack and jump over that many cells in the current instruction pointer direction|
||pop two values and push the result of an arithmetic operation|
||"swapn" -- pop a value N and swap the top with N+1th|
||pop a value and print it as a number or a char of the corresponding ASCII code|
||read character from STDIN, put its ASCII code onto the stack and work as "trampoline" unless EOF|
||read Base10 non-negative integer from STDIN, put it onto the stack and work as "trampoline" unless EOF|
||"if positive" -- pop a value and work as "trampoline" if it's positive|
More detailed specification is on Github.
Quine (11 chars)
2:4v >1\1-\2-1\:.1\>\$01--# >::\:?^:3\1\%?v2-\1\:2\01-- >2- v
How do we check if the value is 0 if we have only the instruction that checks if it is positive?
The naive approach would be to check if it is not positive and then additionally negate the value and check again. Here we make a list of values -2, -1, 0, +1, +2 and then check them:
2-01-012 5> :?@1-1\ :?v$ v >01\-?vv ^ ,,,,,"true"A < ^ ,,,,,,"false"A <
$ rasel examples/naive_if_zero.rasel false false true false false
But we can apply the idea that if you multiply the negative value by itself it will become positive or just remain 0. Of course we don't have the "multiply" instruction but the "divide" effectively works the same for us (and it does not raise an error when we divide by 0):
2-01-012 5> :?@1-1\ :/?vv ^ ,,,,,"true"A < ^ ,,,,,,"false"A <
The check is now 3 times shorter.