DINAC
DINAC is an esolang made by User:PythonshellDebugwindow.
Datatypes
The only datatypes in DINAC are the wrapping unsigned byte (wubyte), the ASCII character (aschar), and the standard nullified value (snuval, basically null). All wubyte literals match the following regex: [0-9A-F]{2}
(case-sensitive), as they're essentially 2-char hex literals, all aschar literals are a single quote (') followed by any ASCII char (Unicode index 0-127) or a valid 2-char escape code (\0, \n, \t, \r, or \\), and the snuval (the default function return value if no value is explicitly returned) is represented by the dollar sign $.
Variables
To create a variable in DINAC, you can use the following:
SET vname:value
(no spaces) which would set the variable vname (which much match the regex [a-z][A-Za-z0-9]*
and not be a keyword or the name of a previously-created variable/function) to value (any value). Don't worry about name conflict with wubyte literals, as the first character of a wubyte is numeric or lowercase alphabetical while the first character of an identifier is lowercase alphabetical. To change a variable (to the same type — see below), you can use the following:
vname . value
(1 space on either side of the period) once the variable vname has already been declared and if value is of vname's type.
Variables in DINAC are strongly typed, as if you initialize a variable as an aschar you can't later change it to a wubyte. The type of a variable is implied from its initial value's type, so for this reason you must give a variable a non-snuval initial value. The snuval is special in that it can be assigned to a variable of either type, so therefore if a variable was initialized with it, it's type would be arbitrary.
Input/Output
Output in DINAC is simple. You simply have to use the following:
OUT value
(1 space after OUT) and it will be printed to STDOUT without a newline. value here can be a variable, function, value, etc. Wubytes are printed as their 2-char literals in the source code, and aschars are printed as would be expected—their character, or escape code, is printed out. Input is a bit more complicated, as you first have to create a variable, much like the Bash read command. To read an ASCII character:
IN vname
(1 space after IN), where vname has been initialized as an aschar, will get the first character of user input from STDIN (not live). Empty input returns \n. To read an unsigned byte (in 1-3 char base-10 form), do the same but where vname has been initialized as a wubyte. Empty input or invalid wubyte (including <0 or >255) will return 00.
Comments
Anything after # is a comment until end-of-line.
Operators
Arithmetic
The only mathematical operations available by default in DINAC are +
(plus 1) and -
(minus one). The syntax for + is N+
(no space allowed between N and +), where N is any wubyte, and it will return N + 1; the same goes for -, which will return N - 1. If the result of either of these is greater than 256, it will be moduloed by 256, or if it's less than 0, it will be subtracted from 256. These operators never modify a variable, so the DINAC equivalent of the C code x++;
is x . x+
and x--;
is x . x-
. They also work for aschars, with the same syntax — it will return the previous/next Unicode character, moduloed by 128 or subtracted from 128 just like with a wubyte.
Comparison
DINAC provides the equality operator =
, which returns 1 if the values on both sides are the same or 0 otherwise, and the inequality operator !
, which returns 0 if the values on both sides are the same or 1 otherwise. To check if a == b, you could write a = b
, or to check if a != b then use ~(a = b)
as ~
is the NOT operator and returns 1 if its operand (here (a = b)
) is equal to 0, otherwise 0, and parentheses can be used for grouping, in this case so the ~
doesn't just operate on a.
Boolean
As shown above, DINAC uses ~
as the NOT operator, returning 1 if its operand is 0 else 0, but as things like AND, OR, and XOR can easily be implemented, it's left to the programmer to implement them.
Indentation
Used in IF-ELSE statements, WHILE loops, and function bodies, indentation is achieved by putting 4 spaces before a line of code. To get N levels of indentation, you put N × 4 spaces before the line.
Control flow
DINAC includes two ways alter control flow, the IF-ELSE
statement and the WHILE
loop. The IF and ELSE keywords always come in pairs, and null statements (expressions or statements that don't affect the program in any way, such as setting a variable to itself, initializing a variable whose value is never used, or typing something like 00 = 00
or F6+
) aren't allowed in either branch. To make an IF-ELSE statement, use the following:
IF condition code if true ELSE code if false
If condition is a wubyte, it will evaluate to false iff it is equal to zero, otherwise true; if it is an aschar, it will be false iff its Unicode value is equal to zero; and a snuval is always false.
The WHILE loop is a bit different, but it uses the same true/false evaluation method. To make one, use the following:
WHILE condition code
Functions
0-argument non- or snuval-returning functions in DINAC can be declared with the following:
DEF/$ fname code
(space before the fname). Then to call it:
fname()
(no space after the fname). Function names must match the same regex as variable names ([a-z][A-Za-z0-9]*
). The $
here symbolizes that this function will return a snuval; you can change it to any wubyte to signal that it will return a wubyte and the same for aschars. Here is a simple add-1 function:
DEF/00 add1 n:00 GIVE n+
that demonstrates parameters (same as variable initializers but the value doesn't matter, the type does, and minus the SET keyword) and returning values (with the GIVE keyword); if you have declared a function with DEF/$, you don't have to return at all, but if you do want to return, you have to type GIVE $
, not just GIVE
. To print the the result of function with 1 passed:
OUT add1(1)
this should output 2. If a function is supposed to return a non-snuval value and doesn't return something with the right type, or anything at all, the program will raise an error. Overloading is possible, e.g.
DEF/00 add1 n:00 GIVE n+ DEF/\0 add1 n:\0 GIVE n+
won't give an error, but this:
DEF/00 add n:00 GIVE n+ OUT add(10,20)
will, as no overload for add takes 2 wubytes as arguments.
Example programs
Hello, World!
OUT 'H OUT 'e OUT 'l OUT 'l OUT 'o OUT ', OUT ' OUT 'W OUT 'o OUT 'r OUT 'l OUT 'd OUT '! OUT \n
Truth-machine
SET zeroOrOne:\0 IN zeroOrOne IF zeroOrOne = '1 WHILE 01 OUT '1 ELSE OUT 00
Cat program
SET c:\0 IN c WHILE c IN c OUT c
Interpret PlusOrMinus 1 char at a time
DEF/\0 aschar n:00 SET res:\0 WHILE n ! 00 res . res+ n . n- GIVE res SET c:\0 SET acc:00 IN c WHILE 01 IF c = '+ acc . acc+ IN c ELSE IF c = '- OUT aschar(acc) acc . acc- IN c ELSE IN c
Interpret Deadfish 1 char at a time (maybe)
DEF/00 add a:00 b:00 WHILE b a . a+ b . b- GIVE a DEF/00 and a:00 b:00 IF a GIVE ~~b ELSE GIVE 00 DEF/00 greater a:00 b:00 WHILE and(a,b) a . a- b . b- GIVE ~~a DEF/00 mul a:00 b:00 SET res:00 WHILE b res . add(res,a) b . b- GIVE res DEF/00 sub a:00 b:00 WHILE b a . a- b . b- GIVE a SET high:00 SET low:00 SET x:00 SET c:\0 IN c WHILE 01 IF c = 'i IF low = FF low . 00 ELSE low . low+ IN c ELSE IF c = 'd IF low = 00 IN c ELSE low . low- IN c ELSE IF c = 's x . mul(low,low) IF ~greater(low,0F) low . x ELSE high . sub(low,x) low . x IF and(high = 01, low = 00) high . 00 IN c ELSE IN c ELSE IF c = 'o OUT high OUT low IN c ELSE IN c
Glossary
- wubyte: Wrapping unsigned byte, an integer 0-255 and DINAC's only numeric datatype
- aschar: ASCII character, a Unicode character with index 0-127
- snuval: Standard nullified value, null value that can be assigned to any variable
Keywords are DEF
, ELSE
, GIVE
, IF
, IN
, OUT
, SET
, and WHILE
.
Subpages
- /STDLIB, some useful functions you can use in your programs