Ndim

Ndim is an esoteric programming language created by User:Schlafhase
In Ndim there are n dimensions. Every program starts with
 [number]dim
where number sets the amount of dimensions. So for example
 2dim
would be the start of a 2 dimensional ndim program. There is a pointer that points either in the positive or negative direction of an axis in the n dimensional space. Ndim stores 2 values. (similar to a stack). Let's call the first value a and the second value b for this documentation. Every command is stored in a n dimensional coordinate system. You can also store values in the coordinate system. The pointer moves in a specified direction until it hits a command or value. Commands get executed and values get pushed to the stack. The pointer points in the positive direction of the first axis (or `1` in ndim syntax) at the start of every program. And every value is an integer.
This language is inspired by befunge
=The "stack"=
Ndim has a stack-like structure storing two values called a and b. a and b are 0 by default.
Pushing to the stack is done by overwriting the value of b with the current value of a. And then overwriting the value of a with the integer.
Popping from the stack is done by overwriting the value of a with value of b. And then overwriting the value of b with 0.
=What does left or right mean?=
To get the coordinate to the right of the current coordinate in ndim you use the following code
 right = currentCoordinate
 right[Math.Abs(pointerDirection) % n] += 1
left is the same but with "-="instead of "+=" so
 left = currentCoordinate
 left[Math.Abs(pointerDirection) % n] -= 1
==Example==
 n = 2
 currentCoordinate = <10, 20>
 pointerDirection = -2
 
 right = currentCoordinate //right is <10, 20> after this line
 right[2 % 2] += 1 //right is <11, 20> after this line
=Syntax=
Ndim's Syntax looks like this:
 [command]<[coordinate]>;
