elastiC - elastiC quick reference
=================================

Marco Pantaleoni (panta@elasticworld.org)

1. Description
==============

elastiC is a very high level language (VHLL) aimed at the ease of
development of large systems. It has a simple syntax, similar to that
of the C language, so it should be very easy to learn. On the other
side it introduces many extremely powerful features, such as:

o    automatic memory management with real, fast, Garbage Collection

o    dynamic typing

o    lexical scoping and first class functions, to allow full
     functional programming

o    many useful types: dynamic arrays, dictionaries, symbols,
     strings, ...

o    OOP support (styled after Smalltalk object model)

o    pervasive exception handling support

o    easy C extensibility (it's possible to add functions, classes,
     methods, packages, ...)

o    hierarchical namespaces

o    easily embeddable in larger C programs as a library

o    portable bytecode compilation & interpretation

elastiC also comes with configuration files for an elastiC emacs mode
(with font-lock support) and an elastiC JED mode.

This manual is not a complete reference document, but rather a quick
reference.

2. Language
===========

2.1. General Syntax Rules
-------------------------

o    The syntax is inspired by the C language.

o    elastiC programs are defined in modules (also called packages).

o    elastiC programs are sequences of declarations, definitions,
     statements and expressions.

2.2. Comments
-------------

C style comments:

  /*
   ...
   ... commented region
   ...
   */

C++ style comments:

 // commented region

2.3. Reserved words
-------------------

  break        catch           class           continue        do              else
  extends      for             from            function        goto            if
  import       in              local           method          package         private
  public       return          static          super           throw           try
  while

2.4. Fundamental Types
----------------------

Basic types are integers, floats (floating point numbers), booleans,
characters, strings, symbols, arrays, hashes, classes, objects (class
instances), packages, bytecode, stacks, primitive functions, primitive
methods, handlers. The last four constitute a very advanced topic and
can be ignored by the casual elastiC user.

The special value @nil can be used as a null value (for example to
specify that no value is available).

There are also the special types undefined, error, which have only one
object instantiated. The undefined object is contained in
uninitialized variables and it produces an error when referenced. The
error object is returned by primitive functions to alert the
interpreter that an exception is pending. These types however are of
interest only to the extension writer and not to the casual elastiC
user.

In the remaining part of this section we'll give details on the single
types and show some examples of constant values of these types.

Null value
----------

The null value doesn't have a type, but it is a very important value
anyway.

  @nil

Integers
--------

  12345        0x3039 (hex)    030071 (octal)

Floats
------

  123.45       123.            1.2345e2        1.2345e+2

Booleans
--------

  @true
  @false

In expressions expecting a logical value, all values are considered
equivalent to @true with the exception of @nil, @false, and the
integer 0

Characters
----------

  'a' 'b' ...  Common characters
  '\\'         \   - Backslash            (ASCII 92)
  '\n'         LF  - Linefeed             (ASCII 10)
  '\t'         HT  - Tab                  (ASCII 9)
  '\b'         BS  - Backspace            (ASCII 8)
  '\r'         CR  - Carriage Return      (ASCII 13)
  '\f'         FF  - Feed Forward         (ASCII 12)
  '\v'         VT  - Vertical Tab         (ASCII 11)
  '\a'         BEL - Bell                 (ASCII 7)
  '\?'         ?   - Question mark "?"    (ASCII 63)
  '\''         '   - Single Quote "'"     (ASCII 39)
  '\0'         NUL - NUL                  (ASCII 0)

Strings
-------

  "abc"
  "This is a string"
  "A string with \"quotes\" too !"

All the escape sequences supported by characters are available for
strings too.

Symbols
-------

  #asymbol
  #thisIsAnotherSymbol
  'anotherSymbol

Symbols are translated to integers during the compilation of the
source program, and from that point on they are always handled as
integers. For this reason symbols are very fast and require very
little memory if compared to strings. There are also library function
to convert from symbols to strings and vice versa. Symbols are used as
symbolic constants (like enumerations in the C language).

Arrays
------

