The Polaris Programming Language

Note: this documentation was written for an older version of Polaris. An update is due (April 29, 2020).

Polaris is a stack-based, interpreted programming language with strings as its only data type. It has been designed to be small in size and minimal in language features. Polaris was conceived to run under MS-DOS and Unix systems, and it consists entirely of a single .c file. The whole interpreter size is under 32 KiB and can also be used as an embeddable language in any C or C++ project.

The Polaris GitHub repository can be found at https://github.com/Lartu/polaris. Instructions for obtaining and building Polaris can be found there.

The Interpreter

Polaris is an interpreted programming language. The Polaris interpreter reads a Polaris script and executes it instead of performing a compilation. To run a Polaris script do: polaris <source_file> if you are on Unix or polaris.exe <source_file> on MS-DOS systems.

The Polaris interpreter understands a series of switches or flags that alter the way it executes. The switches must be prepended to the execution command before the source file path like polaris [switch]* [<source_file>].

Switches

Unix MS-DOS Effect
-v /v Displays Polaris version information and exits.
-h /h Displays Polaris switch information and exits.
-m /m Displays file memory allocation information.
-p /p Shows push and pop contents during execution.

The Polaris Stack

Polaris is a stack-based language. This means that there is an ubiquitous stack where values are pushed and popped from. Every time the Polaris Stack performs an operation that returns a value, said value is pushed to the stack. When it performs an operation that expects parameters (say, for example, an arithmetical addition), those parameters are popped from the stack in reverse order (for example, if you push 2 and 1, when popping you will first pop the 2 and then the 1).

Polaris Strings

In Polaris, unlike other programming languages, only one data type exists: the string. A string is a sequence of characters that, in turn, are also strings. There are three ways in which the Polaris interpreter understands strings and evaluates them:

Quoted Strings

Quoted strings are sequences of characters that start and end with " (double quotes). For example "Hello World" or "I love Polaris!". Quoted strings can contain any character between the double quotes except double quotes.

When the Polaris interpreter finds a quoted string, it evaluates it and pushes it to the stack without modifiying it (although without the double quotes). Quoted strings evaluate to themselves.

Plain Strings

Plain strings are sequences of characters that don't contain whitespaces nor special reserved characters (parentheses, double quotes, sugar glyphs, etc). Examples of plain strings are hello or join.

When the Polaris interpreter finds a plain string, it evaluates it by comparing it to the list of reserver Polaris words. If the words matches a reserved word, then it is a command and that command is executed (for example, the word * matches the multiplication command and thus a multiplication is performed). If the word doesn't match any reserved words, it is pushed to the stack without any modifications.

Block Strings

Block strings are sequences of characters enclosed between parentheses. A block string starts with ( and ends with ). Any character can exist inside a block string, even double quotes and whitespace, but any parentheses found inside must also be met with a matching one. (("hi")()) and (Hello World!) are valid block strings, whilst ("hi"() or ()"hi"() are not. Block strings can be empty and can contain other block strings.

When the Polaris interpreter finds a block string, it evaluates it and pushes it to the stack without modifying it (although without the parentheses).

Escape Sequences

Block strings may contain multiple escape sequences / control characters in them. Each escape sequence counts as only one character. The available escape sequences are:

\n newline / line feed
\r carriage return
\n newline / line feed
\t horizontal tab
\a alert (bell)
\b backspace
\v vertical tab
\f form feed
\\ escaped backslash

Polaris Scripts

A Polaris script is a sequence of strings separated by whitespace. The compiler evaluates each string one at a time and performs the operations stated above depending on the string type and its value. For example:

/* Say Hello! */
"Hello there!\n" print

That script pushes the string Hello there!\n to the stack and then prints it. All text found between /* and */ is considered to be a comment and is ignored except if it's found within a quoted string.

Reserved Words

print Pops and displays the popped value.
+ Pops two values and pushes the sum of their values. Fails in any of the popped values doesn't depict a number.
- Pops two values b and a and pushes a - b. Fails in any of the popped values doesn't depict a number.
* Pops two values b and a and pushes a * b. Fails in any of the popped values doesn't depict a number.
/ Pops two values b and a and pushes a / b. Fails in any of the popped values doesn't depict a number.
% Pops two values b and a and pushes the remainder of the integer division between a and b (a // b). Fails in any of the popped values doesn't depict a number.
// Pops two values b and a and pushes the result of the integer division betheen a and b (a // b). Fails in any of the popped values doesn't depict a number.
** Pops two values b and a and pushes the result of a to the power of b (ab). Fails in any of the popped values doesn't depict a number.
= Pops two values b and a and pushes 1 if the values are equal or 0 if they are not.
!= Pops two values b and a and pushes 1 if the values are not equal or 0 if they are.
< Pops two values b and a and pushes 1 if a < b or 0 otherwise. If any of the popped value doesn't depict a number, the strings are compared alphabetically.
> Pops two values b and a and pushes 1 if a > b or 0 otherwise. If any of the popped value doesn't depict a number, the strings are compared alphabetically.
<= Pops two values b and a and pushes 1 if a <= b or 0 otherwise. If any of the popped value doesn't depict a number, the strings are compared alphabetically.
>= Pops two values b and a and pushes 1 if a >= b or 0 otherwise. If any of the popped value doesn't depict a number, the strings are compared alphabetically.
! Pops a value from the stack. If it's 0 then it pushes a 1. Otherwise it pushes a 0.
& Pops two values b and a and pushes 1 if both values are not 0. Pushes 0 otherwise.
| Pops two values b and a and pushes 1 if any of the values is not 0. Pushes 0 otherwise.
eval Pops a string from the stack and evaluates it as if it was a Polaris script within the scope of the current script.
set Pops two values b and a and then stores the value of a in a variable called b.
get Pops a value a. If there is a variable called a, the value stored within the variable is pushed to the stack. Otherwise an error is thrown.
if Pops three values c, b and a. a is then evaluated. Then a fourth value d is popped from the stack. If d is not equal to 0 then b is evaluated. If d is equal to 0, then c is evaluated.
while Pops two values b and a. a is then evaluated. Then a fourth value d is popped from the stack. If d is not equal to 0 then b is evaluated. Then a is reevaluated and the whole process loops.
join Pops two values b and a and then pushes the concatenation ab to the stack.
copy Pops a value a and then it pushes it back twice to the stack.
del Pops a value from the stack.
swap Pops two values b and a and then pushes them to the stack reversing the order in which they were popped.
input Asks the user to enter a string and then pushes it to the stack.

Sugar Glyphs

In order to make scripts easier to read and write, Polaris includes Sugar Glyphs, syntax sugar for commonly used commands.

Glyph Usage Explanation
> >foo It is understood as foo set.
@ @foo It is understood as foo get.
% foo% It is understood as foo get eval.

Polaris was created by Lartu and is released under the Apache 2.0 License.