Java2K - The Manual

Calling functions

Just like any other language, in a typical Java2K program you will call one function or another. Function calls have the following syntax:

FUNCTION_NAME  "/"  ARGUMENT0  "/"  ARGUMENT1 "\"

For example, take the function 70. Take, for the sake of this example, the two Arguments A and B. You would invoke the Function by writing

70/A/B\

That was easy, wasnt it. Note that Java2K functions always have two arguments (and only two arguments); If your function just takes one argument, you still must write the second argument. (Note for mature readers: If in doubt, use *).

Starting with 0.0.1, there is an alternative syntax for this, which is:

FUNCTION_NAME "=" ARGUMENT1 "+" ARGUMENT0.

DO NOTE that A and B have a different operator precedence, but only for this syntax variant. So when I refer to argument[0] below, I always mean A, and A can be on either position. You can write the above function alternatively as

70=B+A.

To make things a bit more interesting, Java2K has one function that has three (3) arguments, the if-goto-else function. Here it is:

EXPRESSION<=>~(LABEL*FUNCTION);

Here, EXPRESSION denotes the number of a function that is evaluated, LABEL the number of a label, and FUNCTION the number of a function again that is executed if the evaluation-function fails. See the section on "hopping around", below.

Numbers

Numbers actually are a very difficult topic, as mathematics in general is a difficult topic. There are two basic ways numbers are used in Java2K

Using numbers as function names

Using numbers as names-of-objects is a lot easier than using funcions as integer values, so lets just do the easy thing first. Numbers are, as specified in the introduction, 11-based digits. Just like you can use 16-based numbers (i.e. hexadecimal numbers) you can define 11-based digits. The digit 10 is called " " (blank or space). This means, you cannot just fill up your sourcecode with blanks, because blanks are digits. [You can fill up space with tabs, but you will find that there is no need to do so if your sole aim is to write obfuscated code]. For your convenience, the decimal numbers 20-29 read: 

"19", "1 ", "20",  "21", "22", "23", "24", "25", "26", "27".

There is one important restriction on the use of numbers as names: names must be divisibly by 7. For example, 8 is not a valid name, because 8 mod 7=1, wheras 70 [NOTE: 70=77DEC] is.

Using numbers as integers

This is a very hard topic. Philosophers of mathematics to this day aren't 100% sure what numbers really are, so why should Java2K be ? Now, why can you not just write 70 when you mean the number 70 ? Because, remember 70 is the name of the function 70. Instead, you will have to write a function that returns 70. Doing so can be quite a hassle, so lets try writing a function that returns 1 instead.

The easiest way to get 1 is to use an operation that will return 1 very often [remember you cannot write a function that will return 1 always, because every function has only a likelyhood of doing the right thing]. To do this, you can take advantage of two helper tokens:

*	will return a pseudo random number
_	will quote the previous argument

A very good way of doing to is by using the function "11 6" (Divide argument [0] by argument [1]). The syntax is

11 6/*/_\

Now wait, what happened here ? The token * is replaced by a random number, say 203. The _ token is replaced by the previous argument, i.e. 203. So, this function will divide 203 by 203 which has (see below) a 90% chance of returning 1.

You can increase the likelyhood of getting a 1 result, but this is a tricky subject that will be dealt with below. Instead, lets try returning the 2. Well, a two is 1+1, so we use the function "125 " [note there is a blank at the end] for adding two arguments:

125 /11 6/*/_\/_\

This function has a 90% chance of first calculating 1. For this 90% chance, there is a 90% chance of it then calculating 2. You get the idea. The higher the number, the less likely you are to get to it. This treat can make coding Java2K a bit of a mess, or rather: DEBUGGING Java2K, because you just never know if the result was just a margin error caused by the inherent noncausality in the universe. Note that combining the //\ syntax with the alternate version enhances readability and code maintenance:

125 /11 6=*+_./_\

Just in case you want to know, here is one function (there are others, most likely of similar complexity) that will return 70DEC, or at least hopefully return 70DEC:

