54 lines
2.7 KiB
Org Mode
54 lines
2.7 KiB
Org Mode
#+title: Gyehoek Scheme
|
||
|
||
#+begin_center
|
||
(this document is written in present tense as if the project is complete, but Gyehoek is a work-in-progress.)
|
||
#+end_center
|
||
|
||
Gyehoek is an R⁷RS-compliant Scheme compiler targeting WebAssembly 3.0, relying principally on the recently standardised garbage collector and tail call proposals. the Gyehoek compiler is implemented in Haskell, and the Gyehoek runtime is a Rust program providing primitive routines and WebAssembly execution via the Wasmtime library.
|
||
|
||
primitives are implemented as native Rust functions made available to the guest by Wasmtime. in the future, it would be ideal to provide the primitives as a WASI interface to help decouple ourselves from a specific Wasm runtime, but it is not a priority.
|
||
|
||
Gyehoek allows separate compilation, ~eval~, first-class continuations, and so on.
|
||
|
||
* pipeline
|
||
|
||
a Scheme program's journey through Gyehoek is as follows:
|
||
1. read (source code → Scheme data)
|
||
2. parse (Scheme data → AST)
|
||
3. expand(?) (AST → AST)
|
||
4. contify (AST → CPS)
|
||
5. close (CPS → CPS)
|
||
6. lower (CPS → Wasm)
|
||
|
||
** read
|
||
|
||
in the read phase, Gyehoek's reader serialises textual source code into a sequence of tokens, which are then parsed into S-expressions. this phase is completely agnostic towards any interpretation of the data — it's just data, not code (yet). this distinction between reading and parsing is made so that the reader can easily be shared amongst many parsers, allowing convenient definition of human-readable representations for all sorts of compiler internals. Gyehoek's intermediate languages and WebAssembly text format are of particular interest.
|
||
|
||
the reader may be configured to extend R⁷RS's syntax with a special "antiquotation" notation, used internally in the compiler to elegantly interpolate and splice S-expression literals via Haskell's quasiquotation.
|
||
#+begin_src haskell
|
||
let meta = 123 :: Int
|
||
in [sx|(a b c #{meta} d)|] -- ⇒ (a b c 123 d)
|
||
|
||
let metas = ["c","d"] :: List Text
|
||
in [sx|(a b ##{metas} e f)|] -- ⇒ (a b "c" "d" e f)
|
||
#+end_src
|
||
|
||
Gyehoek's lexer and parser are generated by Alex and Happy, respectively.
|
||
|
||
unless otherwise noted, the term "parse" will be used in reference to the phase taking S-expressions to ASTs, while "read" refers to the combined Alex/Happy process. if the tokenisation process (Alex) must be distinguished from the "parse" process (Happy), the former is called "lexical analysis" and the latter "syntactic analysis."
|
||
|
||
** parse
|
||
|
||
- use invertible-grammar library
|
||
|
||
** expand
|
||
|
||
** contify
|
||
|
||
- procedures are distinguished from continuations, and procedure applications are distinguished from continuation jumps.
|
||
- all continuations and lambda will be named i think. the exception is continuations for primitive calls.
|
||
|
||
** close
|
||
|
||
** lower
|