RASEL

From Esolang
Jump to navigation Jump to search
RASEL
Paradigm(s) imperative
Designed by User:Nakilon
Appeared in 2020
Type system rational
Memory system stack-based
Dimensions two-dimensional
Computational class Turing complete
Reference implementation Github
Influenced Befunge, Funge-98
File extension(s) .rasel


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.


Instructions

@ exit with code popped from the stack
0..9 A..Z 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
> < ^ v set instruction pointer direction
# "trampoline" -- the character under the next instruction pointer position will be ignored
j "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.

Examples

Hello, world!

A"!dlrow ,olleH">:?@,Hj

Cat program

~@,

Quine (11 chars)

<@,Yj5#?:,"

Factorial

1&\:?v:1-3\$/
     >$11\/.@

Nth Fibonacci number

1&-:?v1\:3\01\--1\
     >2\.@

Prime numbers generator

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.

Computational class

There is a translator from Brainfuck to RASEL written in Ruby.

Try it online

You can join the #esolangs IRC channel on Libera and ask bot to execute your RASEL code.