~ruan_p/errless_docs

#Reference

<-- Tutorial || Contents || Turing Completeness Proof -->

#∘ Notes

This, and the language itself, is still heavily WIP. If something is missing from the reference, or an operation isn't defined, assume that the reference implementations are correct.

#Versioning

There are multiple ErrLess versions supported by this reference.

Integers must be signed, and they can contain a certain number of bits, or they can be unbounded. If integers are bounded, then they may overflow, or they may be truncated, as long as this behaviour is consistent. The implementation can either support any character encoding, but ASCII or Unicode is recommended. It should read the program, and any input in the chosen encoding, and also output in the chosen encoding.

This is how to version your implementation of ErrLess:

  • If it uses bigints, then follow it with Bigint, otherwise with i, followed by the number of bits in an integer.

  • If you do not use bigints and you let integers overflow/underflow, then add an o, if you truncate integers, add a t.

  • If your character encoding isn't ASCII, add the character encoding.

Reference Python implementation: ErrLess Bigint Unicode

Reference C++ implementation (I'm working on it): ErrLess i64o

#Data types

ErrLess supports two data types:

  • Integers

  • Stacks

    Stacks act like arrays or lists. They can contain nothing, integers, other stacks, or a combination if other stacks and integers.

  • Booleans

    Booleans are integers. 0 for false, and -1 for true (all bits 1). Booleans aren't really a data type, but rather a convention.

Also note that there is a function stack (?) that contains procedures and macros. This can be used to create pseudo-variables, through a macro that always pushes a certain value to the stack.

#Notation

To represent an integer I'll use a capital letter: N, M

To represent an integer or a stack I'll use a lowercase letter: x, y

To represent an empty stack I'll use (.).

To represent a stack containing something I'll use (x).

To represent a list of zero or more numbers/values I'll use N../x...

To represent N numbers/values I'll use M.N/x.N.

I'll represent the main stack like a normal stack, but without the brackets: . x etc

#Function Application

Functions marked with * expects numbers.

If a monadic function expects a number, but gets a stack, it returns the stack, but with the function applied to every element of the stack.

If a dyadic function expects two numbers, but

  • gets one stacks

    It applies it's numerical argument to each element of the stack.

  • gets two stacks

    It truncates the stacks to the same length and then applies it to the first elements of both stacks, then the second elements, then the third, etc.

#Running a program

The interpreter operates on the source of the program, and loops back to the start of the program when it reaches the end.

#∘ Operations

#Stack operations
  • Concatenate

    :

    Concatenates the top two elements in the stack. If either is not a stack, then make a stack containing both.

    (x..) (y..)(x.. y..)

    (x..) N((x..) N)

    N (y..)(N (y..))

    N M(N M)

  • Append

    x

    Appends the top element of the stack to the one below. If the second element is not a stack, then make a stack containing both.

    (x..) y(x.. y)

    N (y..)(N (y..))

    N M(N M)

  • Separate

    ;

    Takes everything out of the top stack and pushes it to the main stack. Doesn't do anything to single values.

    (x..)x..

    NN

  • Pop

    !

    Pops the top element off of the stack.

    x.

  • Duplicate

    @

    Duplicates the top element of the stack.

    xx x

  • Grab

    g

    Grabs hte Nth element from the top stack (0-indexed).

    (x.N y z..) N(x.N z..) y

  • Grab from stack

    G

    Grabs the Nth element from the stack (0-indexed).

    x.N y z.. Nx.N z.. y

  • Length

    l

    Returns the length of the top stack, return -1 for integers.

    (x.N)(x.N) N

  • Length of stack

    L

    Return the length of the stack.

    x.Nx.N N

  • Rotate

    r

    Gets two stacks, x and y_N. Then every element x[y_i] is moved to x[y_(i+1)], for every i where 0 ≤ i < N-1, and x[y_(N-1)] is moved to x[y_0]. Returns x. If an element is moved out of the stack's bounds, it is deleted, and fetching an element from out of the stack's bounds yields an empty stack.

    (1 2 3 4 5) (1 0 3 6)(2 (.) 3 1 5)

    (0 1 2 3 4 5 6 7) (1 0 3 6)(1 6 2 0 4 5 3 7)

  • Rotate stack

    R

    Same as r, but uses the entire stack for x.

    1 2 3 4 5 (1 0 3 6)2 (.) 3 1 5 0 1 2 3 4 5 6 7 (1 0 3 6)1 6 2 0 4 5 3 7

  • Nest

    ,

    Nests the top element of the stack in a stack. Equivalent to LGx or SSx.

    x(x)

  • Swap

    $

    Swaps the top two elements of the stack.

    a bb a

#Literals
  • Numbers

    0 - 9 & a - f

    Push the number to top of the stack.

    .N

  • Characters

    'c

    Push the character code of c onto the stack.

    .ord(c)

  • Strings

    S...S

    Push the characters between two S's onto the top of the stack. Cannot contain a capital S. No escape sequences.

    . [SHello, world!S] → (72 101 108 108 111 44 32 119 111 114 108 100 33)

    . [SS] → (.)

    . ['S,SeaS:] → 83(83)(83) (101 97)(83 101 97)

#Arythmatic & Other Operations
#Arythmatic

  • Add

    +*

    Add the top two elements in the stack together.

    N MN+M

  • Subtract

    -*

    Subtract the top element from the next.

    N MN-M

  • Negate

    _*

    Negate the top integer of the stack.

    N-N

  • Multiply

    **

    Multiply the top two elements of the stack.

    N MN×M

  • Divide

    /*

    Divide the top two elements of the stack. Use integer division, return zero when dividing by zero.

    N MN÷M

  • Modulus

    %*

    Get the remainder of the 2nd element of the stack divided by the top element. Return zero when dividing by zero.

    N MN%M

  • Divmod

    \*

    Return the result and remainder of the division of the top two elements of the stack. Return (0 0) if the top element is 0.

    N M(N÷M N%M)

#Comparison

  • Equality

    =*

    Check if the top two elements are equal.

    N MN=M

  • Less than

    <*

    Check if the second elements is less than the top element.

    N MN<M

  • Greater than

    >*

    Check if the second elements is greater than the top element.

    N MN>M

#Bitwise / Logical

  • NOT

    ~*

    Return the bitwise inverse of the number.

    N~N

  • AND

    &*

    Return the bitwise AND of the top two numbers in the stack.

    N MN&M

  • OR

    |*

    Return the bitwise OR of the top two numbers in the stack.

    N MN|M

  • XOR

    ^*

    Return the bitwise XOR of the top two numbers in the stack.

    N MN^M

#Other

  • Little T ...

    t*

    Returns N×10*M (N times 10 to the power of M) when N is the second element on the stack and M is the top element.

    N MN×10*M

  • Big T

    T*

    Returns ten to the power of the top element of the stack.

    N10*N

  • Little P

    p*

    Returns N×2*M (N times 2 to the power of M) when N is the second element on the stack and M is the top element.

    N MN×2*M

  • Big P

    P*

    Returns two to the power of the top element of the stack.

    N2*N

#Control Flow
  • Halt

    .

    Halts the program.

  • Forwards Goto

    z...Z

    A forward-nestable construct.

    When the lowercase z is reached, skip forwards to the capital 'Z', allowing nesting of forward-nestable constructs.

  • Backwards Goto

    Y...y

    A backward-nestable construct.

    When the lowercase y is reached, skip backwards to the capital 'Y', allowing nesting of backward-nestable constructs.

  • Two-way Goto / "Comment"

    {...}

    A forward-nestable construct.

    A backward-nestable construct.

    When { is reached, skip forwards to '}', allowing nesting of two-way gotos. Can be used as a nestable comment. Beware of the skip instructions!

  • Skip Forwards

    ]*

    Move the pointer forwards by the amount indicated by the top element of the stack. Move backwards for negative numbers.

  • Skip Backwards

    [*

    Move the pointer backwards by the amount indicated by the top element of the stack. Move forwards for negative numbers.

#Procedures & Macros
  • Procedure

    (...)

    A forward-nestable construct.

    A backward-nestable construct.

    See the section titled "Procedures & Macros"

  • Macro

    m...M

    A forward-nestable construct.

    A backward-nestable construct.

    See the section titled "Procedures & Macros"

  • Run Procedure/Macro

    "

    See the section titled "Procedures & Macros"

#Input / Output
  • Print

    ?*

    Print the top element to stdout as a character, treating the number as a code point, not a binary representation (eg. Unicode codepoint, not UTF-8 byte). Treat invalid numbers as a NULL character.

    83. >> S

    (83 101 97). >> Sea

  • Print Num

    #*

    Print the top element to stdout as a number. If the top element is a stack, print an opening bracket, then a space-separated list of its elements, then a closing bracket.

    83. >> 83

    (83 101 97). >> (83 101 97)

    (.). >> ()

  • Input

    Q*

    First print the top element of the stack using ?. Read one line from stdin, and then either return the codepoints of the read characters.

  • Input Num

    q

    First print the top element of the stack using ?. Try to fetch an integer from stdin, ignoring whitespace. If this fails, return an empty stack.

  • Input Char

    i

    Input one character from stdin.

  • Input Chars

    I*

    Get the top value of the stack, N, and input N characters from stdin.

#Other
  • Debug

    D

    Print the stack to stderr. Output is implementation-defined.

#∘ Procedures & Macros

There are two function-like constructs in ErrLess: Procedures and Macros. When a procedure or a macro is created, it is added to the function stack, and the top element of the stack is popped and used to identify the procedure/macro. When a procedure/macro is called it is run as if it is a separate program, except that a procedure operates on the top element of the current stack as it's own stack, and a macro keeps the same stack. They also share the same function stack as the program that originated them.

Can be used to implement psuedo-variables by defining a macro that always pushes a certain value to the stack.

A macro is created with m...M, a procedure is created with (...). Run a procedure/macro with ".

Pseudo-variable Life, the universe, and everything that stores the value 42:

SLife, the universe, and everythingS m
 '*.
M
#∘ Useful constructs

#Boolean conversion
#Int to boolean

Any number other than zero becomes -1.

0=~
#Stack to boolean

Any non-empty stack becomes -1, empty stacks become 0.

l0=~
#Any to boolean

Combination of the above. Uses modified If construct.

@l1_=1-[l0=~
#If Statements
#If

(Assumes that top stack value is 0 or -1)

Runs code CODE if the top stack value is -1.

1-[{
 CODE
}
#IF-Else

(Assumes that top stack value is 0 or -1)

Runs code CODE-IF-TRUE if the top stack value is -1, and the code CODE-IF-FALSE if the top stack value is 0.

2-[z{
 CODE-IF-TRUE
z}
 CODE-IF-FALSE
Z
#Loops
#While

(Assumes that top stack value is 0 or -1)

Runs code CODE while the top stack value is -1.

Y1-[{
 CODE
y}2]y
#Until

(Assumes that top stack value is 0 or -1)

Runs code CODE while the top stack value is 0. (Until the top stacks value is -1)

Y2+]{
 CODE
y}2]y
#Do...While

(Assumes that top stack value is 0 or -1)

Like While, but runs CODE at least once.

Y
 CODE
2+]y
#Do...Until

(Assumes that top stack value is 0 or -1)

Like Until, but runs CODE at least once.

Y
 CODE
1-[y

Back to top

About this wiki

commit 2a4a5bbef22026959061378e2f7dbf86f34f132c
Author: Ruan <ruan@pysoft.co.za>
Date:   2021-10-23T08:30:20+02:00

Minor Fixes
Clone this wiki
https://git.sr.ht/~ruan_p/errless_docs (read-only)
git@git.sr.ht:~ruan_p/errless_docs (read/write)