# LICE

## Name

**LICE** stands for the **L**ISP **I**NTERCAL **C** **E**soteric language.

## Syntax

prog-->exp1exp2`exp1: command line,exp2: exit code `exp--> (exp1exp2exp3) ` assignment ` --> .num` integer variable ` --> ,num` array of integer variables ` --> ;num` floating-point variable ` --> :num` macro ` --> #num` numeric constant ` --> $num` I/O handle ` -->binopexp1exp2` arithmetic etc. on expressions ` -->unopexp` arithmetic etc. on expressions ` --> [exp-list]exp1exp2` 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 ofcharacter(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 *exp1* *exp2* *exp3*)

and assigns *exp2*

(an lvalue) to it. The whole assignment-expression then evaluates to *exp1*

.
*exp3*

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 *num*`:`

is used in an expression, the saved code is substituted. Recursion is fully supported (since this is the ONLY method of flow control).
*num*

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 `#1`

.

`[`

is the arithmetic if-then-else. It sequentially evaluates each *exp-list*] *exp1* *exp2*

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 *exp*

s after it to evaluate. If all *exp*

s in the brackets are nonzero, then *exp*

is evaluated, otherwise *exp1*

is evaluated. (Note that it uses lazy evaluation both inside and after the brackets.)
*exp2*

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 `$1`

, it is printed as a number; if an array is assigned to `$1`

, it's elements are printed as a string; and similarly for assigning `$1`

to something else.

## Examples

### Hello world

#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)))