Number-rock

Number-rock is a programming language where each program consists of a series of definitions. It is not allowed to mention any one after it is defined, nor can a definition include mentioning itself (but a function can indirectly call a function defined above it).

Data types are natural numbers and pure functions (which take one input and one output). Types are allowed to be polymorphic, but a value always has a type (which is sometimes unknown).

The significant characters are: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ:.;,=^[] and all others are ignored, except that lowercase letter is treated the same as uppercase, and that # begins a comment which ignores everything up to the next line break.

Each definition must consist of: name(args): statements; result. The (args) and/or statements; can optionally be omitted.

The arguments are a list of variables with commas in between which specifies the arguments to the function. If there is more than one, it is done by currying.

The possible statements are:
 * var=value; Writes the value to the variable. Variables are local to each function and must be defined in this function before being used (if in the args, it is implicitly defined). You can have multiple variables with commas, to write the same value to each. Or, you can put commas on both sides, meaning the number of variables and number of values must be equal; all expressions are evaluated and then you write the results to the variables.
 * expression; The statement must include a variable name somewhere, with an equal sign after the variable name. Causes the result to be written to that variable.
 * count[statements]; Evaluate the count expression, and then execute the statements inside of the block by exactly that many times. The last statement is allowed to omit the semicolon at the end if wanted.
 * var=count[statements];</tt> Same as: var=count; var[statements];</tt>
 * var[statements]=value;</tt> Same as: var[statements]; var=value;</tt>

The possible expressions are:
 * var</tt> Read value of a variable, or a function defined after the current one if there is no such variable.
 * var=</tt> Only allowed in one kind of statement; see above.
 * number</tt> A natural number in decimal format.
 * func(args)</tt> Call a function with specified arguments (if more than one, does currying). The function can be any expression, and arguments can be any expressions, with commas in between. If it is not a function, then the result is always going to be zero.
 * ^expr</tt> The successor of a natural number. If it is a function, it makes the new function by passing the successor of whatever argument is passed to the new function as the argument to the old function.

Examples
FIBO(N): X,Y=0,1; N[PLUS(X=,Y); X,Y=Y,X]; X. COMPOSE(F,G,X): F(G(X)). EQUAL(X,Y): NOT(PLUS(MINUS(X,Y),MINUS(Y,X))). NOT: MINUS(1). TIMES(X,Y): A=0; X[PLUS(A=,Y)]; A. MINUS(X,Y): Y[PRED(X=)]; X. PLUS(X,Y): Y[^X=]; X. PRED(X): A,B=0; X[B[^A=]=1]; A. CONST(X,Y): X. SUBST(X,Y,Z): X(Z,Y(Z)). CHURCH(X,Y,Z): X[Y(Z=)]; Z. UNCHURCH(X): X(SUCC,0). SUCC(X): ^X.