Don't visit cells that are already marked. This prevents the marking
phase from looping forever when two cells refer to each other.
Also do the marking directly from the CellVisitor, removing another
unnecessary phase of the collector. :^)
It's now possible to assign expressions to variables. The variables are
put into the current scope of the interpreter.
Variable lookup follows the scope chain, ending in the global object.
Do note that when it comes to evaluating binary expressions, we are
asserting in multiple contexts that the values we're operating on are
numbers, we should probably handle other value types to be more tolerant
in the future, since for example, adding a number and a string, in
which case the number is converted to a string implicitly which is then
concatenated, although ugly, is valid javascript.
Objects can now be allocated via the interpreter's heap. Objects that
are allocated in this way will need to be provably reachable from at
least one of the known object graph roots.
The roots are currently determined by Heap::collect_roots().
Anything that wants be collectable garbage should inherit from Cell,
the fundamental atom of the GC heap.
This is pretty neat! :^)
If statements execute a certain action or an alternative one depending
on whether the tested condition is true or false, this commit helps
establish basic control flow capabilities in the AST.
I always tell people to start building things by working on the thing
that seems the most interesting right now. The most interesting thing
here was an AST + simple interpreter, so that's where we start!
There is no lexer or parser yet, we build an AST directly and then
execute it in the interpreter, producing a return value.
This seems like the start of something interesting. :^)