LICE

Name
LICE stands for the LISP INTERCAL C Esoteric language.

Syntax
prog --> exp1 exp2             ` exp1: command line, exp2: exit code ` exp --> (exp1 exp2 exp3)        ` assignment ` --> .num                   ` integer variable ` --> ,num                   ` array of integer variables ` --> ;num                   ` floating-point variable ` --> :num                   ` macro ` --> #num                   ` numeric constant ` --> $num                   ` I/O handle ` --> binop exp1 exp2        ` arithmetic etc. on expressions ` --> unop exp               ` arithmetic etc. on expressions ` --> [exp-list] exp1 exp2   ` arithmetic if-then-else ` --> {exp-list}             ` array constant ` --> 'char                  ` character constant ` --> "char-list"            ` array of character constant ` binop --> +        ` addition ` --> -       ` subtraction ` --> *       ` multiplication ` --> /       ` division ` --> %       ` remainder ` --> &       ` bitwise AND ` --> |       ` bitwise OR ` --> ^       ` bitwise XOR ` --> <       ` less-than ` --> =       ` equals ` --> >       ` greater-than ` --> @       ` array concatenation and INTERCAL mingle ` --> !       ` array indexing and INTERCAL select ` unop --> ~        ` bitwise NOT ` --> ?       ` random number ` --> \       ` converts nonzero to #1 ` char --> character      ` Unicode codepoint of character (not \) ` --> \character    ` escaped character (like in C) ` num              ` a decimal integer `

Description
Whitespace is ignored (except in special syntax:,   and  ). The backquote  is used to open and close comments. There has to be a space either side of each  - this allows for extension to the language.

The most important construct is the assignment. This evaluates  and assigns   (an lvalue) to it. The whole assignment-expression then evaluates to.

All variables are global. Each variable has a number, and a symbol in front for its type:  integer,   array of integers,   floating-point and   for I/O handles (see below).

Type coercion is done automatically between integers and floating-point numbers, in the C way, but arrays cannot be coerced into scalars, nor vice-versa (use indexing and array constants).

Integer constants are like integer variables, but with  in front. Array constants are written within braces ; the entries are just a list of expressions (no separators). For text, a shorthand can be used:  in front of a character other than   is that character's Unicode codepoint, and   can be used for C-style escapes. Array constants of characters can be written in double-quotes. If a constant is used as an lvalue in an expression, any alteration will be ignored.

Macros are defined by using a  as the lvalue of an assignment. Basically the code in the rvalue of the assignment is saved, and every time  is used in an expression, the saved code is substituted. Recursion is fully supported (since this is the ONLY method of flow control).

Expressions are generally operation-operand-operand or operation-operand. are the basic mathematical binary operators. are the bitwise operators. are the comparison operators. is concatenation (on arrays) and INTERCAL mingle (on numbers). is indexing (on arrays - zero-based) and INTERCAL select (on numbers). generates a random floating-point number between zero and it's operand. converts all nonzero expressions to.

is the arithmetic if-then-else. It sequentially evaluates each  in the list (no separators), until one of them evaluates to zero, or it runs out of expressions. This is then used to decide which of the s after it to evaluate. If all s in the brackets are nonzero, then   is evaluated, otherwise   is evaluated. (Note that it uses lazy evaluation both inside and after the brackets.)

The whole program is a special type of assignment, but with only two expressions. The first is assigned to the command-line arguments, and the result of evaluating the second is returned to the system as the status/exit code.

I/O is done with variables starting with. I don't want to bother defining exactly how it all works, but basically, every odd-valued handle allows access to the I/O data, and the even-valued handle after it allows the changing of its I/O mode. By default, if an integer or floating-point number is assigned to, it is printed as a number; if an array is assigned to  , it's elements are printed as a string; and similarly for assigning   to something else.

Hello world

 * 1) 0($1"Hello, world!\n"#0)

Fibonacci sequence
Infinite:

#0(:1(.3+.1.2($1.3(.2.1(.3.2:1))))(.1#1(.2#1:1)))

Prints a certain number of numbers (given in the command-line). Has an exit code of 0 if inputted number was positive; otherwise exits with 1 (and doesn't print anything):

.4(:1(.3+.1.2($1.3(.2.1(.3.2(.4-.4#1[.4]:1#0)))))(.1#1(.2#1[>.4#0]:1#1)))