naz

From Esolang
Jump to navigation Jump to search
naz
Paradigm(s) imperative
Designed by sporeball
Appeared in 2019
Computational class FSA
Major implementations Original
File extension(s) .naz
Note that naz is typically lowercased, even at the start of a sentence.

naz is an esoteric programming language designed by sporeball in 2019. Each instruction in a naz program is given by one number, from 0 to 9 (referred to as n), and one letter, from A to Z.

Overview

naz programs operate on a single register, whose value starts at 0 and can be between -127 and 127, inclusive. A number of arithmetic instructions can be used to manipulate this value, and custom variables and functions can be declared during runtime to allow for more complex programs. Final output, if any, is only shown once a program finishes running.

List of instructions

Literals

0-9 - A number literal; exactly one of these must be placed before every instruction.

Arithmetic

a - Adds n to the register.

s - Subtracts n from the register.

m - Multiplies the register by n.

d - Divides the register by n, rounding down.

p - Divides the register by n, then sets the register equal to the remainder.

I/O

o - Outputs a value n times. The value that is output depends on the value in the register:

  • 0-9 - Outputs that number.
  • 10 - Outputs a newline.
  • 32-126 - Outputs the character with that ASCII value.

r - Sets the register equal to the ASCII value of the n-th character in the input string, then removes that character from the input string.

Conditional

l - Executes the n-th function if the value in the register is less than the value of the previously referenced variable.

e - Executes the n-th function if the value in the register is equal to the value of the previously referenced variable.

g - Executes the n-th function if the value in the register is greater than the value of the previously referenced variable.

The 3 instructions above can only be run in opcode 3.

Other

f - Function instruction:

  • If run in opcode 0, this instruction calls function n.
  • If run in opcode 1, this instruction begins declaration of function n.

v - Variable instruction:

  • If run in opcode 0, this instruction sets the register equal to the value of variable n.
  • If run in opcode 2, this instruction sets variable n equal to the value in the register.

n - Negates variable n.

x - Sets the current opcode to n.

h - Halts program execution.

Opcodes

0 - Default operation. Instructions will execute one at a time, in order.

1 - Function write. The interpreter must parse a call to the f instruction; instructions will then be added onto the end of the referenced function until a newline is parsed or the opcode is explicitly set to 0.

2 - Variable write. The interpreter must parse a call to the v instruction; once it does, it will return to opcode 0.

3 - Conditional opcode. The interpreter must parse a call to the v instruction, followed by a call to a conditional instruction; after it finishes executing (or not executing) the given function, the interpreter will return to opcode 0.

Examples

Hello, World!

This program outputs Hello, World!:

9a8m1o
9a9a9a2a1o
7a2o
3a1o
3d7a1o
9s3s1o
8a2m7a1o
9a9a6a1o
3a1o
6s1o
8s1o
3d1o

Without newlines:

9a8m1o9a9a9a2a1o7a2o3a1o3d7a1o9s3s1o8a2m7a1o9a9a6a1o3a1o6s1o8s1o3d1o

Custom functions

This program outputs A, then defines a function that can be reused to output subsequent letters; the final output is ABCDE.

9a7m2a1o
1x1f1a1o
1f1f1f1f

Alphabet

A number of concepts are illustrated in this program:

  • Two functions are defined, creating a loop where the register value can be incremented and output on each step.
  • Opcode 2 is used to set the value of variable 1 equal to 90.
  • Opcode 3 is used in one of the functions to check that the register is less than variable 1.

The final output of this program is ABCDEFGHIJKLMNOPQRSTUVWXYZ.

9a9m9a2x1v
1x2f3x1v1l
1x1f1a1o2f
9s9s8s
3x1v1l

Computational class

naz is at least as powerful as a finite-state automaton, because it can implement dd.

The following naz program produces valid dd output given any input file terminated with the control character STX (U+0002):

2a2x1v
9a9m1a2x2v
9a9a9a2x3v

1x1f2v2o2f
1x2f1r3x1v5e3x2v3e3x3v4l
1x3f1r3x1v5e3x2v1e3x3v2l
1x4f2f
1x5f0a

2f

naz can be no better than a FSA. It has finitely many variables, functions, and the register. The variables and register are both bounded arbitrarily. The functions, while unbounded, can only be appended to. They cannot be cleared, copied, or compared.

If the arbitrary bounds on the variables and register are removed (e.g. by using the -u flag on the command line), the language becomes Turing complete. It is possible, just barely, to implement a Turing machine with up to 6 states and up to 9 symbols by treating 0v and 1v as the left half and right half of a Turing machine tape, each considered as representing a base-n digit string where n is the number of symbols. 4 functions are dedicated to adding the register to each of these variables, leaving the remaining 6 functions to handle all the symbol reading, writing, tape moving (using the previously mentioned functions) and state transitioning for each of the 6 states. Since there is a universal Turing machine with 5 states and 7 symbols, this capability is sufficient for universality. As such, naz is a Bounded-storage machine.

External resources