Rewrite the compiler
A few days ago I found a bug in the compiler that I decided merited basically an
entire rewrite of it.
This was long overdue. The compiler kind of grew organically and unhealthily
over time as I wrapped my head around how the whole WAM is structured, and now
that I understand a lot more I can do things right.
This new implementation is a lot "flatter" than the old one. It makes use of
CLOS classes and generic methods to un-nest a lot of the crap that was
previously happening in bigass `labels` blocks. This is a lot easier to read
and understand because you can take things a piece at a time.
Unfortunately, it's currently a lot slower than the old one. But at least it's
*correct*, and now I can start taking a look at optimizing the performance with
a cleaner base to start from.
Notes/ideas for the near future:
* Switch to structs instead of CLOS classes for all the bits and bobs in the
compilation process.
* Inline hot functions in the compilation process.
* Type hint the fucking compiler already. I've put this off for far too long.
* Move the compiler to its own package for easier profiling and to maintain my
shreds of sanity.
* Look into that generic-function-inlining library thing I saw on Reddit...
* Remove the last vestiges of `match` and kill the dependency on optima.
author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 07 Jun 2016 14:49:20 +0000 |
parents |
e244881864f7 |
children |
de6e248866f4 |
(in-package #:bones.wam)
;;;; Opcodes
(declaim (inline instruction-size))
(defun* instruction-size ((opcode opcode))
(:returns (integer 1 3))
"Return the size of an instruction for the given opcode.
The size includes one word for the opcode itself and one for each argument.
"
(eswitch (opcode)
(+opcode-noop+ 1)
(+opcode-get-structure+ 3)
(+opcode-unify-variable-local+ 2)
(+opcode-unify-variable-stack+ 2)
(+opcode-unify-value-local+ 2)
(+opcode-unify-value-stack+ 2)
(+opcode-get-variable-local+ 3)
(+opcode-get-variable-stack+ 3)
(+opcode-get-value-local+ 3)
(+opcode-get-value-stack+ 3)
(+opcode-put-structure+ 3)
(+opcode-set-variable-local+ 2)
(+opcode-set-variable-stack+ 2)
(+opcode-set-value-local+ 2)
(+opcode-set-value-stack+ 2)
(+opcode-put-variable-local+ 3)
(+opcode-put-variable-stack+ 3)
(+opcode-put-value-local+ 3)
(+opcode-put-value-stack+ 3)
(+opcode-call+ 2)
(+opcode-proceed+ 1)
(+opcode-allocate+ 2)
(+opcode-deallocate+ 1)
(+opcode-done+ 1)
(+opcode-try+ 2)
(+opcode-retry+ 2)
(+opcode-trust+ 1)
(+opcode-cut+ 1)
(+opcode-get-constant+ 3)
(+opcode-set-constant+ 2)
(+opcode-put-constant+ 3)
(+opcode-unify-constant+ 2)
(+opcode-get-list+ 2)
(+opcode-put-list+ 2)))
(defun* opcode-name ((opcode opcode))
(:returns string)
(eswitch (opcode)
(+opcode-noop+ "NOOP")
(+opcode-get-structure+ "GET-STRUCTURE")
(+opcode-unify-variable-local+ "UNIFY-VARIABLE")
(+opcode-unify-variable-stack+ "UNIFY-VARIABLE")
(+opcode-unify-value-local+ "UNIFY-VALUE")
(+opcode-unify-value-stack+ "UNIFY-VALUE")
(+opcode-get-variable-local+ "GET-VARIABLE")
(+opcode-get-variable-stack+ "GET-VARIABLE")
(+opcode-get-value-local+ "GET-VALUE")
(+opcode-get-value-stack+ "GET-VALUE")
(+opcode-put-structure+ "PUT-STRUCTURE")
(+opcode-set-variable-local+ "SET-VARIABLE")
(+opcode-set-variable-stack+ "SET-VARIABLE")
(+opcode-set-value-local+ "SET-VALUE")
(+opcode-set-value-stack+ "SET-VALUE")
(+opcode-put-variable-local+ "PUT-VARIABLE")
(+opcode-put-variable-stack+ "PUT-VARIABLE")
(+opcode-put-value-local+ "PUT-VALUE")
(+opcode-put-value-stack+ "PUT-VALUE")
(+opcode-call+ "CALL")
(+opcode-proceed+ "PROCEED")
(+opcode-allocate+ "ALLOCATE")
(+opcode-deallocate+ "DEALLOCATE")
(+opcode-done+ "DONE")
(+opcode-try+ "TRY")
(+opcode-retry+ "RETRY")
(+opcode-trust+ "TRUST")
(+opcode-cut+ "CUT")
(+opcode-get-constant+ "GET-CONSTANT")
(+opcode-set-constant+ "SET-CONSTANT")
(+opcode-put-constant+ "PUT-CONSTANT")
(+opcode-unify-constant+ "UNIFY-CONSTANT")
(+opcode-get-list+ "GET-LIST")
(+opcode-put-list+ "PUT-LIST")))
(defun* opcode-short-name ((opcode opcode))
(:returns string)
(eswitch (opcode)
(+opcode-noop+ "NOOP")
(+opcode-get-structure+ "GETS")
(+opcode-unify-variable-local+ "UVAR")
(+opcode-unify-variable-stack+ "UVAR")
(+opcode-unify-value-local+ "UVLU")
(+opcode-unify-value-stack+ "UVLU")
(+opcode-get-variable-local+ "GVAR")
(+opcode-get-variable-stack+ "GVAR")
(+opcode-get-value-local+ "GVLU")
(+opcode-get-value-stack+ "GVLU")
(+opcode-put-structure+ "PUTS")
(+opcode-set-variable-local+ "SVAR")
(+opcode-set-variable-stack+ "SVAR")
(+opcode-set-value-local+ "SVLU")
(+opcode-set-value-stack+ "SVLU")
(+opcode-put-variable-local+ "PVAR")
(+opcode-put-variable-stack+ "PVAR")
(+opcode-put-value-local+ "PVLU")
(+opcode-put-value-stack+ "PVLU")
(+opcode-call+ "CALL")
(+opcode-proceed+ "PROC")
(+opcode-allocate+ "ALOC")
(+opcode-deallocate+ "DEAL")
(+opcode-done+ "DONE")
(+opcode-try+ "TRYM")
(+opcode-retry+ "RTRY")
(+opcode-trust+ "TRST")
(+opcode-cut+ "CUTT")
(+opcode-get-constant+ "GCON")
(+opcode-set-constant+ "SCON")
(+opcode-put-constant+ "PCON")
(+opcode-unify-constant+ "UCON")
(+opcode-get-list+ "GLST")
(+opcode-put-list+ "PLST")))