Where command stands for the command and coordinate for the coordinate in the n dimensional coordinate system.
Every line ends with a ";"
Everything behind the ";" will be ignored. Another way to make comments is by writing // at the start of a line.
Note: Every line matching the following regular expression is (probably) a valid line of ndim code
 ^\s*((-?\d+|\?|jump)|(#\d|pop|swap|duplicate|\+|-|\*|/|\^|&|\||!|<|>)|if\s+\d+|(assignHere|assign|toggleEat|input|printChar|print)|end) *(<)([\d, -]+)(>);
==Syntax Highlighting==
Download a Highlighting Extension for vscode and use the Ndim configuration file
=Commands=
Note: Every command needs to have its coordinate specified in <> brackets behind it like described above.
The [] brackets stand for parameters of the commands. They are not actually valid syntax.
 Ndim commands
Command 	Description
[number]dim	Specify how many dimensions the program has. Every program must begin with this line. It will throw a Syntax Error if it appears anywhere but on the first line.
[axis] 	Set direction of the pointer to the positive direction of the specified axis. (axis is an integer like everything else)
-[axis] 	Set direction of the pointer to the negative direction of the specified axis.
? 	Set direction of the pointer to a random direction.
jump 	Skip any command that comes immediately after this command.
#[digit] 	Push digit to the stack.
pop 	Pop a value from the stack and discard it.
swap 	Swap the values of a and b.
duplicate 	Overwrite the value of b with a's value.
+ 	Pop the values a and b from the stack and push a + b to the stack.
- 	Pop the values a and b from the stack and push b - a to the stack.
* 	Pop the values a and b from the stack and push a * b to the stack.
/ 	Pop the values a and b from the stack and push b / a to the stack.
^ 	Pop the values a and b from the stack and push b ^ a to the stack. (Math.Pow(b, a) not XOR)
< 	Pop the values a and b from the stack. If b < a push 1 to the stack.
> 	Pop the values a and b from the stack. If b > a push 1 to the stack.
& 	Pop the values a and b from the stack. If a and b are both greater than 0 push 1 to the stack.
 	Pop the values a and b from the stack. If a or b is greater than 0 push 1 to the stack.
! 	Pop a value a from the stack. If a is greater than 0 push 0 to the stack else push 1.
if [value] 	Pop a value a from the stack. If a is equal to value point the pointer to the right else point the pointer to the left.
input 	Ask for an input and then push it to the stack. Throw Exception if the input is not an integer.
assign 	Pop a value a from the stack and store it to the right of the pointer. (this will overwrite commands and other values stored at that position)
assignHere 	Pop a value a from the stack and store it at the current position of the pointer. (this will overwrite itself)
toggleEat 	Toggles the eat mode. When the eat mode is enabled, commands and values get deleted from the coordinate system after the pointer hit them. (they still get processed one last time)
print 	Pop a value from the stack and output it.
printChar 	Pop a value of the stack and output it as a character.
end 	Ends the program. (programs not containing this will run forever)
=Interpreter=
You can find a Ndim Interpreter by User:Schlafhase here.
==Esoteric IDE==
EsotericIDE also supports Ndim. It supports debugging and shows a visualised version of the Ndim program in the Watch window which makes it alot easier to program in Ndim
=Examples=
==Hello, World!==
 2dim;
 #9 <0,0>;
 #8 <1,0>;
 * <2,0>; //9*8 = 72
 assign <3,0>; //store 72 at <3,1>
 #7 <4,0>;
 duplicate <5,0>;
 * <6,0>; //7*7 = 49
 #2 <7,0>;
 * <8,0>; //49*2 = 98
 #3 <9,0>;
 + <10,0>; //98+3 = 101
 duplicate <11,0>;
 assign <12,0>; //store 101 at <12,1>
 #7 <13,0>;
 + <14,0>; //101+7 = 108
 duplicate <15,0>;
 assign <16,0>; //store 108 at <16,1>
 duplicate <17,0>;
 assign <18,0>; //store 108 at <18,1>
 #3 <19,0>;
 + <20,0>; //108+3 = 111
 assign <21,0>; //store 111 at <21,1>
 #6 <22,0>;
 #7 <23,0>;
 * <24,0>; //6*7 = 42
 #2 <25,0>;
 + <26,0>; //30+2 = 44
 duplicate <27,0>;
 assign <28, 0>; //store 44 at <28,1>
 #9 <29,0>;
 - <30,0>; //44-9 = 35
 #3 <31,0>;
 - <32,0>; //35-3 = 32
 assign <33,0>; //store 32 at <33,1>
 #9 <34,0>;
 duplicate <35,0>;
 * <36,0>; //9*9 = 81
 #6 <37,0>;
 + <38,0>; //81+6 = 87
 duplicate <39,0>;
 assign <40,0>; //store 87 at <40,1>
 #9 <41,0>;
 + <42,0>; //87+9 = 96
 #9 <43,0>;
 + <44,0>; //96+9 = 105
 #6 <45,0>;
 + <46,0>; //105+6 = 111
 duplicate <47,0>;
 assign <48,0>; //store 111 at <48,1>
 #3 <49,0>;
 + <50,0>; //111+3 = 114
 duplicate <51,0>;
 assign <52,0>; //store 114 at <52,1>
 #6 <53,0>;
 - <54,0>; //114-6 = 108
 duplicate <55,0>;
 assign <56,0>; //store 108 at <56,1>
 #8 <57,0>;
 - <58,0>; //108-8 = 100
 assign <59,0>; //store 100 at <59,1>
 #5 <60,0>;
 #6 <61,0>;
 * <62,0>; //5*6 = 30
 #3 <63,0>;
 + <64,0>; //30+3 = 33
 assign <65,0>; //store 33 at <65,1>
 2 <68,0>; //point the pointer "up"
 -1 <68,2>; //point the pointer "left"
 -2 <0,2>; //point the pointer "down"
 1 <0,1>; //point the pointer "right"
 printChar <5,1>;
 printChar <13,1>;
 printChar <17,1>;
 printChar <19,1>;
 printChar <22,1>;
 printChar <29,1>;
 printChar <34,1>;
 printChar <41,1>;
 printChar <49,1>;
 printChar <53,1>;
 printChar <57,1>;
 printChar <60,1>;
 printChar <66,1>;
 end <67,1>;
==readable code==
You can use comments to make your code more readable.
 2dim;
 input <0, 0>;
 if 0 <2, 0>;
 //{
 input <2, 1>;
 #2 <2, 2>;
 * <2, 3>;
 print <2, 4>;
 end <2, 5>;
 //}
 //else
 //{
 input <2, -1>;
 #3 <2, -2>;
 * <2, -3>;
 print <2, -4>;
 end <2, -5>;
 //}
But since the order doesn't matter you can arrange the commands however you like!
For example alphabetically:
 2dim; //except this line because it has to be at the top
 #2 <2, 2>;
 #3 <2, -2>;
 * <2, 3>;
 * <2, -3>;
 end <2, -5>;
 end <2, 5>;
 if 0 <2, 0>;
 input <0, 0>;
 input <2, -1>;
 input <2, 1>;
 print <2, -4>;
 print <2, 4>;
==Factorial==
Here is a Ndim program that takes an input x and outputs x! (x factorial). This took me over 5 hours.
 3dim;
 input <0, 0, 0>; //ask for input
 duplicate <5, 0, 0>;
 assign <10, 0, 0>; //store input at <10, 1, 0>
 #2 <15, 0, 0>;
 < <20, 0, 0>;
 if 0 <25, 0, 0>;
 //if input was not smaller than 2
 //{
 -1 <25, 5, 0>;
 #1 <24, 5, 0>; //push 1 as starting value
 2 <23, 5, 0>; 
 
 //get previous value
 -1 <23, 6, 0>;
 jump <8, 6, 0>;
 -2 <6, 6, 0>;
 1 <6, 4, 0>;
 2 <22, 4, 0>;
 -1 <22, 5, 0>;
 //add one to previous value
 #1 <20, 5, 0>;
 + <15, 5, 0>;
 duplicate <14, 5, 0>;
 //store new previous value
 assign <13, 5, 0>; //<13, 6, 0>
 //get original input
 -2 <12, 5, 0>;
 -1 <12, 1, 0>;
 2 <9, 1, 0>;
 -1 <9, 5, 0>;
 2 <8, 5, 0>;
 > <8, 10, 0>;
 if 1 <8, 15, 0>;
 //if the current value is greater than the original input
 // {
 //get previous multiplied result and print it
 -2 <8, 15, 4>;
 -1 <8, 6, 4>;
 -3 <-4, 6, 4>;
 -1 <-4, 6, 0>;
 print <-6, 6, 0>;
 end <-7, 6, 0>;
 // }
 // else 
 // {
 //get previous value then go to line <7, 7, 0>
 -2 <8, 15, -1>;
 1 <8, 6, -1>;
 3 <13, 6, -1>;
 -1 <13, 6, 3>;
 2 <7, 6, 3>;
 -3 <7, 7, 3>;
 //get previous multiplied value
 -2 <7, 7, 0>;
 3 <7, 6, 0>;
 -1 <7, 6, 1>;
 -3 <-5, 6, 1>;
 -1 <-5, 6, -1>;
 2 <-6, 6, -1>;
 1 <-6, 7, -1>;
 -2 <1, 7,-1>;
 3 <1, 5, -1>;
 -1 <1, 5, 0>;
 //multiply both then store the new value
 * <0, 5, 0>;
 assign <-5, 5, 0>; //<-5, 6, 0>
 #1 <-5, 6, 0>;
 2 <-13, 5, 0>;
 1 <-13, 13, 0>;
 //go to line 15
 -2 <23, 13, 0>;
 // }
 //}
 //else
 //{
 #1 <25, -5, 0>;
 print <25, -10, 0>;
 end <25, -15, 0>;
 //}
You can also do it like this if you like to have your code sorted.
 3dim;
 #1 <-5, 6, 0>;
 #1 <20, 5, 0>;
 #1 <24, 5, 0>;
 #1 <25, -5, 0>;
 #2 <15, 0, 0>;
 * <0, 5, 0>;
 + <15, 5, 0>;
 -1 <-4, 6, 0>;
 -1 <-5, 6, -1>;
 -1 <1, 5, 0>;
 -1 <12, 1, 0>;
 -1 <13, 6, 3>;
 -1 <22, 5, 0>;
 -1 <23, 6, 0>;
 -1 <25, 5, 0>;
 -1 <7, 6, 1>;
 -1 <8, 6, 4>;
 -1 <9, 5, 0>;
 -2 <1, 7,-1>;
 -2 <12, 5, 0>;
 -2 <23, 13, 0>;
 -2 <6, 6, 0>;
 -2 <7, 7, 0>;
 -2 <8, 15, -1>;
 -2 <8, 15, 4>;
 -3 <-4, 6, 4>;
 -3 <-5, 6, 1>;
 -3 <7, 7, 3>;
 1 <-13, 13, 0>;
 1 <-6, 7, -1>;
 1 <6, 4, 0>;
 1 <8, 6, -1>;
 2 <-13, 5, 0>;
 2 <-6, 6, -1>;
 2 <22, 4, 0>;
 2 <23, 5, 0>;
 2 <7, 6, 3>;
 2 <8, 5, 0>;
 2 <9, 1, 0>;
 3 <1, 5, -1>;
 3 <13, 6, -1>;
 3 <7, 6, 0>;
 < <20, 0, 0>;
 > <8, 10, 0>;
 assign <-5, 5, 0>;
 assign <10, 0, 0>;
 assign <13, 5, 0>;
 duplicate <14, 5, 0>;
 duplicate <5, 0, 0>;
 end <-7, 6, 0>;
 end <25, -15, 0>;
 if 0 <25, 0, 0>;
 if 1 <8, 15, 0>;
 input <0, 0, 0>;
 jump <8, 6, 0>;
 print <-6, 6, 0>;
 print <25, -10, 0>;
Category:Languages Category:Multi-dimensional languages Category:Implemented Category:Stack-based