Esolang: Piet, an easy tutorial

Introduction

Piet is a so-called esotheric programming language (esolang). A program in Piet differs from a program in a conventional programming language since it is a colourful picture. The specifications of the Piet language can be found here. You should read this before continuing. All programs were written, run and saved with PietDev which is an online IDE for Piet.

When programming in Piet the following tables are the essential refence.

light red light yellow light green light cyan light blue light magenta
red yellow green cyan blue magenta
dark red dark yellow dark green dark cyan dark blue dark magenta
white black
 darkness change
Hue changeNone1 Darker2 Darker
None pushpop
1 Stepaddsubtractmultiply
2 Stepsdividemodnot
3 Stepsgreaterpointerswitch
4 Stepsduplicaterollin(number)
5 Stepsin(char)out(number)out(char)

In a Piet program the colours themselves do not matter, it's the transitions in hue and darkness that form the code.

An example

The following picture is a Piet program that asks the user for a number and calculates its square.

Starting in the top right codel (= enlarged pixel, examples here use codel size 20) and going right we get:
  • light blue to dark green (darkness shift 2 and hue shift 4): in(number). So the user is asked for a number and it is put on the stack.
  • black wall. The direction is changed clockwise, we go down.
  • dark green to dark red (hue shift 4):duplicate. The number is duplicated and put on the stack.
  • dark red to yellow (darkness shift 2 and hue shift 1):multiply. So two numbers are taken from the stack and multiplied. Since they're both the same, we've squared the number. It is then put on the stack again (which now contains only the result).
  • yellow to dark red (darkness shift 1 and hue shift 5):out(number). The result is written as output.
  • over white to blue (jumping over white causes no transitions): noop. Nothing is done.
  • black walls everywhere, the program terminates.
The program can be summarized as in(number)-duplicate-multiply-out(number)

As said before, the colours are not important, the transitions are. Hence the above program could also be given as , wich is clearly much more compact, but less artistic ...

Either way the programs are fine, but not quite readable for a human. To solve this (with the hope of writing longer programs) we choose to insert white codels, so as to breakdown the picture in recognisable codepieces. Moreover we will start any stack-changing code with red and any flow-changing code with green. Our program becomes:
  • : in(number)
  • : duplicate
  • : multiply
  • : out(number)
  • : end program

Elementary codepieces

Starting any stack-changing code with red, we get the following codepieces.

Numbers on a stack

Now that we've managed to code somewhat clearly in Piet, we're going to use the stack for more complicated things. Lets try to put a number on the stack. Numbers in Piet are surfaces of the same color. They are pushed on the stack by means of the push command which is a darkness shift 1. Pushing 6 on the stack is coded as

or

Often we want to put several numbers on the stack. This can be done by alternating shades of different surfaces. For instance the sequence of even numbers 2,4,6,8 is put on the stack as follows

A special case is when we want to put 0 on the stack. This is achieved by push 1-not: .

Once we have numbers on a stack, we'd like to use them as counters. In order to increment a number we add 1. Hence we get

Controlling the flow

Any programming language has the ability to keep values stored (either as variables or in a stack) and the necessary operations on these values (+,-,*,/, ...). Piet does this as described above. Besides this, we'd like to have conditional branching and loops. Any flow-changing code will start with a green codel.

Conditional statements are achieved by means of the pointer command, which changes the flow of the program clockwise, according to the top value on the stack. Following codepiece describes duplicate-not-not-pointer

The top value is duplicated and, by means of the double negation, replaced by 1 if it is non-zero or by 0 if it was zero. The pointer command follows. Hence if the top value is 0 the flow goes straight ahead, else it is turned clockwise and goes downwards. This gives us an ifzero codepiece.

An infinite loop is easily created.


Combining this with the above conditional branching we can make a loop until the top value is 0.

Examples

Accessing the stack

Using the stack can be somewhat complicated. We'll introduce two codepieces to put and retrieve a value to/from an arbitrary place in the stack. The Piet command needed is roll. roll will bury a value too a certain depth (in the example below 3) in the stack. It is used as follows.

Stack push 3
push 1
roll piet code
10
9
8
7
6
1
3
10
9
8
7
6
9
8
10
7
6

Using roll with -1 instead of 1 allows to retreive a value from the stack.

Stack push 3
push 1-push 2-substract
roll piet code
10
9
8
7
6
-1
3
10
9
8
7
6
8
10
9
7
6

We now have the codepieces

Making art

We are now able to write some more example programs in Piet.

Reference

input/output:
  • : in(number)
  • : out(number)
stack operations:
  • : duplicate
  • : pop
math operations:
  • : add
  • : substract
  • : multiply
  • : divide
  • : mod
flow-control:
  • : ifzero

  • : loop until zero

  • : end program
numbers:
  • : push 6

  • : pushzero
counters:
  • : increment
  • : decrement
stack access:
  • : put 3

  • : get 3