~ruan_p/errless_docs

#Tutorial

<-- Getting started || Contents || Language Reference -->

I've never written any tutorials before, so any help / criticism would be appreciated.

#Before we start

I would encourage you to play around with everything you learn - just following the tutorial without experimenting yourself is unlikely to help you much. This tutorial is also definitely not rigorous and complete, so I would encourage you to explore the language reference.

One nice command when you are playing around is D. All it does is to output the stack. Please note that it outputs to stderr, and that the output format is entirely implementation-defined. It should definitely not be used for anything other than exploring the language or debugging programs.

#Hello, world!

In ErrLess, every command is only one character long. And every character is one command - even though many are no-ops. Note: Erless is case-sensitive.

First the basics:

  • In an ErrLess program the stack starts empty. The IP starts at the first character of the program. When the IP reaches the end of the program, it loops back to the beginning instead of halting the program.

  • There are two types in ErrLess: A stack, and an integer. A stack can contain either other stacks, or integers, or a combination of both.

  • Whenever a command tries to get a value outside the bounds of the stack - element -1, element x of a stack of length ≤ x, the top element of an empty stack, etc. - it just gets an empty stack in return.

Now some instructions:

  • All whitespace - \n\r \t - and unprintable characters are no-ops. You can use them to structure your code.

  • S starts and ends a string. There are no escape characters or anything. It just copies everything up to the next S. You may notice that this means that you cannot have a capital s in a string. We'll come to this later. You may also remember that there are only stacks and integers - so where did the string come from? I'll explain how strings work later, but it isn't important at the moment.

  • We'll also need to output the string - ErrLess doesn't automatically output the stack when it's finished. To do this use ?. Note: ? doesn't automatically print a newline.

  • We need one last essential for our hello world program: A way to end the program, otherwise it'll just loop back to the beginning and keep on printing forever. To halt the program we'll use ..

To summarise:

  • \n\r \t - No-op
  • S...S - Construct a string
  • ? - Print the string, no automatic newline
  • . - Halt the program

So now our program:

  • First, we construct the string: SHello, world!S

  • Next, we print: ?

  • Lastly, we end the program: .

  • Putting this all together we have this: SHello, world!S ? .

  • If you want a newline at the end use this:

    SHello, world!
    S?.
    
#Strings

So how do strings work? Easy! It uses a stack containing integers, where every integer represents a character of the string. If any character is outside the range of valid characters, then it is treated as a NULL character. So to add a capital s to a string, we need to learn a few new commands:

  • ' - Adds the character code of the next character to the top of the stack

  • x - Append the top value of the stack to the stack just below it.

  • : - Concatenate the top two elements of the stack.

So, to create the string "There are SEAMONSTERS??":

SThere are S 'Sx SEAMONSTERS: 'Sx S??S:

Here's a view of the stack:

  1. SThere are S: "There are "
  2. SThere are S 'S: "There are " S
  3. SThere are S 'Sx: "There are S"
  4. SThere are S 'Sx SEAMONSTERS: "There are S" "EAMONSTER"
  5. SThere are S 'Sx SEAMONSTERS:: "There are SEAMONSTER"
  6. SThere are S 'Sx SEAMONSTERS: 'Sx: "There are SEAMONSTERS"
  7. SThere are S 'Sx SEAMONSTERS: 'Sx S??S:: "There are SEAMONSTERS??"
#Comments

Unfortunately my language does not have comments. Fortunately there is a structure that can be used to simulate comments. To add a comment, just surround it with curly braces:

{ Look! A "Hello, world!" program! }
SHello, world!
S?.
{ Did you know that you can nest "comments"? Like this: {Wow!} }

It should be noted that there are ways to get the IP to enter these "comments", but you don't need to worry about that for now.

#Interactive Program

Let's make a little program that asks for a name, greets the user with their name, asks their age, and then tells them how old they'll be in eleven years. Something like this:

What is your name? John
Hello, John! How old are you? 25
You will be 36 years old in eleven year's time.

The first thing we'll need is a way to take inputs. Q prints the top element of the stack in the same way ? does, and then takes one line of input. q - note the difference in case - prints the top element of the stack like ?, and then tries to get an integer as an input, and returns an empty stack if it was unsuccessful.

So we can do the first part of the program so far:

SWhat is your name? SQ { Get the name }
SHello, S?
? { Print the name }
S! How old are you? Sq { Get the age }

.

But for the next step we'll need to add eleven to the age and then print it as a number. To add eleven to the age we'll need numbers, and some mathematical operators:

  • 0 to 9 - Push the corresponding number to the stack

  • a to f - Push the corresponding hex number to the stack: 10 for a, 11 for b, etc.

  • +, -, *, / - The basic mathematical operators: Addition, subtraction, multiplication, division

  • # - Output the top value of the stack as a number

Using this we can expand our program:

