Reaper

Reaper is a lazy object-oriented language by Ørjan Johansen (originally idea from 2002, but not published until 2006). It is lazier than most languages, in that objects perform actions only at the last possible time, when they are destroyed. To facilitate destruction the language has a reference-counting garbage collector (the reaper), as well as replacement instructions.

Syntax
The syntax may be approximated by the following BNF description: program ::= destructor destructor ::= statement {statement} statement ::= class-definition | class-prototype | expression class-definition ::= class-declaration INDENT destructor DEDENT class-prototype ::= class-declaration REDENT class-declaration ::= constructor parameter-list parameter-list ::= {variable | "(" parameter-list ")"} expression ::= replacement | constructor expression-list | variable replacement ::= expression ("=" | ":=") expression expression-list ::= {expression | "(" expression-list ")"} constructor ::= IDENTIFIER | NUMBER | STRING variable ::= IDENTIFIER comment ::= "--" {comment-list} comment-list ::= "(" {ANYCHAR - ("(" | ")") | comment-list} ")"

Nested destructor blocks are indented; the tokens,   and   denote a newline beginning, ending or continuing a destructor block, according to how it is indented. Note that newlines may be used freely as whitespace anywhere none of the indentation tokens can apply.

Numbers and strings follow approximate C syntax. Identifiers may contain letters, digits, periods, dashes and underscores.

Identifiers in Reaper are capitalization insensitive. There are also several ways of writing identifiers concatenating more than one word. For example:
 * The builtin constructor  may also be written as   or even.
 * ,  and   are all equivalent.
 * ,  and   are equivalent, and so are   and , but the first group is of course different from the second.
 * is a shorter form of.

Statements
A class definition generates a new class with a corresponding constructor and destructor. The definition is visible in the rest of the surrounding destructor.

A class prototype only gives the constructor. It is useful for creating mutually recursive classes. It is an error for a constructor to be executed before the corresponding destructor has been defined.

An expression statement constructs an object and then promptly forgets it. Unless the object was taken from a variable it is then destroyed, since there can be no other references to it.

Expressions
A variable expression constructs a new reference to the object in the variable. If the variable has not been mentioned previously it is generated in the scope of the current destructor, as a new dummy object (with empty destructor).

A constructor or replacement expression constructs a new object of the corresponding class, constructing the arguments recursively.

Strings and numbers are also considered constructors (with no arguments), so new objects are created each time they are evaluated.

Destruction
Reference counts are kept to all objects and classes. When the reference count of an object reaches 0 (either because it was forgotten by other objects or because it was replaced by another object), its destructor is constructed from its class and the argument list of its constructor, and then run immediately.

As each statement of a destructor is executed, the references used to perform it are released, thus if a variable or object used by a statement is not referenced anywhere else, it will be destroyed.

The reference counting scheme does not detect unreachable circular references. Thus if you want to prevent a destructor from being run, you can create a circular data structure referencing its object. This will not work for a  replacement, however, in which case a   replacement may be used to explicitly cancel the destructor.

Builtin classes

 * The destructors for replacements replace all references to the first argument by the second. The deep replacement using   also replaces the destructor of the first argument, while the shallow replacement using   allows it to run.


 * The destructor for  string or number will destroy and print its argument.
 * The destructor for  object will read a line of input, then replace the object by the resulting string.
 * The destructor for  object will destroy object if at end of file.

Example
A cat program: Cat ReadLine a    Print a     c = Cat := NOP IfEOF c    c := NOP Cat