APOL
Paradigm(s) | imperative |
---|---|
Designed by | User:GingerIndustries |
Appeared in | 2021 |
Memory system | cell-based |
Computational class | Unknown |
Reference implementation | PyPOL |
File extension(s) | .pol (source), .abf (bytecode) |
APOL (Another Polish Golfing Language or APOL's a Poor Golfing Language) is a golfing language that is based off of Lisp and uses entirely polish notation for its instructions (+ 1 1 instead of 1 + 1.)
Syntax
APOL has three basic parts: Constants, literals (which can only occur within instructions), and instructions.
Constants
APOL's constants are as follows:
Symbol | Value |
---|---|
↹ | The interpreter's version information |
T | Boolean true |
F | Boolean false |
X | None/null |
ĥ | The string "Hello, World!" |
ô | 100 |
õ | 1000 |
ö | 10000 |
ø | 100000 |
ó | 1000000 |
ò | 1000000000 |
π | The interpreter's pi constant |
ε | The interpreter's e constant |
Ⓠ | The string "qwertyuiop" |
Ⓔ | The string "aeiou" |
⒬ | The list ["q" "w" "e" "r" "t" "y" "i" "o" "p"] |
Ⓐ | A string of all lowercase and capital ASCII letters |
⒜ | The list [a-zA-Z] |
ⓛ | A string of all lowercase ASCII letters |
Ⓛ | A string of all capital ASCII letters |
① | The string "0123456789" |
⑴ | The list [0-9] |
⑩ | A string of all numbers, 1-100 (i.e. "12345678910111213" etc.) |
⑽ | The list [1-100] |
⑨ | A string of all numbers, 0-99 |
⑼ | The list [0-99] |
⒈-⒔ | Successive powers of 2, 16-65536 (i.e. ⒈ = 16, ⒉ = 32, ⒊ = 64, etc.) |
⒕ | 2147483648 |
⒖ | 4294967296 |
Literals
There are three literals: numbers, strings, and lists. Numbers are simply typed out (ex. 12.34), however strings and lists require special formatting. Single-word strings (with no spaces) that do not start with an instruction or constant symbol can simply be typed out, however this is discouraged. It is better practice to enclose strings in single or double quotes. (ex. "Hello World!") Lists are enclosed within square brackets, with items separated by spaces. Lists can contain strings and numbers, but not other lists due to laziness parsing engine limitations. (ex. [1 2 3 "some text" 4 5.8])
Instructions
Instructions are split into two parts: the type and the parameters. The type is always one character long, and always comes first. The parameters are right after the type, in curved brackets. Each parameter is separated by a space. Instructions can accept any literal or another instruction as parameters.
Implicit Printing
If the last instruction (which in this case also includes constants) of a program returns a non-None value, APOL will print that value automatically. This means that instead of writing:
p(ĥ)
You can write:
ĥ
This instruction will add the numbers 1 and 2, and print the result.
p(+(1 2))
Instruction table
This table lists APOL's instructions. The instruction column explains the instruction symbol and the parameters it takes. (* for any type, ~ for string, # for number, ! for boolean, @ for cell index (see below), and [ for list. Parameters after the | symbol are optional. ex. *required any input|#optional number input=10.7) The friendly name can be typed instead of the symbol and will be automatically replaced with the symbol before execution. The returns column expains what the instruction will return, the usage column details what the instruction will do, and the notes column lists additional information.
Instruction | Friendly name | Usage | Returns | Notes |
---|---|---|---|---|
p(*text|~end="\n") | Prints text to stdout. | None | ||
i(|~prompt) | input | Reads text from stdin. | The inputted text as a string | |
⧤(|~prompt) | floatinput | Reads text from stdin and returns a float. | The inputted text as a float, or None if it can't be parsed | |
⧣(|~prompt) | intinput | Reads text from stdin and returns an integer. | The inputted text as an integer, or None if it can't be parsed | This instruction will also accept floats, but wil truncate them to integers before returning. |
+(#n1 #n2) | add | Adds two numbers together. | The sum of the two numbers | |
-(#n1 #n2) | subtract | Subtracts n1 from n2. | The difference of the numbers | |
*(#n1 #n2) | multiply | Multiplies n1 and n2. | The product of the numbers | Can also be called as x(#n1 #n2). |
/(#n1 #n2) | divide | Divides n1 from n2. | The quotient of the numbers | |
#n2=2) | exponent | Raises n1 to the power of n2 . | The result of the operation | |
%(#n1 #n2) | modulo | Returns the remainder of n1 divided by n2. | The result of the operation | |
∸(#n1 #n2) | floordiv | Returns n1 divided by n2 and truncates the decimal point. (ex. ∸(5 2) returns 2) | The result of the operation | |
*data=0) | write | Saves data to the cell at address address. | None | |
@(#address) | dynamicread | Returns the data at the passed address, similar to superscript numbers but allowing for dynamic reading. | ||
I(#n1) | castnumber | Converts a string containing a number to a number (ex. I("1") returns 1.0) | The converted number | |
L(~data) | castlist | Returns the passed string as a list, one item for each character. | ||
Ŀ(~[data) | castfloatlist | Returns the passed string or list as a list, containing each item converted to a float. | ||
Ľ(~[data) | castintlist | Returns the passed string or list as a list, containing each item converted to a integer. | ||
b(#num) | tobinary | Convert the passed number to its binary representation. | ||
B(~binary) | frombinary | Convert the passed binary number (as a string) to its integer representation. | ||
⌬(~[data) | reverse | Reverses the passed string or list | The reversed string or list | |
l(~[data) | length | Returns the length of the passed string or list | The length of the string or list | |
c(~string ~find) | stringcontains | Returns True if string contains find, False otherwise. | ||
C(~[data ~find) | count | Returns the number of occurences of find in data | ||
⌕(~string ~find) | stringfind | Returns the index of the first occurrence of find in string, or -1 if it can't be found. | The index of the first occurrence | |
s(~string |~sep=" ") | stringsplit | Splits the passed string at every occurence of sep. | A list of the split strings (not including the seperator) | The behavior of this instuction with an empty separator is undefined. |
j([list |~sep="") | stringjoin | Joins the items in list together in a string, seperated by sep. | The joined string | This instruction will convert all items in the list to strings before joining them. |
R(~instr ~toreplace ~replacewith) | stringreplace | Replaces all occurrences of toreplace in instr with replacewith. | The replaced string | |
V(~input #start |#end=None) | substring | Returns the characters in the string input starting at start and ending at end. | If end is not passed, start will be interpreted as end. (i.e. V("hello" 2) returns "llo") | |
↑(~input) | uppercase | Returns the string input with all characters converted to uppercase. | ||
↓(~input) | lowercase | Returns the string input with all characters converted to lowercase. | ||
↶(~string) | tocodepoint | Returns the codepoint of the first character in the passed string. | ||
↷(#codepoint) | tochar | Returns the character corresponding to the passed codepoint. | The behavior of this instruction with invalid codepoints is undefined. | |
t(*data) | caststring | Returns data represented as a string. | ||
a(@address *value) | append | Appends value to the list at address address. | None | This method can append lists to lists, despite this not being possible when lists are created normally. |
⊕([#in) | sum | If the input is a list, return all items in the list added together. If it is an integer (floats will be converted to integers), return the sum of its digits. | The total | The behavior of this instruction with a list containing non-number values is undefined. |
m([in) | min | Returns the smallest item in the passed list. | ||
M([in) | max | Returns the largest item in the passed list. | ||
z([in) | contig | Returns every contiguous sublist of the passed list. | ||
A(~code) | apolexec | Executes one APOL instruction (passed to it as a string) and returns the result. | ||
g([list |#index=0) | listget | Returns the item at index index in the passed list. | ||
S([list *value |#index=0) | listset | Sets the item at inxed index in the passed list | The modified list | |
P([list |#index=0) | listpop | Removes the item at index index from the passed list | The modified list | |
r([list *value) | listremove | Removes the first occurence of item from list | The modified list | |
~([list) | sort | Returns a sorted version of the input list | ||
⭳([list) | listflatten | Turns a list of lists (a 2d list) into a 1d list. | The modified list | |
w(!condition {instructions}) | while | While the instruction condition retuns True, execute the passed instructions. | None | After the condition, a theoretically unlimited number of instructions may be passed, separated by spaces. (ex. w(T p("1") p("2")) will print 1 and 2 for infinity) |
W(!condition {instructions}) | precheckwhile | Works exactly like while, except it checks its condition once before the loop starts. This means this loop can exit immidiately, compared to the normal while which will always run at least once. | ||
f(#[iter {instructions}) | for | If iter is a number, execute the passed instructions that many times. If it is a list, execute the passed instructions once for each item in the list. (only really useful when used with ∋, see below) | None | The instructions parameter behaves the same as while. (see above note) |
ⅎ(#[iter {instructions}) | onefor | Works exactly like for, but starts its counter at 1. | ||
ƒ(#[iter *instruction) | listfor | Works exactly like for, but only takes one instruction and returns each return value of that instruction as a list. (ex. ƒ(10 *(∈ 2)) will return [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]) | The list of return values | |
Ƒ(#[iter *instruction) | onelistfor | Works exactly like listfor, but starts counting at 1 instead of 0. | ||
ḟ(#start #end {instructions} | startendfor | Works like for, however it allows you to specify a start and an end to count from. | None | In this for, forcounter will always start at 0 but foritem will contain the current number. (i.e. ḟ(12 15 p(∈) p(∋)) will print 0 12 1 13 2 14) |
ℱ([list *instruction) | filter | Returns a list composed of every item in the input list which makes the instruction return true. | ||
∈ and ∋ | loopcounter (∈) and loopitem (∋) | When iterating through a list, ∈ will return the index in the list (starting from 0) and ∋ will return the item at that index. When iterating through a number, both ∈ and ∋ will return the iterations passed (starting at 0.) When used in a while loop, ∈ will return the iterations passed and ∋ will return the loop's condition. | The counter and item | The behavior of these instructions when outside a loop is undefined. |
⋒ | foriterator | Returns the item the for loop containing it is iterating through. (ex. f(3 p(⋒)) will print 3 3 3. | ||
⋔ | ifitem | Inside an if statement, returns the result of the statement passed as the condition. | The behavior of these instructions when outside an if statement is undefined. | |
?(!condition *iftrue |*iffalse=None) | if | If condition evaluates to True, execute the instruction iftrue, otherwise execute the instruction iffalse. | None | Because this instruction only can have one other instruction passed to iftrue or iffalse, it is advised to use it with the : instruction. |
¿(!condition *iftrue *iffalse=None) | returnif | Works the same as ?, but returns the value of the instruction (or literal) that got executed. | ||
:({instructions}) | function | When executed, will execute every instruction passed to it. | None | |
⍭(#delay) | delay | Pauses program execution for delay seconds. | None | |
<(#n1 #n2) | lessthan | Returns whether n1 is less than n2. | ||
>(#n1 #n2) | greaterthan | Returns whether n1 is greater than n2. | ||
≤(#n1 #n2) | lessorequal | Returns whether n1 is less than or equal to n2. | ||
≥(#n1 #n2) | greaterorequal | Returns whether n1 is greater than or equal to n2. | ||
=(*n1 *n2) | equal | Returns whether n1 equals n2. | ||
≠(*n1 *n2) | unequal | Returns whether n1 does not equal n2. | ||
≬(#n1 #n2 #n3) | between | Returns whether n1 is between n2 and n3. | ||
∆(@address |#amount=1) | increase | Increases the value at the passed address by amount. | None | The behavior of this instruction if the value is not a number is undefined. |
∇(@address |#amount=1) | decrease | Decreases the value at the passed address by 1. | None | The behavior of this instruction if the value is not a number is undefined. |
≐(#number) | geteven | Returns if the passed number is even. | ||
∓(#number) | getsign | Returns if the passed number is positive. | ||
⌿(#number) | abs | Returns the absolute value of the passed number. | ||
∿(#n1 #n2) | randnum | Returns a random number between n1 and n2 inclusive. | ||
≀ | randfloat | Returns a number between 0 and 1 inclusive. | ||
≖(#n1) | round | Rounds the passed number and returns it. |
Codepage
Note that F1 is a space character.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
0 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p |
1 | q | r | s | t | u | v | w | x | y | z | A | B | C | D | E | |
2 | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U |
3 | V | W | X | Y | Z | + | - | * | / | % | ^ | ? | : | < | > | = |
4 | & | ! | | | " | ' | ( | ) | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
5 | 9 | [ | ] | ⁰ | ¹ | ² | ³ | ⁴ | ⁵ | ⁶ | ⁷ | ⁸ | ⁹ | Ŀ | Ľ | ⭳ |
6 | @ | # | $ | _ | \ | , | ; | { | } | ` | ~ | ⌬ | ⌕ | ↶ | ↷ | ⊕ |
7 | ⅎ | ƒ | ḟ | ∈ | ∋ | ¿ | ⋔ | ⍭ | ≤ | ≥ | ≠ | ≬ | ∆ | ∇ | ≐ | ∓ |
8 | ⌿ | ∿ | ≀ | ≖ | ⧤ | ⧣ | ∸ | ⋒ | \n | |||||||
9 | ↹ | ĥ | ô | õ | ö | ø | ó | ò | π | ε | ℱ | |||||
A | Ⓠ | ⒬ | Ⓐ | ⒜ | ⓛ | Ⓛ | ① | ⑴ | ⑩ | ⑽ | ⑨ | ⑼ | Ⓔ | ↑ | ↓ | Ƒ |
B | ⒈ | ⒉ | ⒊ | ⒋ | ⒌ | ⒍ | ⒎ | ⒏ | ⒐ | ⒑ | ⒒ | ⒓ | ⒔ | ⒕ | ⒖ | |
C | ||||||||||||||||
D | ||||||||||||||||
E | ||||||||||||||||
F |
Memory
APOL stores data in an infinite list of cells, numbered 0-∞. Each cell can contain any literal data type, and their values are acessed using superscript numbers. For example , to print the value in cell 12 you would write:
p(¹²)
However, you do not use superscript numbers to refer to cells. This is valid:
v(1 "hello")
This is not:
v(¹ "hello")
Example Programs
Hello World:
ĥ
Fibonacci sequence: (input what number to print up to)
v(1 I(i));v(2 0);v(3 1);v(4 0);w(<(² ¹) p(²) v(4 ²) v(2 ³) v(3 +(⁴ ³)))
99 bottles of beer:
v(0 99);v(1 " bottles of beer");w(>(⁰ 1) p(+(+(t(⁰) +(¹ +(" on the wall, " +(t(⁰) +(¹ "."))))) +("\nTake one down, pass it around, " +(t(-(⁰ 1)) +(¹ " on the wall.\n"))))) ∇(0))
FizzBuzz:
ⅎ(⧣ ?(&(=(%(∈ 3) 0) =(%(∈ 5) 0)) p("FizzBuzz") ?(!(%(∈ 3)) p("Fizz") ?(!(%(∈ 5)) p("Buzz") p(∈)))))
Collatz Conjecture:
v(0 ⧣);w(>(⁰ 1) p(⁰) ?(≐(⁰) v(0 /(⁰ 2)) v(0 +(*(⁰ 3) 1))))