mkvsynth/mkvsynth — pull request #16 by lukechampine (2014-03-21 06:17:37+00:00)
Title: AST reorganization

Well, my last enormous break-the-spec refactoring nightmare was such a hit that I've decided to repeat it. The good news is that, just like last time, the result is a net reduction in line count (albeit a slight one).

The most significant change here is a reorganization of the AST. In earlier versions of delbrot, everything was an ASTnode: operations, values, argument lists, function tables... at first, this seemed like an elegant way to do things, but as the interpreter matured, the ASTnode struct began to feel very bloated and overly generic.
With this change, the various structs are now defined as such:
- `ASTnode`: Either a value, or an operation on a set of child ASTnodes.
- `Value`: A constant value (`num`, `bool`, `str`, `clip`), an identifier, or a variable
- `Var`: A name and a value, and a `next` pointer for creating argument lists and lookup tables.
- `Fn`: A name, a function pointer or ASTnode param list/body, and a `next` pointer for creating lookup tables.

That's it. `Env`, `argList`, and `Plugin` are still used too, but all the rest have been removed. Much cleaner.

Another big change is that `ex()` now returns a value instead of an ASTnode. This makes sense given the new model. This is why all the filters had to be rewritten (again): functions should return a value, not an ASTnode.

The other change to filters is that they no longer take an ASTnode as an argument. Previously, that ASTnode was preallocated, and held the return value of the function. Now, the `RETURN` macros do all the allocation. So the new filter type signature is `Value* functionName(argList *)`.

One bit of good news is that since reorganizing the AST, the whole memory management issue is looking a lot less scary. Hopefully I'll be able to make real some progress in that area now.