SWhat is your name? SQ
SHello, S? ? S! How old are you? Sq
b+ { Add eleven to the age }
SYou will be S?
# { Print the age }
S years old in eleven year's time.
S?

.

If we remove the comments:

SWhat is your name? SQ
SHello, S? ? S! How old are you? Sq
b+ SYou will be S? # S years old in eleven year's time.
S?
.
#Some maths stuff

Errlang doesn't only have addition, subtraction, multiplication, and division. Here's a few more mathematical operators:

  • _ - Negates the top element of the stack: N_ is equivalent to 0N-, where N is some command / set of commands that results in one value being pushed to the stack

  • % - Modulo, gets the remainder after a division

  • \ - Divmod, returns a stack containing two integers: The result of the division, and the remainder

  • t - N * 10ᴹ, 89t == 8e9, or eight eight thousand million / billion

  • T - 10ᴺ, 6T == 1e6, one million

  • p - N * 2ᴹ; see t

  • P - 2ᴺ; see T

#Truth machine

What if we want to make a slightly more complex program, one that does different operations depending on the input? For this we could make a truth machine: If it gets a zero as input, it returns zero and halts immediately, and if it gets a one it keeps on printing ones forever. For now we'll assume that the input is valid.

To make this a bit easier I'll first design a truth machine in Python-like pseudocode:

inp = input()

do:
    print(inp)
while inp == 1

The first part is easy: SSq

But the next part is slightly more difficult.

#Comparisons and boolean logic

In ErrLess we use -1 for true and 0 for false. Why -1 and not 1? This is because -1 is represented as all ones in binary. This means that we don't need separate bitwise and logical operators. A demonstration in C++:

std::cout << (~0) << ' ' << (~1) << std::endl; // -1 -2
std::cout << (!0) << ' ' << (!1) << std::endl; // 1 0

As you can see, bitwise and logical not gives completely different results: The bitwise inversion of zero, is negative one! This is because of how computers represent numbers internally, called two's complement notation. To read more you can visit the wiki page for two's complement notation.

In ErrLess there are three comparison operators, and four bitwise/logical operators:

(8 bit integers used for demonstration purposes)

  • = - Checks equality

  • < - Less than

  • > - Greater than

  • ~ - NOT, returns the bitwise inverse: NOT 42 "00101010" → -43 "11010101"

  • | - OR: 42 "00101010" OR 13 "00001101" → 47 "00101111"

  • & - AND: 42 "00101010" AND 13 "00001101" → 8 "00001000"

  • ^ - XOR: 42 "00101010" XOR 13 "00001101" → 39 "00100111"

#Control flow

It's all fine being able to get input, print stuff, compare stuff, and add numbers, but you can only do so much without control flow. ... So I introduce you to gotos:

  • z...Z - When a z is reached, skip to the next Z, allowing nesting. Ignore all z's and Z's inside "comments"

  • Y...y - When a y is reached, skip backwards to the previous Y, allowing nesting. Ignore all y's and Y's inside "comments"

  • {...} - When a { is reached, skip to the next }, allowing nesting. Note that this ignores both z...Z and Y...y.

You may notice a problem with this: z...Z makes sections of code permanently inaccessible, while Y...y causes infinite loops. This doesn't help us much! That is why there are two skip instructions:

  • ] - Skip forward by the number indicated by the top of the stack, skipping backwards for negative numbers

  • [ - Skip backwards by the number indicated by the top of the stack, skipping forward for negative numbers

With these you can make an if statement (assumes 0 or -1 at the top of the stack):

1-[{ CODE }

Or an if-else statement:

2-[z{ CODE-IF-TRUE z} CODE-IF-FALSE Z

Using the same principles we can also have a while loop:

Y1-[{ CODE y} 2]y

An until loop:

Y2+]{ CODE y} 2]y

A do... while loop:

Y CODE 2+]y

And a do... until loop:

Y CODE 1-[y
#Back to the truth machine

So far, we're busy translating the following pseudocode into Errlang:

inp = input()

do:
    print(inp)
while inp == 1

And this is what we have:

SSq

Well, this should be easy:

SSq     { Get input }

Y       { do ... }
 #      { print(inp) }
1= 2+]y { while inp == 1 }
.       { Halt }

But if you run this, you may notice that the program prints the input once, and then hangs. Why is this? Very simple: The # consumes our input. So would the 1= 2+]. What can we do about this? For this there is a command that duplicates the top value of the stack: @. So lets modify the program accordingly:

SSq      { Get input }

Y        { do ... }
 @#      { print(inp) }
@1= 2+]y { while inp == 1 }
.        { Halt }

And now we have a working truth machine!

#The end

... for now.

You've run out of tutorial! Don't worry, I'll probably add more sometime. To find out more about the language yourself, feel free to visit the reference page or the FAQ. You can also check out the examples page to see a few sample programs.

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)