Arrays are ordered sequences of values. They can be indexed with an
integer. Arrays can be nested, and can be initialized with
non-constant expressions too.

  #[1, 2, 3, 4.0, 'a', "A String", #aSymbol]
  #[1, 3, 5, #['a', 'b', 'c'], 3 + 4, 11]

Array indexing
--------------

  a = #["Paris", "Rome", "Washington", "Madrid"]

  a[0] will give the value "Paris"

  a[1] will give the value "Rome"

  a[-1] will give the value "Madrid"

  a[-4] will give the value "Paris"

Hashes
------

Hashes are also known as dictionaries, or tables. They associate
values to a key. These keys can then be used later for value retrieval
or to memorize a different value.

  %["key 1", "value 1", "key 2", "value 2"]
  %["key 1", 1,
    "key 2", 2,
    #key3,   3]
  %[1,           5,
    "abc",       6.6,
    3.4,         "ok",
    #[1, 2, 3],  "cool"]

Hash indexing
-------------

  a = %[1,           5,
        "abc",       6.6,
        3.4,         "ok",
        #[1, 2, 3],  "cool"]

  a[1] will give the value 5

  a["abc"] will give the value 6.6

  a[3.4] will give the value "ok"

  a[#[1, 2, 3]] will give the value "cool"

Classes and objects
-------------------

Classes and class instances (objects) will be explained in a
subsequent section of this document.

 public class MyClass extends basic.Object
 {
     local  an_instance_variable;
     static a_class_variable;

     method a_normal_method()
     {
         basic.print( an_instance_variable );
     }

     class method a_class_method()
     {
         basic.print( a_class_variable );
     }
 }

 local anObject = [MyClass new];
 [anObject a_normal_method];
 [MyClass a_class_method];

Packages (modules)
------------------

Packages are the basic compilation unit in elastiC. The compiler reads
the source of a package, producing a bytecode compiled version,
suitable for execution by the interpreter. A package can import other
packages to reference variables, functions and classes therein
contained.

 package mypackage;

 import basic;

 basic.print( "Hello world !" );

Bytecode
--------

elastiC compiles source code into a special virtual machine sequence
of instructions called bytecodes. Modules, functions, classes are all
compiled into bytecode. These compiled objects are values as well as
integers or strings, and can be manipulated in almost the same ways:
they can be memorized in variables, passed to functions, and so on.

For examples the following two pieces of code, defining a function,
are equivalent:

  public function add(a, b)
  {
      return a + b;
  }

  private v = add(3, 5);

and

  public add;

  add = function (a, b)
  {
      return a + b;
  };

  private v = add(3, 5);

Stacks, primtive functions and methods, handlers
------------------------------------------------

These are of interest only to C extension writers and to (very)
advanced elastiC users.

2.5. Expressions
----------------

Expression are syntactical units producing values. A formal definition
of expressions in elastiC would require the description of a complex
grammar, but simply speaking expressions can be constant values or
combinations of operations on simpler expressions. Operations are
identified by operators and operands (operands are the arguments of
the operator, and are expressions again). Expressions can be grouped
with parenthesis.

We've already seen constant values when speaking about fundamental
types (to be more precise, array and hash construction construction in
the above examples are actually examples of expressions).

2.5.1. Operators
----------------

Array and hash construction operators
-------------------------------------

The #[...] syntax we've already encountered is the array construction
operator. Similarly the %[...] is the hash construction operators.

Arithmetic operators
--------------------

Arithmetic unary operators are the unary '+' and '-'.

  +5
  -4.6

Arithmentic binary operators are '+', '-', '*', '/', '%' (modulus),
'**' (pow).

  3 + 4
  "string " + "concatenation"

  2 - 1.5

  4.1 * 2

  8.0 / 2.0

  9 % 2

  2 ** 3

The arithmetic operators have the expected precedence relations and
group from left to right.

Relational and equality operators
---------------------------------

Relational operators are: '<', '<=', '>', '>='

Equality operators are: '==' (equality), '!=' (inequality)

Equality operators have lower priority than relational ones.

Bit-wise logical operators
--------------------------

Bit-wise logical operators are: '&' (arithmetic and), '|' (arithmetic
or), '^' (arithmetic xor), '<<' (left shift), '>>' (right shift), '~'
(one complement).

Logical operators
-----------------

Logical operators are: '&&' (logical and), '||' (logical or)

Logical operators are short-circuited: the evaluation stops as soon as
possible, without evaluating operands where not needed. For example,
in:

  @false && myfunction()

the function myfunction won't be called.

Assignment operators
--------------------

The assignment operator '=' assign the value on the right to the name
(variable) on the left. Moreover, binary operators have a
corresponding assignment operator form. If OP is one of this
operators, then the form:

  e1  OP=  e2

is equivalent to:

  e1  =  e1  OP  e2

Increment and decrement operators
---------------------------------

Increment and decrement operators are respectively '++' and '--', and
can be either prefix or postfix. These operators can applied to an
expression that could stay at the left of an assignment expression
(said l-value). They perform an increment or decrement operation on
the expression. The value of the expression is returned after the
operation has been performed for the prefix form, and before the
modification for the postfix form.

After the execution of the statements:

  a = 5;
  b = ++a;

The following conditions will hold:

  a == 6
  b == 6

While, after:

  a = 5;
  b = a++;

we'll have:

  a == 6
  b == 5

Conditional operator
--------------------

The conditional operator (also known as ternary operator) takes the
form:

  e1 ? e2 : e3

The expression e1 is evaluated. If it produces a non-false value, then
the e2 is evaluated and returned as the global result value, otherwise
e3 is evaluated and returned as the global result value.

Sequence operators
------------------

The operator in can be used to the the membership of a value to a
collection such as an array (or user-defined class instances with
support for sequence operations).

  "red" in #[1, 2, "green", "yellow", "red"]

will return @true

Function call
-------------

The function call is a valid expression. The syntax is:

  function(argument-list)

where argument-list is a (possibly empty) comma separated list of
expressions and function is an expression returning a callable
bytecode object (usually created with the function statement).

Method call
-----------

The method call is a valid expression. The allowed syntactical forms
are:

  [object methodname argument-list]

  [object keyword-argument-list]

  [super methodname argument-list]

  [super keyword-argument-list]

In the first two forms, object is an expression returning a class
instance or a class. methodname is a name identifying a method in the
class of the called object. argument-list is a (possibly empty) comma
separated list of expressions. keyword-argument-list is sytactic form
that specifies both the method name and its arguments. For example,
in:

  [anObject moveToX: 5 andY: 6]

the method name is moveToX:andY: and the arguments are 5 and 6.

The super keyword must be explained after some concepts of OOP have
been introduced.

2.5.2. Function definition
--------------------------

Another kind of expression is the function definition. As its name
implies it produces a new function, returning a callable bytecode
object, that can be used with the function call defined above.

XXX TODO

2.6. Statements
---------------

As we've seen, elastiC programs are sequences of declarations,
definitions, statements and expressions. Of these, roughly speaking,
statements are the basic units of the language producing effects
during the execution of the program.

Expressions can become statements when followed by a semicolon ';'.
For example:

  a = 5;

is an statement composed by an assignment expression.

2.6.1. Blocks
-------------

Blocks are groups of statements to be executed in sequence. A block
constitutes a compound statement. Blocks can be placed wherever a
simple statement would be considered legal. The syntax of a block is:

  {
      statement-1
      ...
      statement-N
  }

Blocks can be nested.

2.6.2. Control statements
-------------------------

Selection statements
--------------------

Looping statements
------------------

2.7. Functions
--------------

Function definition
-------------------

Function invocation
-------------------

2.8. Variables
--------------

elastiC makes a strong distinction between values and variables.
Variables are essentially locations in memory, identified by a name,
where the address of a value can be stored. Note that a variable
contains the address of a value, not the value itself ! This implies
that a value can be referenced by more than one variable. elastiC
variables are not typed: a variable can contain a value of any type.
Stated differently:

in elastiC type is a characteristic of values, not variables

This said, in elastiC we can have different kind of variables:

o    package variables

o    function / method variables

o    Variables introduced in classes

When declared, variables can be also be initialized.

Package variables
-----------------

Package variables are the ones declared at the top level of a package,
and are visible in the package starting from the point where they are
introduced. They can be of two kinds: public or private (for package
variables, local is a synonym for private). Private variables are
local to this module and cannot be accessed from the outside. Public
variables are visible from other modules through importing and
qualification.

  package testpackage;

  public var1;
  public var2 = 5;

  private var3;
  private var4 = 1;

Note: function names are variables. The syntax to introduce a named
function is only a shorthand for the sequence of variable declaration,
and assignment of the function to the variable (as already mentioned
above, functions are first-class objects, like all other values).

Function and method variables
-----------------------------

Variables defined inside function and method bodies are visible only
there and from the point where they are introduced. There are two
kinds of these variables: local and static. Local variables exist only
during the execution of the function or method where they have been
introduced (but see lexical scoping below for a noteworthy exception)
and don't retain the value across successive calls. Static variables
work in the same way as local ones except that they retain their value
across successive calls. Initialization for static variables is
performed only once, during the first invocation of their enclosing
function/method.

    function localexample()
    {
        local v = 5;          // a local variable

        v = v + 1;
        basic.print( v, '\n' );
    }

    localexample();
    localexample();
    localexample();

will produce the output:

    6
    6
    6

While:

    function staticexample()
    {
        static v = 5;          // a static variable

        v = v + 1;
        basic.print( v, '\n' );
    }

    staticexample();
    staticexample();
    staticexample();

will produce the output:

    6
    7
    8

Variables introduced in classes
-------------------------------

Also said class-introduced, or class-scoped, are not to be confused
with class variables (which are a only subset of class-introduced
variables). Variables introduced inside class declarations are visible
only inside the class body. There are two kind of these variables:
instance variables and class variables.

Instance variables are introduced with the keyword local: every class
instance (object in the narrower acception) has its own set of private
members identified by instance variables. Instance variables can be
referenced only from methods.

Class variables are introduced with the keyword static and they
introduce members common to every instance of the class: they are a
property of the entire class and not of the single instances. Class
variables can be referenced from normal methods and from class
methods.

2.9. Lexical scoping
--------------------

elastiC is a lexically scoped language. XXX TODO

2.10. Object Oriented Programming
---------------------------------

Class definition
----------------

Method definition
-----------------

Method invocation
-----------------

2.11. Defining a Module
-----------------------

2.12. Closures
--------------

2.13. Exceptions
----------------

3. Standard Library
===================

3.1. basic module
-----------------

3.2. sys module
---------------

3.3. math module
----------------

3.4. string module
------------------

3.5. list module
----------------

3.6. array module
-----------------

3.7. re module
--------------

4. Tools
========

4.1. The ec interpreter
-----------------------

4.2. The ecc compiler
---------------------

4.3. The ecdump bytecode disassembler
-------------------------------------

5. Final Considerations
=======================

6. See Also
===========

the ec(1) manpage: for the elastiC interpreter

the ecc(1) manpage: for the elastiC compiler

the ecdump(1) manpage: for the bytecode disassembler

[Cox86]: Brad J. Cox, Object Oriented Programmingm An Evolutionary
Approach, Productivity Products International, Inc.

7. Author
=========

Marco Pantaleoni (panta@elasticworld.org)

8. Credits
==========

I wish to thank the following people:

B.W. Kernighan, D.M. Ritchie, K. Thompson, R. Pike, for giving us the
C programming language and Unix.

L. Torvalds and the other kernel hackers, for letting us common
mortals to use a real operating system.

Bill, for letting us to demonstrate how much superior Unix is.

And all the others, that I can't cite in a manual page.

9. Copyright
============

Copyright (C) 2001 Marco Pantaleoni. All rights reserved.

The contents of this file are subject to the elastiC License version
1.0 (the "elastiC License"); you may not use this file except in
compliance with the elastiC License. You may obtain a copy of the
elastiC License at http://www.elasticworld.org/LICENSE

IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND
THE AUTHOR AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

See the elastiC License for the specific language governing rights and
limitations under the elastiC License.

