Numbers

Numbers is an esoteric programming language created by User:Xorol. The main gimmick is that all of the commands (with some exceptions) are numbers. It uses two stacks, but only one can be used at a time.
==Data storage==
Numbers stores its data in two stacks: the main stack and the control stack. Most commands that perform operations on the stack are indifferent as to which stack they're using. But, most of the commands starting with 4 will only use the control stack.
===Toggling stacks===
You can toggle between stacks with the command 21. The program starts with the main stack selected.
==Commands==
Commands are split into four groups: arithmetic, stack manipulation, IO, and control flow. Arithmetic commands start with 1, stack commands with 2, etc.
Command 	Arguments 	Description
Arithmetic 	Arithmetic 	Arithmetic
10 	2 	Adds a + b
11 	2 	Subtracts a - b
12 	2 	Multiplies a * b
13 	2 	Divides a / b
14 	2 	Floor divides a // b
15 	2 	Modulos a % b
16 	1 	Increments a++
17 	1 	Decrements a--
18 	1 	1 if a is negative, else 0
19 	1 	Factorial a!
Stack manipulation	Stack manipulation 	Stack manipulation
20 	Syntactic 	Pushes the number after it to the stack. Alias: *
21 	0 	Toggles which stack is selected
22 	2 	Swaps a and b
23 	1 	Pops a
24 	1 	Moves a to the unselected stack
25 	1 	Moves a (from the unselected stack) to the selected stack
26 	1 	Duplicates a
27 	0 	Clears the stack
IO 	IO 	IO
30 	1 	Prints a as it is
31 	1 	Prints a as a character
32 	entire stack 	Prints the entire stack as integers, separated by spaces
33 	entire stack 	Prints the entire stack as a string
34 	0 	Gets input as an integer
35 	0 	Gets input as a character, pushing its Unicode representation
36 	0 	Gets input as a string, pushing each character's Unicode representation
Control flow 	Control flow 	Control flow
40 	1 	Only executes the next command if a is not 0
41 	1 	Only executes the next command if a is 0
42 	1 	Sets the pointer to a
44 	1 	Defines a function
45 	1, and syntactic args	Maps a as a function onto all following numbers
46 	entire stack 	Loads the file specified by the stack as a module
There's also a special command: ~ which ends the program.
===Further explanation===
=====20=====
Pushes the number after it to the stack. Examples:
 20 5
 *5
Both of these push 5 to the stack and are interchangeable. 
=====40 & 41=====
These will only execute the command after them if the top value on the stack is (or, in the case of 40 is not) 0. Examples:
This will print 1
 *1 40 30
This won't do anything
 *0 40 30
But this will
 *0 41 30
=====44=====
Defines a function, with the following syntax:
 *function_name 44 mapping_compatibility function_code 44
Replacing function_name with the name of the function, mapping_compatibility with either a 0 or 1 depending on whether the function is to be compatible with mapping (45), and function_code with the code for the function. For example:
 *6 44 0 *6 30 44
Defines a function 6, that is incompatible with mapping, and that prints a 6 whenever run. 
=====45=====
Maps the top value on the stack as a function onto all of its arguments. For example:
 *16 45 1 2 3 4 5 6 7 8 9 45
Maps 16 (increment) onto 1 2 3 4 5 6 7 8 9 and puts the results on the stack, in this case 2 3 4 5 6 7 8 9 10.
===Built-in functions===
Numbers has a number of built-in functions. All built-in functions are accessible using 10.x, replacing x with the name of the function.
Command	Arguments	Description
10 	2 	1 if a == b else 0
11 	2 	1 if a > b else 0
12 	2 	1 if a < b else 0
==Comments==
Comments in Numbers are done using a ;. For example:
 ; This is a comment
 *10 30 ; this is a comment
 *10 30 ;this is a comment
 *10 30; error: 30; is not a command
Block comments are done with a double semicolon (;;) at the start of the opening and closing lines:
 ;; Start of a block comment
 inside 
 still inside
 ;; End of the block comment
===Meta-comments===
Meta-comments start with ;! and must be on their own line. They are special comments and affect how the program runs. Here are the ones that are required for a Numbers implementation:
Comment 	Arguments	Description
NOBUILTINS	0 	Disables built-in functions
USE 	1 	Used for modules. Defines the namespace into which the module's contents should be loaded
The main implementation linked at the top also implements these meta-comments:
Comment	Description
NOILC 	Disables the interpreter's infinite loop checker
DEBUG 	Activates debug mode
TOOLS 	Opens the tool menu instead of running the program.
These are explained in full in the interpreter's README
==Stack references==
Stack references act as a way to use values that are not on top of the stack. They use the syntax $x, replacing x with the index from the top that is being referenced. These can be used as syntactic arguments only; if used as stand-alone commands, an error will be thrown. Examples:
 *$1 ; push the second item on the stack to the top
 44 $3 ... 44 ; using the fourth item as mapping compatibility
 
 $2 ; Error: stack references cannot be used as commands.
==Namespaces==
Namespaces are containers for functions. All functions within a namespace can be accessed using x.y, replacing x with the namespace's name and y with the function's name. Namespaces can also contain other namespaces, nesting infinitely. They can also be empty. To define one, use the following syntax:
 15 {
 1 : 0 : *1 30
 2 : {}
 }
This defines a namespace 15 with two things inside it: a function 1 (accessible as 15.1) and an empty namespace 2 (accessible as 15.2). Note how the syntax is different inside namespaces: functions use colons instead of the normal 44 syntax, and namespaces have a colon before the opening brace.
===Notes===
* Make sure you don't have a function spread across two or more lines; functions may only occupy a single line.
* Comments must be on separate lines.
===Modules===
Modules are just namespaces, but loaded in from a different file, all module files have the extension .nmod. For example, the code from earlier as a module would look like this:
 ;!USE 15
 1 : 0 : *1 30
 2 : {}
That ;!USE 15 defines the namespace the module's contents should be loaded as, besides that, the syntax is exactly the same as for namespaces. Once the module is loaded, the functions inside are accessible as if it were a normal namespace. 
To load a module, you have to get its filepath first. The filepaths are all relative to the location of the script. Here's an example filesystem with the corresponding filepaths beside them:
 root
 |-a.nmod (^^a)
 |--utils
 | |-b.mod (^b)
 | |--other
 | |-c.nmod (c)
 | |-script.nums
 |--math
 |-d.nmod (^^math/d)
 |--complex
 |-e.nmod (^^math/complex/e)
As you can see, / is used to go down a level and ^ is for going up a level. To load it, push the corresponding unicode representation to the stack and run 46.
==Example programs==
===Hello, world!===
The Hello World! program pushes each letter's corresponding ASCII values onto the stack, then prints the stack as a string.
 *20 45 72 101 108 108 111 32 87 111 114 108 100 33 45 33
===Truth-machine===
The truth-machine takes input from the user, if it is a "1" it outputs "1"s indefinitely, if it's a "0" it outputs a singular "0"
 34 26 26 30 41 ~ *2 42
===Cat program===
A cat program outputs whatever the user inputs.
 36 33
An infinite version:
 36 33 *0 42
Category:LanguagesCategory:2021Category:Stack-basedCategory:Turing completeCategory:Implemented