DINAC

From Esolang
Jump to navigation Jump to search

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 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 since 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, you have to be prepared for the condition being either true (1) or false (0). To make an IF-ELSE statement, use the following:

IF condition
    code if true
ELSE
    code if false

(include a space right after the IF). If condition is a wubyte, it will evaluate to false if it's equal to 0, otherwise true; an aschar, the same thing but with its Unicode value; a snuval, 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

(include a space right after the WHILE). To make a do-while loop, you can simply use the following:

IF condition
    WHILE condition
        code
ELSE
    code

(the conditions should be the same and so should the codes).

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 for 1 char

SET c:\0
WHILE 01
    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