| Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
|
|
|
|
Now bool flags are handled properly. We have a compiler!!
|
|
|
|
|
|
I'm just copying the go strings library API.
|
|
I haven't written any tests yet, so this code probably doesn't
even compile.
|
|
|
|
|
|
|
|
|
|
|
|
I was using the load procedure to load a program, but by a strict
reading of R7RS, load can only handle expressions and definitions, not
imports. So instead I'm defining each test as a library, and using the
environment procedure to load them at runtime.
|
|
I inserted jump statements into the bytecode at the beginning of each
compilation unit, to jump to the init label. The point is that now the
bytecode can be executed from start to finish, and assuming the
libraries were ordered correctly, it will run the full program.
|
|
|
|
I greatly improved the library, and changed it to expect register
bytecode instead of stack-based.
|
|
|
|
The advantage to this approach is that the user can modify the loop
variables and the variables will be stepped as expected, e.g.
(loop for i from 1 to 10
do (set! i (+ 1 i))
collect i)
should return '(2 4 6 8 10).
|
|
|
|
|
|
I'm not sure yet how to test regalloc.
|
|
|
|
|
|
I guess you can pattern match using quote as a literal.
That's pretty cool.
|
|
|
|
|
|
Now you can use multiple collect statements and they will all accumulate
into the same variable. I think in common lisp you could collect into
the same variable even with collect x into, but it's pretty unclear to
me how to do that in Scheme. How would we know that they are the
same variable?
|
|
Let's not introduce dead code.
|
|
This will maybe be useful for live variable analysis.
|
|
God damn delete is even more complicated than insert. I think it works,
at least.
|
|
Global variables will be stored in an array which is kept in register 0.
The linker will later translate each library-ref into an integer, which
is used as an index into the globals table.
This design makes implementing eval quite straightforward, the eval
bytecode will accept a globals table and a bytevector of bytecode, save
the current set of registers, set register 0 to the new globals table,
and begin executing the given bytecode. When eval is finished, it will
restore the saved registers and return to the previous instruction
pointer. In this way, calling eval can create a call stack.
We could think about implementing function calls with eval, and it's
cool that it would work, but the CPS transformation mostly makes this
irrelevant. It's interesting to think about implementing an interpreter,
where a function call would simply eval the function's bytecode, and the
function call stack would be handled automatically.
|
|
|
|
Running the record matcher has a side-effect (raising *no-match*), so we
call it ahead of time to ensure a consistent order of evaluation.
|
|
The point of argument conversion is to validate on each function call
that the right number of arguments were passed, and to ensure that no
function has more than 1 argument. This second condition makes CPS
slightly simpler, and ensures that the arguments will all fit in locals.
We take the strategy of allocating a vector for each function call.
Ideally we would optimize away most of these allocations, but for now I
just want it to work.
|
|
|
|
|
|
I'm marginally reducing verbosity with this change,
without sacrificing readability.
|
|
|
|
I was hesitant to add a diff library, but it was surprisingly easy. A
straightforward application of dynamic programming.
|
|
I desperately need a diffing library.
|
|
Now variables can't be updated after they're created, so they can be
freely copied into closures.
|
|
I'm partially doing it because I'm not sure if what I had was really
safe, but also it just looks much cleaner this way.
|
|
|
|
I like scheme because it's possible to add any convenient language
feature I can think of.
|
|
Goodbye soup. Thanks to "Compiling with Continuations" by Appel.
|
|
Wow we actually finished CPS. Next is closure conversion, then codegen,
and then we should be able to run some end to end tests. Then we can
look at garbage collection, and from there continue building features
down the long road to self hosting.
|
|
I improved the abstraction in to-cps.
|
|
|
|
|