Pile

From Esolang
Jump to navigation Jump to search

Introduction

Pile is an esoteric, concatenative, stack-based and compiled programming language made for educational purposes.

How Pile works

Pile's compiler uses LLVM to compile the source code and execute it. You can compile it to an executable or use the JIT compiler to execute the code directly. One problem I ran into throughout early Pile compiler development is that LLVM is not Stack-based. So I had to solve the problem by having stack processed at compile time! I know it might sound weird but that's one of the main reasons this language is esoteric!

Pile’s compiler is 100% written in the Python programming language. The entire implementation of Pile is at the official Github repository: https://github.com/marc-dantas/pile/

Familiarizing with Pile

Here’s a simple “hello world” program in Pile:

   // simple comment ...
   "hello world" dump

Because it’s a stack-based language, Pile uses the Reverse Polish Notation to represent stack operations. So, a simple mathematical operation like 1 + 1 turns into 1 1 +.

Pile’s typing system

Pile is also a statically typed language and it has 4 types:

  • integer: Represents a signed 32-bit integer value.
  • bool: Represents a 1-bit integer value (1 or 0).
  • float: A floating point value.
  • string: Character pointer (i8* or char*)

Each operation has it’s own typing, and if you disrespect them, you’ll get an error like this:

   pile: error at ...:
      | type mismatch:
      |    `/` operation got mismatched types (float,
      |    integer) but operation expects (float, float)

All operations in Pile are type-checked during compile-time.

Operations

Operations in pile are basically every word in a Pile program. Except literals and some control flow words. > Words are every token in a Pile program

Pile has a very small list of built-in operations:

Pile operations
Operation Description
+ mathematical addition operation
- mathematical subtraction operation
* mathematical multiplication operation
/ mathematical division operation
% mathematical remainder (modulo) operation
> “greater than” comparison operation
< "less than” comparison operation
>= “greater than or equal” comparison operation
<= “less than or equal” comparison operation
!= “not equal” comparison operation
= “equal” comparison operation
| bitwise OR operation
& bitwise AND operation
>> bitwise shift right operation
<< bitwise shift left operation
drop drops a value from the top of the stack (a --)
dup duplicates the last element to the top of the stack (a -- a a)
over copies the 2nd last element on top of the stack (a b -- a b a)
rot moves the 3rd last element to the top of the stack (a b c -- b c a)
swap swaps the top two values on top of the stack (a b -- b a)
dump prints the last element (of any type) on top of the stack to stdout

Here's a simple demonstration of all operations in Pile programming language:

   // math
   1 1     + dump // Sums 1 + 1
   3 1     - dump // Subtracts 3 by 1
   2 2     * dump // Multiplies 2 by 2
   1.0 2.0 / dump // Divides 1 by 2 (half)
   1 2     % dump // Gets the remainder of the division 1/2
   // comparison
   1 1 =  dump // Compares 1 == 1
   3 1 != dump // Compares 3 != 1
   2 2 >  dump // Compares 2 > 2
   2 2 >= dump // Compares 2 >= 2
   1 2 <  dump // Compares 1 < 2
   1 2 <= dump // Compares 1 <= 2
   // bitwise
   1 1 |  dump // 0001 | 0001
   3 1 &  dump // 0011 & 0001
   2 2 >> dump // 0010 >> 0010
   2 2 << dump // 0010 << 0010
   // stack operations
   1     drop                // There's nothing here anymore :(
   1     dup  dump dump      // There are two values here now :)
   1 2   over dump dump dump // Now it's 1 2 1
   1 2 3 rot  dump dump dump // Rotated numbers: 2 3 1 
   69 96 swap dump dump      // They even swapped the digits!

Control flow

In Pile you can control the flow of your program using two statements:

If conditions

If conditions are very simple in Pile, here’s it’s syntax:

   condition if
       ...
   [else
      ...]
   end

and Here’s a simple example of how to use it:

   10 10 = if
       1 dump
       1 1 = if
           3 dump
       else
           4 dump
       end
   else
       2 dump
   end

While loops

While loops are a little bit different. Here’s it’s syntax:

   while condition do
       ...
   end

and here’s a simple example of how to use it:

   0 while dup 10 <= do
       dup dump
       dup 2 % 0 = if
           2 +
       end
   end drop

Strings

strings in Pile are C-styled strings. That means that every string in Pile is null-terminated (it has a NULL character at the end). Here it is an example of how to work with strings:

   "hello" dump // Pushes a char pointer to the stack and prints
   "world" dump