Still pretty horribly broken. I was generating dispacements
backwards, failing to emit stuff like the beginning of
loops, the logic for `if` jumps was backwards, etc.
I was also completely forgetting to increment file_here
for appends. I don't remember what all I did; check the diff.
Also no top-level declarations or operator precedence.
The syntax is LL(1). LL syntax seems necessary because
our codegen requires emitting certain code (e.g. entering control)
prior to any codegen inside that context, whereas something like
LR would presumably parse the inner expression before recognizing
the control structure. There may be some way to work around this;
I don't know, I'm not a parsing expert.
Certain parts of the syntax are wonky, e.g. juxtaposition as
function application means a missing semicolon can give confusing
results. I suspect indentation-sensitive syntax would work
more nicely, and intend to implement it some time in the future.
I don't need some fancy atomic output file updating or
posix_fadvise. I removed all platform-specific code
except for a single `chmod`.
That's not to say there's no advantage to atomically
reading or writing files, but for this project, the first
rule needs to be KISS. It's premature optimization and
overengineering.
Now we always use the stack instead of keeping a TOS register.
This is very inefficient, but I'll worry about register
allocation later.
The new block model is inspired by x86's `enter` and `leave`
instructions. I intend to support nested procedures at some point
in the future.