Nand1
| Paradigm(s) | imperative |
|---|---|
| Designed by | User:craftyBLUE |
| Appeared in | 2025 |
| Computational class | Turing complete |
| Major implementations | Original |
| File extension(s) | .nand1 |
Nand1 is a programming language with just one instruction based on the logical operator NAND. It works with a memory of just binary values with minimal Memory I/O. A command is a number, the address of the cell being modified.
Hello, World! program example with only 68 commands:
0 17 20 3 0 20 18 21 23 3 0 23 20 3 3 22 23 3 0 17 0 22 0 23 3 0 20 0 21 3 0 18 17 19 21 22 23 3 0 19 18 20 3 0 20 0 21 0 23 19 3 0 19 0 22 20 21 3 0 20 3 0 17 0 21 23 3 2
Program flow
Nand1 takes inputs from the source code .nand1 file as nonnegative numbers (in base 10), let's say X
The language will execute the following steps in order:
- compare bits in memory at position 0 and at position X with the NAND operator ( not (A and B) )
- set the bit at location X to be the same as the bit at position 0
- set the bit at location 0 to the result from step 1.
This is repeated for every command.
When the end of the source code file is reached, NAND1 starts running commands again starting from the begining of the file, in an infinite loop. To stop the program you must write value 1 to the position of the Halt signal in memory.
Memory-mapped I/O
NAND1's memory is entirely made of binary zeros and ones (0 and 1, false and true). To make the program connected to the world we have to "hijack" some addresses in memory and use them as our window to the outside world. The layout of this mapping is shown with a table:
| Address | Name | |
|---|---|---|
| 0 | Primary register | |
| 1 | Secondary register | |
| 2 | Halt signal | |
| 3 | Write output signal | |
| 4 | Read input signal | |
| ⋮ | RESERVED | |
| 16 | Output byte | |
| 17 | ||
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | ||
| 22 | ||
| 23 | ||
| 24 | Output byte | |
| 25 | ||
| 26 | ||
| 27 | ||
| 28 | ||
| 29 | ||
| 30 | ||
| 31 | ||
| ⋮ | ||
Up to 2^32 (4294967296) bits of memory are avaiilable, that is 512 MiB of RAM on an actual machine running the code.
Signals fire with the rising edge of the values at their positions in memory (setting a 1), they are set to 0 in the next step.
Input and output is conscidered to be in ASCII form.
Examples
Flipping a bit
0
Location 0 is our register, following the steps defined above we conclude that the new value in the register is inverted from the old value.
Forcing a value into the register
Force a 1
1 0 1 1
No matter the state of both registers the one in the primary register will be 1.
Force a 0
1 0 1 1 0
(Force a 1) + (Flipping a bit) = (Force a 0)
cat/echo
1 0 1 1 4 1 0 1 1 16 1 0 1 1 17 1 0 1 1 18 1 0 1 1 19 1 0 1 1 20 1 0 1 1 21 1 0 1 1 22 1 0 1 1 23 1 0 1 1 24 0 24 0 16 1 0 1 1 25 0 25 0 17 1 0 1 1 26 0 26 0 18 1 0 1 1 27 0 27 0 19 1 0 1 1 28 0 28 0 20 1 0 1 1 29 0 29 0 21 1 0 1 1 30 0 30 0 22 1 0 1 1 31 0 31 0 23 1 0 1 1 3
- Request an input (one char)
- Prepare output addresses for easy copying
- Copy input to output
- Request a write (one char)
Note that the program continues forever because we don't touch the Halt signal.
Hello, World!
(Nand1 does not support comments cuurently) CraftyBLUE (talk) 01:05, 27 November 2025 (UTC)
0 # set register to 1 17 20 # write ascii binary value of 'H' 3 # output char to the console 0 20 # unset values of ascii 'H' 18 21 23 # set other needed for 'e' (note the overlap in the ascii code) 3 # ... 0 23 20 # 'l' 3 3 # print 'l' 2 times 22 23 # 'o' 3 0 17 0 22 0 23 # ',' 3 0 20 0 21 # ' ' 3 0 18 17 19 21 22 23 # 'W' 3 0 19 18 20 # 'o' 3 0 20 0 21 0 23 19 # 'r' 3 0 19 0 22 20 21 # 'l' 3 0 20 # 'd' 3 0 17 0 21 23 # '!' 3 2 # Halt signal
Arithmetic
Proof of concept examples of a binary counter and a fibonacci sequence generator are located in the GitHub repository. Other arithmetic programs are yet to be written...
Notes and observations
- Nand1 code itself does not support branching. The program always runs the same commands, doing the same operations again and again. However, the memory that the program is manipulating can be different with a different set of inputs due to the way the NAND operator works. Conditional code is possible all be it in a very roundabout way. (Simple example of this pending...)
- The secondary register (position 1 in memory) is not needed, what I mean by that is: Yes you can use any other location in memory for whatever you use position 1 for, but in my oppinion position 1 better be reserved for simple operations needed to be done without thinking for example forcing a value into the primary register (position 0). "1" is easier to write than most other numbers available. CraftyBLUE (talk) 01:05, 27 November 2025 (UTC)