125 /125 /131 /125 /11 6/*/_\/_\/125 /11 6/*/_\/_\\/131 /131 /125 /
11 6/*/_\/_\/131 /125 /11 6/*/_\/_\/_\\/_\\/125 /11 6/*/_\/_\\

Hint: Here 70 is represented as 2*2*2*2*2*2+2*2+2. And here is a much better representation - better, because it uses the stealth technique referred to above.

125 /119 /125 /11 6/*/_\/_\/125 =13 2=*+_.+_.\/125 =131 =119 =125
=11 6=*+_.+_.+125 /13 2/*/_\/_\.+119 /125 /11 6/*/_\/_\/125 =13 2
=*+_.+_.\.+131 /119 /125 /11 6/*/_\/_\/125 =13 2=*+_.+_.\/131 =
119 =125 =11 6=*+_.+_.+125 /13 2/*/_\/_\.+131 /119 /125 /11 6/*/_
\/_\/125 =13 2=*+_.+_.\/131 =119 =125 =11 6=*+_.+_.+125 /13 2/*/_
\/_\.+131 /119 /125 /11 6/*/_\/_\/125 =13 2=*+_.+_.\/119 =125 =11
 6=*+_.+_.+125 /13 2/*/_\/_\.\.\.\.\

Please note that, because there are so many instructions involved, the actual chance of this expression returning 70 is very very low.

Builtin functions

Lets start with the builtin functions. All built-in functions have a 90% chance of returning the correct result. If a function does not return the correct result, the result returned most likely (pun intended) will be a random number. Functions are:

"125 "
Add argument [0] to argument [1]
"11 6"
Divide argument [0] by argument [1]
"12 4"
Subtract argument [1] from argument [0]
"131 "
Multiply argument [0] with argument [1]
"13 2"
NAND argument[0] with argument[1]
"16  "
[two spaces] Assign argument[0] to argument[1]
"1 1 "
This function will output argument [0] as single ascii character
"1 00"
Exit program.
"61 8"
Loop forever, executing argument[0]. If the instruction fails, argument[1] is executed instead.
"5  5"
Compare argument[0], argument[1]
"5 60"
If both arguments last compared were equal, execute argument[0], else argument[1]
"5 67"
If argument[0] was less than argument [1], execute argument[0], else argument[1]
"1 07"
Declare an array of argument[0] 32-bit integers named - numerically - by argument[1].
"837"
Use variable named argument[0], indexed by argument[1].

An unrealistic assumption

Actually, I lied to you. There is one - and only one - function that has a 100% chance of doing the-right thing: "119 ". If argument 0 is a random number (more specifically: was created by a failure of a function to return the correct result), return argument 1, otherwise return argument 0.

You can use this function to increase the likelyhood of getting correct results. Take the following expression:

119/11 6/*/_\/11 6/*/_\\

This function will first evaluate 11 6/*/_\, which is 1. If it is not, the functio will return 11 6/*/_\ [this time, a new invokation with a new * random number], which again has a 90% chance of getting the correct result. This function is, of course, physically impossible, so to be on the safe side you should assume that there is a 1-in-10-billion chance of this function returning something wrong. Note that writing

