Pairpointing
Pairpointing is an esoteric programming language made by User: Fazaazafg. In Pairpointing, every variable is a pair. Each pair holds two pointers, which both can point to some other pair, to nothing (also known as a null pointer), or even point to its own pair.
This is currently in a work in progress, so expect some sections of it being unfinished.
Syntax
The syntax itself is fairly simple. Each line is separated with a semicolon, with them being executed from top to bottom and the program terminates when it reaches the bottom. Comments can be made using the ~
symbol to mark a comment. Each comment ends after a newline character. Just like the usual stuff like on most typical programming languages.
Pairs
In this language, the only data type that exist are pairs. As said before, a pair holds two pointers. The pointer can only point to a pair or null.
The =
symbol is used to modify the pointers on a pair. The syntax for doing it is like so:
name = left, right;
where name
is the pair to modify on and left
and right
are the pairs to make the pointers point on to. If name
is a pair that doesn't exist yet, then it will create a new pair with the identifier name
with the pointers pointing to the left
and right
pairs.
You can also do this:
pair = pair2;
which will make pair
now point to pair2
's pointers.
pair2 = left, right; pair = left, right; ~ Same thing pair = pair2; ~ Same thing
The pointers of a pair can also point to null by doing this:
pair = , right; ~ left element is null pair = left, ; ~ right element is null pair = ,; ~ both elements are null
the last case can also be written shortly as:
pair = ; ~ both elements are null
You can also create pairs with pairs inside of them using parentheses. Here's an example.
templ = l, r; tempr = r, l; pair = templ, tempr; ~ Too long pair = (l, r), (r, l); ~ Do this instead
To refer to an element in a pair, you can use <
and >
symbols to refer the left and right element of a pair. Example of how it can be used:
pair = left, right; pair2 = >left; >pair = <pair, pair2;
These can be stacked together to have the very inner elements on a pair. The order goes from right to left.
<>>>pair = pair2, pair4; ><<><>>pair3 = ><pair4, <pair;
Although pairs can only have two pointers, you can however put in more than two pairs to assign to the pointers.
pair = a, b, c, d, e;
But, how does this even work? Well, the thing is that the code above is a shorthand for:
pair = a, (b, (c, (d, e)));
Okay, so, what would this even be used for? Well, turns out, this could be used as a some sort of array actually.
pair = a, b, c, d, e; index0 = <pair; ~ gets the first element of [a, b, c, d, e], which is a index1 = <>pair; ~ gets the second element of [a, b, c, d, e], which is b index2 = <>>pair; ~ gets the third element of [a, b, c, d, e], which is c index3 = <>>>pair; ~ gets the fourth element of [a, b, c, d, e], which is d index4 = <>>>>pair; ~ gets the fifth element of [a, b, c, d, e], which is e
If statements
The ?
symbol is used to create an if statement. The code blocks for the statements are written using curly brackets.
There are two types of if statements in this language:
variable? { statements }
var1 = var2? { statements }
The first one will execute statements
if variable
has at least one of its pointers not pointing to null. The only time statements
will not execute after triggering this if statement is when both of the pointers are pointing null. If variable
is already null, then it will not execute statements
.
The second if statement will execute statements
if var1
's pointers are the same pointers as var2
's. It will not however if at least one isn't the same, even if the contents of the pointer matches.
left = ; right1 = , left; right2 = , left; ~ Has the same pointers as right1, but has different names pair1 = left, right1; pair2 = left, right1; pair3 = left, right2; pair1 = pair2? { ~ It will execute this because right1 and right1 are the same } pair1 = pair3? { ~ It will *not* execute this because right1 is not right2 }
If var1
and var2
are the same pair, then statements
will always be executed.
Else if statements in this language can be written like this:
variable? { ~ if statement1 }, var1 = var2? { ~ else if statement2 }, { ~ else statement3 }
One line if statements also exists in this language, and it can be written like this:
variable? statement1 , var1 = var2? statement2 , statement3
Loops
Loops in Pairpointing are while loops, in that they will keep executing until a condition is false. The syntax is very similar to if statements and uses the same two conditions as said before, but the only difference is that it uses the !
symbol and not the ?
symbol. Here's some examples of loops.
pair! { statements } pair = pair2! { statements }
Each iteration on a loop the program will jump at the beginning of that loop and check whether the condition is true or not. If it is still true, it will continue executing the loop, but if it's not, then it'll break out of the loop automatically.
Breaking out of a loop manually (also known as the break
keyword in most typical programming languages) can be done by using the <
symbol, like this:
p! { statements <; ~ breaks out of the loop statements }
Skipping over an iteration of a loop (also known as the continue
keyword in most typical programming languages) uses the >
symbol.
p! { statements >; more statements }
Functions
Functions allows you to make abstractions if code gets too complex. Functions in this language only has one argument, and the argument and return type is a pair. If at by the end of the function it hasn't been returned to, then it will automatically returns with a null pair (a pair that has both of its pointers null).
func_name arg { statements }
To return, use the =
symbol to return with the pair at the front. Here is an example of a swap function that swap pointers.
swap p { = >p, <p; }
Calling a function can be done like this:
pair2 = swap pair;
Calling multiple functions at once will make it execute from right to left.
p = func1 func2 func3 func4 p; ~ which is just func1(func2(func3(func4(p))))
Calling a function with a null pair can be written shortly as:
p = func;
IO
To take inputs from the user, call the built-in function input
and it will return a pair the user has inputted. Outputting is kind of the same. When the built-in function output
is called, what's in the argument of the function will be outputted.
Here's a diagram of what will be returned of the input
function when inputting the word "Hi", for example.
Input / \ H . / \ i null H / \ 0 . / \ 0 . / \ 0 . / \ 1 . / \ 0 . / \ 0 . / \ 1 . / \ 0 null i / \ 1 . / \ 0 . / \ 0 . / \ 1 . / \ 0 . / \ 1 . / \ 1 . / \ 0 null
The 0s and 1s are both two constant pairs that are hardcoded into the language. 0
points to null and null, while 1
points to 1
and 1
.
Outputting is done by doing the same thing, just in reverse. Create a pair that has the same structure as above and pass it into the arguments of the output
function.
message = input; ~ Gets input from user output message; ~ Outputs it back output (0,1,0,1,),; ~ Print a newline (ASCII code 10) output message; ~ Output the message again
To input and output numbers, use the hardcoded input_num
and output_num
functions respectively. The numbers are structured like the ASCII characters, except with an extra bit at the beginning to tell whether the number is positive or negative. It's null if it's positive and 1
if it's negative. The number 0 is considered as positive. If the input isn't a number (i.e. has letters in it), it'll return null. If the output isn't a number, it will not print anything. Example if the number 25 is inputted:
Input / \ null . / \ 1 . / \ 0 . / \ 0 . / \ 1 . / \ 1 null
This here is all of the IO pairs and functions used in this language. These pairs are constant and will never change its value. Assigning a value to them won't have any effect.
Name | Points to | Description |
---|---|---|
0 |
null and null |
Used by the IO functions to represent 0 |
1 |
1 and 1 |
Used by the IO functions to represent 1 |
Name | Description |
---|---|
input |
Gets input from the user and returns that input as ASCII characters, argument is ignored |
output |
Outputs the argument as ASCII characters, function returns null |
input_num |
Gets input from the user and returns that input as a number, argument is ignored |
output_num |
Outputs the argument as a number, function returns null |
Examples
Note that since Pairpointing currently doesn't have an implementation, I don't know if some of these programs actually work. But at least it should in theory.
inp = input; inp! { output inp; inp = input; }
inp = input_num; output_num inp; <>inp? { output_num inp; }
and p { <p? >p? = 1; = 0; } or p { <p? = 1; >p? = 1; = 0; } not p { p? = 0; = 1; } xor p { and p? = 0; q = not <p, not >p; and q? = 0; = 1; }
H = 0, 0, 0, 1, 0, 0, 1, 0, ; e = 1, 0, 1, 0, 0, 1, 1, 0, ; l = 0, 0, 1, 1, 0, 1, 1, 0, ; o = 1, 1, 1, 1, 0, 1, 1, 0, ; c = 0, 0, 1, 1, 0, 1, 0, 0, ; ~ Comma s = 0, 0, 0, 0, 0, 1, 0, 0, ; ~ Space w = 1, 1, 1, 0, 1, 1, 1, 0, ; r = 0, 1, 0, 0, 1, 1, 1, 0, ; d = 0, 0, 1, 0, 0, 1, 1, 0, ; x = 1, 0, 0, 0, 0, 1, 0, 0, ; ~ Exclamation mark output H,e,l,l,o,c,s,w,o,r,l,d,x,;
S = 0, 0, 0, 0, 0, 1, 0, 0, ; ~ Space P = 0, 1, 1, 1, 0, 1, 0, 0, ; ~ Period C = 0, 0, 1, 1, 0, 1, 0, 0, ; ~ Comma L = 0, 1, 0, 1, 0, 0, 0, 0, ; ~ Newline b = 0, 1, 0, 0, 0, 1, 1, 0, ; o = 1, 1, 1, 1, 0, 1, 1, 0, ; t = 0, 0, 1, 0, 1, 1, 1, 0, ; l = 0, 0, 1, 1, 0, 1, 1, 0, ; e = 1, 0, 1, 0, 0, 1, 1, 0, ; s = 1, 1, 0, 0, 1, 1, 1, 0, ; f = 0, 1, 1, 0, 0, 1, 1, 0, ; r = 0, 1, 0, 0, 1, 1, 1, 0, ; n = 0, 1, 1, 1, 0, 1, 1, 0, ; h = 0, 0, 0, 1, 0, 1, 1, 0, ; w = 1, 1, 1, 0, 1, 1, 1, 0, ; a = 1, 0, 0, 0, 0, 1, 1, 0, ; T = 0, 0, 1, 0, 1, 0, 1, 0, ; k = 1, 1, 0, 1, 0, 1, 1, 0, ; d = 0, 0, 1, 0, 0, 1, 1, 0, ; p = 0, 0, 0, 0, 1, 1, 1, 0, ; i = 1, 0, 0, 1, 0, 1, 1, 0, ; u = 1, 0, 1, 0, 1, 1, 1, 0, ; N = 0, 1, 1, 1, 0, 0, 1, 0, ; ~ Capital N. Only used for: "No bottles of beer on the wall." bottles = 1, 1, 0, 0, 0, 1, 1, 0, ; 1! { output_num bottles; output S,b,o,t,t,l,e,s,S,o,f,S,b,e,e,r,S,o,n,S,t,h,e,S,w,a,l,l,C,L; ~ [bottles] bottles of beer on the wall, output_num bottles; output S,b,o,t,t,l,e,s,S,o,f,S,b,e,e,r,P,L, T,a,k,e,S,o,n,e,S,d,o,w,n,C,S,p,a,s,s,S,i,t,S,a,r,o,u,n,d,C,L; ~ [bottles] bottles of beer. ~ Take one down, pass it around, decrement bottles; >>bottles? , { ~ if bottles equals one output_num bottles; output S,b,o,t,t,l,e,S,o,f,S,b,e,e,r,S,o,n,S,t,h,e,S,w,a,l,l,P,L; ~ [bottles] bottle of beer on the wall. output_num bottles; output S,b,o,t,t,l,e,S,o,f,S,b,e,e,r,S,o,n,S,t,h,e,S,w,a,l,l,C,L; ~ [bottles] bottle of beer on the wall, output_num bottles; output S,b,o,t,t,l,e,S,o,f,S,b,e,e,r,P,L, T,a,k,e,S,o,n,e,S,d,o,w,n,C,S,p,a,s,s,S,i,t,S,a,r,o,u,n,d,C,L, N,o,S,b,o,t,t,l,e,s,S,o,f,S,b,e,e,r,S,o,n,S,t,h,e,S,w,a,l,l,P,L; ~ [bottles] bottle of beer. ~ Take one down, pass it around, ~ No bottles of beer on the wall. <; } output_num bottles; output S,b,o,t,t,l,e,s,S,o,f,S,b,e,e,r,S,o,n,S,t,h,e,S,w,a,l,l,P,L; ~ [bottles] bottles of beer on the wall. } decrement p { <p? { p = 0, >p; =; } p = 1, >p; decrement >p; }
Notes
- Pairs and functions can't have the same name at the same time. For example, you can't have a pair named
name
and a function namedname
at once. Since pairs and null argument function calls both look identical. - In Pairpointing, null is defined as a constant pair that points to null and null.
- Constant pairs are pairs that has pointers that can't change what it's pointing to. Pairs can't be set as constant manually in code.