## The Interpreter

Former versions of &ECL;, as well as many other lisps, used linked lists to represent code. As of version 0.3 a bytecodes compiler and a bytecodes interpreter were developed to circumvent the limitations of linked lists.

When you enter code at the lisp prompt, or when you load a source file, &ECL; begins a process known as minimal compilation. Barely this process consists on parsing each form, macroexpanding it and translating it into an intermediate language made of bytecodes.

The bytecodes compiler is implemented in `src/c/compiler.d`. The main entry point is the lisp function `SI::MAKE-LAMBDA`, which takes a name for the function and the body of the lambda lists, and produces a lisp object that can be invoked. For instance,

    > (defvar fun (si::make-lambda 'f '((x) (1+ x))))
    *FUN*
    > (funcall fun 2)
    3

&ECL; can only execute bytecodes. When a list is passed to `EVAL` it must be first compiled to bytecodes and, if the process succeeds, then the resulting bytecodes are passed to the interpreter. Similarly, every time a function object is created, such as in `DEFUN` or `DEFMACRO`, the bytecodes compiler processes the lambda form to produce a suitable bytecodes object.

The fact that &ECL; performs this eager compilation means that changes on a macro are not immediately seen in code which was already compiled. This has subtle implications. Take the following code:

    > (defmacro f (a b) `(+ ,a ,b))
    F
    > (defun g (x y) (f x y))
    G
    > (g 1 2)
    3
    > (defmacro f (a b) `(- ,a ,b))
    F
    > (g 1 2)
    3

The last statement always outputs `3` while in former implementations based on processing of lambda lists it would produce `-1`.