InDec

From Esolang
Jump to navigation Jump to search

InDec (Increment Decrement) is an esoteric programming language developed by Ettore Marmo in 2013.

Overview

There is no proper variable declaration in InDec, any alphanumeric string is a positive integer variable set to zero. Values cannot be assigned directly, the only possible operations on a variable are increase by one (++) or decrease by one (--).

a++

Instantiate the variable 'a' and add one to it. The numbers used are strictly greater or equal to 0, trying to decrement a zero valued variable in an algorithm will not stop the execution of the program but it's not a recommended practice. The curly brackets after an expression initiates a 'while' loop that gets executed only if the variable in the header is equal to zero

a { do stuff... }  

Note that

a ++ ++ ++ { ... }

actually modifies the variable 'a', InDec is meant to be very low-level, it translates The command

()

breaks the loop. The logical values are therefore inverted, 0 is True and everything else is False. Comments are enclosed between two double slashes

// This is a comment //

Semicolons add line breaks so that statements can be written in the same line at the expense of readability

Suffixes

A strange kind of suffixed functions can be defined in InDec with the keyword @. They have the following characteristics

  •  They must have at least one parameter
  •  They always return the first parameter
fn @ x,y,z {
    ...
}

translates to

function fn(x,y,z) {
    ...
    return x
}

When a suffix is applied with one or more variables as arguments, it modifies the first

a,b,c fn      //  a = fn(a,b,c) //

Function composition being lazily and badly implemented in the interpreter is a bit problematic and it does only work on one-argument functions.

a,b,c fn other      // a = other(fn(a,b,c)) // 

The basic operators can be applied as well with the following results

a,b,c fn --      // a = fn(a,b,c)-1 //

But for some reasons it behaves oddly in some cases

a,b,c fn -- other
a = other(fn(a,b,c)) -1

Output

InDec has a lot of nice ways to output values, the most basic being Assuming a=64, b=5, c=33

a .      // outputs 64 //
a,b,c . // outputs 64533 //

An & after a variable makes it being displayed as its corresponding character

a&,b,c .  // outputs @533 //
a&,b,c& . // outputs @5! //

An ? used in the same way prints True if the variable is equal to zero, False otherwise

a?,b . // outputs False5 //

A trailing comma after the '.' chops the newline after printing so that

a&.,
b.,

outputs @5 in the same line For better readability (or at least in the author's opinion) when applied after a multi-argument suffix, only prints the first one

a,b,c fn .

translates to

a = fn(a,b,c)     
print(a)

Import

Every file .indec file is also a module that can be imported with the following syntax

module1,module2,module3 import

The Interpreter

Written in python3.3 translates and executes .indec files.

python3 InDec.py filename.indec

The following arguments can be appended to the command

-d	Debug (prints the translated python code)
-t   Prints the time elapsed during the compilation and execution of the program

It can be downloaded here https://github.com/hektor41/Esolangs/tree/master/InDec It comes with some useful modules such as Operations, Logic etc...

Examples

This language is so low-level it doesn't have comparison operators or logic gates or even basic arithmetic functions, but it's powerful enough for them to be implemented (it's also fun to do).

Basic adders that simulates number assignments

add2  @ N { N add1  add1  }
add4  @ N { N add2  add2  } 
add8  @ N { N add4  add4 }
a add4 ++ // a = 5 //

Set N to zero

zero @ N {
    c                           // Declare variable c
        N {	                 // If N is already zero, skip the following loop by incrementing c
                c++		 // And then break the outer loop by incrementing c
                ()              // break
        }			
        c {                    // If N was larger than zero
                N-- {        // Decrement it until is equal
                        c++     // And then break the outer loop by incrementing c
                        ()      // break
                }
        }
	                  // omitted return N
}

In the condensed form

zero @ N {c;N{c++()}c{N--{c++()}}}

Note that there is no need for semicolons before the break () statement and after the closed brackets A related function

one @ N {N zero ++} //Set N to 1//

Every logical operator can be constructed using the two previous functions

//AND gate//
and @ R,P,Q {
    P {R one;Q{R zero()}()}
    Q {R one;P{R zero()}()}
}

The convention with these operators is to use three arguments where the first 'R' is the result and the other two are the values to compare so that P and Q won't get modified during the operation. It can be useful when dealing with loops

c,a,b and {
	...	
}	

means

c = and(c,a,b)
while c {...}

and a and b are left untouched

Addition

add @ X,Y {
   	 // Set X to X+Y //
   	 c
   	 Y {c++;()} // Catch X+0 //
   	 c {
                X++
                Y-- {c++;()}
   	 }
}	

Multiplication

mul @ X,Y {
        // Set X to X*Y // 
        c
        multiplicator,X add 
        Y {X zero;c++;()}  // Catch X*0 // 
        c {
                X,multiplicator add
                Y-- {c++;()}
        }
}

Factorial

fact @ X {
        // Set X to X! // 
        c
        result++
        X {c++;()} // 0! = 1 // 
        c{
                result,X mul
                X--{c++;()}
        }
                            // X's value is now zero //
        X,result add // X's value is now the result //
}

The whole language is completely inefficient (computing 10! takes 30.4335 seconds), but that's not much of a surprise is it? Everything is still being worked on if you have any idea write it in the talk section


HelloWorld.indec

Operations import

SPACE add32
H   add64 add8
d,H add add16 add8 add4
e,d add ++
l,e add add4 add2 ++
o,l add add2 ++
W,H add add8 add4 add2 ++
r,o add add2 ++

H&,e&,l&,l&,o&,SPACE&,W&,o&,r&,l&,d& .
// Always leave some newlines at the end of the file just in case... //