119/11 6/*/_\/_\

shows you dont understand the concept of _, because _ just requotes the last argument. In order to get a higher chance for a number 2, you would write

119/125 /11 6/*/_\/_\/125 /11 6/*/_\/_\\

and so on.

Variables

You cannot declare a single variable, you can only declare an array of variables. All variables are 32-bit integers. You use the function "1 07" to declare an array of size <argument[0]> and name it by the number <argument[1]>. For example, the following easy-to-read source extract declares a single 32-bit integer named 0:

1 07=119 /12 4/*/_\/12 4=13 2=*+*.+_.\+119 =11 6=*+_.+13 2/*/_\..

To use this variable, e.g. assign it a value, use function "837", which works like a pointer to a variable named argument[0], indexed by argument[1]. For example, here is a code extract (granted, a tiny bit complicated), that will assign 70 to variable 0[0] (previously declared).

16  /125 =119 =125 =11 6=*+_.+_.+125 /13 2/*/_\/_\.+125 /131 /
119 /125 /11 6/*/_\/_\/
125 =13 2=*+_.+_.\/119 =125 =11 6=*+_.+_.+125 /13 2/*/_\/_\.\/131 =
119 =125 =11 6=*+_
.+_.+125 /13 2/*/_\/_\.+131 /119 /125 /11 6/*/_\/_\/125 =13 2=*+_.+_
.\/131 =119 =125 
=11 6=*+_.+_.+125 /13 2/*/_\/_\.+131 /119 /125 /11 6/*/_\/_\/125 =
13 2=*+_.+_.\/131 =
119 =125 =11 6=*+_.+_.+125 /13 2/*/_\/_\.+119 /125 /11 6/*/_\/_\/
125 =13 2=*+_.+_.\.\
.\.\./837=119 /12 4/*/_\/12 4=13 2=*+*.+_.\+119 /12 4/*/_\/12 4=
13 2=*+*.+_.\.\

"13 2" or: The Swiss Army Knife of Logical Operations

Java2K has one logical function, "13 2" which implements NAND(A,B) (that is: NOT A AND NOT B) and is sufficient to handle any logical operation. To use NAND(A,B), you write

13 2/A/B\

To make your life easier, here are a few common logic constructs and their Java2K complements.

NOT A 13 2/A/_\
A AND B 13 2/13 2/A/_\/13 2/B/_\\
A OR B 13 2/13 2/A/B\/13 2/A/B\\

Remember again, any of these expressions has a 90% chance of being right; you might want to add "119 ". So, real hardcore 100% native Java2K programmers will write the number 1 like this:

119/13 2/13 2/11 6/*/_\/_\/13 2/11 6/*/_\/_\\/13 2/13 2/11 6/*/_\/_\/
13 2/ 11 6/*/_\/_\\\

but then again, maybe not.

Functions

Functions are implicitly declared by the ! token. Functions don't have names, they have zero-based indices. Imagine your typical Java2K program being just one large array of function pointers, and you are not very close to the real thing, unless you stand directly before it. For example, the following code fragment declares two functions, 0 and 1, which return 0 and 1, respectively.

! 119 /12 4/*/_\/12 4=13 2=*+*.+_.\
! 119 =11 6=*+_.+13 2/*/_\.

Note the nice formatting. Functions are never directly called, functions can only implicitly be called by making use of the hopping-around-instruction:

Hopping around, or: The Java2K main()

For anything but the smallest of small programs (such as hello world), a simple instruction sequence isn't enough. Java2K does not have a simple goto instruction, it has a EVALUATE-FUNCTION-BRANCH-EQUAL-CALL-OTHERWISE function, as shown in the introduction:

A<=>~(B*C);

This expression will do the following:

As always, Java2k supports implicit labeling [only]. For example, a C program that calculates pi to an arbitrary number of digits may have the following structure [note the fine use of function pointers]).

int main(int argc, char* argv[]) 
{
A000: if(F[18]()) goto A001; else F[0]();
A001: if(F[11]()) goto A003; else F[3]();
A002: if(F[17]()) goto A001; else F[17]();
A003: if(F[18]()) goto A004; else F[4]();
A004: if(F[12]()) goto A013; else F[5]();
A005: if(F[13]()) goto A007; else F[1]();
A006: if(F[17]()) goto A005; else F[17]();
A007: if(F[18]()) goto A008; else F[2]();
A008: if(F[14]()) goto A009; else F[6]();
A009: if(F[15]()) goto A011; else F[7]();
A010: if(F[16]()) goto A011; else F[8]();
A011: if(F[18]()) goto A012; else F[9]();
A012: if(F[17]()) goto A004; else F[17]();
A013: if(F[18]()) goto A014; else F[10]();
A014:
return 0;
}

(Personally, I would add a comment here and there). Such a structure lends itself ideally to a Java2K program. At the beginning of the code, just write a couple of EVALUATE-FUNCTION-BRANCH-EQUAL-CALL-OTHERWISE instructions, and then one call to quit.