FYI.
The following code outlines the implementation of ATS3 so far:
val source = source_get()
val ABStree0 = source_parse(source) // parsing
val ( ) = synread_abstree(ABStree0) // AST-checking
val ABStree1 = trans01_abstree(ABStree0) // fixity resolution
val ( ) = tread01_abstree(ABStree1) // AST-checking for trans01
val ABStree2 = trans12_abstree(ABStree1) // binding resolution
val ( ) = tread12_abstree(ABStree2) // AST-checking for trans12
)
val ABStree30 = trans23_abstree(ABStree2) // resolving overloaded symbols
val ( ) = tread23_abstree(ABStree30) // ast-checking for trans23
val ABStree31 = trans33_abstree(ABStree30) // Hindley-style type-inference
val ( ) = tread33_abstree(ABStree31) // ast-checking for trans33
val ABStree32 = trans3t_abstree(ABStree31) // resolving template instances
val ( ) = tread3t_abstree(ABStree32) // ast-checking for trans3t
A functional implementation of a compiler essentially consists of a set of trans-functions for translating
one form of abstract syntax tree to another form.
This time I am employing a style of error-handling that internalizes errors inside abstract syntax trees,
relying on various checking functions (e.g., tread01, tread12) for inspecting abstract syntax trees to report
error-messages. My current implementation of these checking functions only produces error-messages that
may be difficult for others (esp. beginners) to understand. But my hope is that other interested parties may
re-implement these functions to give more detailed error-message reporting.
As a rough analogy, ATS3 is structured somewhat like a micro kernel (e.g., L4). I will focus on implementing
the "kernel" of ATS3. And other interested parties can readily add "services" on top of this "kernel".
Cheers!
--Hongwei