Try is the first esoteric programming language that I made. It uses exception handling, a feature found in many languages (such as C++ and Java) as its only control structure. Exceptions in try are simple strings indicating the type of error.
A Try program consists of several statements, entered one per line. The following types of statements are available:
The simplest type of statement; consists of the name of a variable (letters, numbers, underscores; can't start with a number) followed by an expression. No equals sign or other symbol should be between the variable name and the expression. Expressions can contain variables (though see below), numbers, strings (enclosed in quotes with possible escapes \n, \\, \"), sqrt(expression) (for square roots), addition, subtraction, multiplication, division, and string concatenation (using &).
try, catch, end
A try block is a group of statements that has one or more catch blocks. Each try block starts with a line consisting only of the word try and ends with a line consisting of only the word end. A catch block starts with a line containing catch followed by the name of an exception (or the word all) and continues until the next catch block or the end of the try block. When an error of the type named in a catch block occurs while the code in the try block is running, control jumps to the catch block. For example:
output "If code here divides by zero, the program will just stop"
output "But here it won't"
output "This statement will never run"
output "This statement will run after the 1/0 line"
output "This statement will never run, because there are no sqrts"
output "This statement will run last."
When used in a catch block, restarts the try block that caused the exception. This is the only way to get a loop.
A macro is defined by a block starting with macro macro_nameargs and ending with end. It's called with call macro_nameargs, where args must be variables (not arbitrary expressions). Macros may not recurse. How the language handles macro arguments is left as an exercise to the reader.
Comments may be used by assigning a string to an unused variable. Expressions evaluated for their side effects must also be assigned to an unused variable.
While most variables can be read to and written from normally, there are several variable names that are treated specially:
Set this variable to change what is displayed in the output area. Read from this variable to find the current output. For compatibility with future implementations of this language, it is recommended that you only use this variable in statements of the form output output & something.
Read from this variable to prompt the user for input. The input always comes back as a string; see number below.
Read from this variable to obtain a random number between 0 and 1. Set this variable to seed the random-number generator.
If you write a string to this variable and then read from it, instead of the string you wrote you'll find a number there instead (as long as the string represents a number). You'll need to do this if you want to do any math on user input.
Write a number to this variable and then read from it, and you'll get the number truncated to an integer.
The array currently being used. The only way to work with an array is to put it into this variable.
The size of the current array. Write to this variable to create a new array of the specified size.
The value of the arindexth element (zero-based) of array. Write to this variable to change the array.
Write a string to this variable to throw an exception (i.e., cause an error) of the type indicated by the value. Read from this variable to find the last error that occurred.
current_time (JS only)
The current time, expressed as milliseconds since 1970-01-01T00:00:00z. Assigning this to a date in the future will cause the program to wait.
input_mode (JS only)
If set to the value "char", input will return as soon as a single character is entered, rather than waiting for the user to press return/enter.
Initially the ratio of the circumference of a circle to its diameter. This is a normal variable that can be reassigned.
tau (JS only)
Initially the ratio of the circumference of a circle to its radius. This is a normal variable that can be reassigned.
Initially the base of natural logarithms. This is a normal variable that can be reassigned.
Initially positive infinity. This is a normal variable that can be reassigned.
Initially the special "null" value that all unassigned variables initially have. (This is the only variable guaranteed to be unassigned at the beginning of the program.) This is a normal variable that can be reassigned.
A macro was called with the wrong number of parameters.
A statement contained a syntax error.
The number variable was assigned a string that contained something other than a number.
The throw variable was assigned something other than a string.
A mathematical expression attempted to divide by zero. Try using inf.
A statement contained a syntax error, possibly because you didn't finish typing the
A statement contained a syntax error, namely that the line should have already ended.
An expression contained a syntax error, namely mismatched parentheses.
An array was created with a negative size.
A mathematical expression attempted to take the square root of a negative number.
An attempt was made to access an array element outside the array.
A feature was not implemented by the interpreter
A call statement referenced a macro that was never defined.
An attempt was made to perform array operations on a value that wasn't an array.
An attempt was made to perform numerical operations on a value that wasn't a number. Try using the number variable.
current_time was set to a time in the past.
An attempt was made to use a variable that was not yet assigned (or that was assigned null).
An attempt was made to define a recursive macro.
A try block or macro did not have an end.
An end didn't have a try block or macro, or a catch block didn't have a try block to go in.
Exceptions marked with asterisks are syntax errors; it is not guaranteed that any program that can cause these errors will compile (and therefore be able to handle them in a catch) block. The asterisk is not part of the name of the exception. Additional exceptions can be used by assigning the throw variable.
Some parser differences:
Whitespace at the end of a line is ignored in the JS version; in the Java version, putting a space after a "try" statement is an error
In the JS version, most things can be used in a catch handler; in the Java version, only valid variable names can be used
Possibly some others...
In the Java version, most syntax errors were reported before the program started executing (but still had exception-like names). In the JS version, they're exceptions that occur at runtime and can be caught.
input is case-sensitive in the Java version, but case-insensitive in the JS version for consistency with other variables that do things when you assign to or read from them.
Special variables current_time, input_mode, and tau are new in the JS version.
The JS version has a new message if you don't type any code or delete the prompt to type code here. It also restores (and slightly changes) some Easter egg predefined variables from the original unpublished version that weren't in the applet (or downloadable). Oh, and there's a new variable code in the JS version.
The JS version has saving, and some example programs. Most of the example programs are from 2006-7, but some are new: Hello world, Quine, and Unlambda interpreter are new.
In the JS version, due to implementation details, variables won't always stay between executions of the program if you click Stop. Of course, the fact that variables stay between executions at all was always an undocumented feature (except for here).
In the Java version, setting rand only has an effect if the value is a number; in the JS version, it always has an effect.