The source code sits in the samlang repository. The repository follows a monorepo setup, managed by Gradle multi-projects.
To produce a source set (defined by
sconfig.json) into an optimized compiled native program, the
samlang CLI performs following computation in order:
samlang-clicollects all sources specified by
sconfig.jsonand stores a mapping from
ModuleReferenceto source code in
samlang-core/parserparses the sources code into AST's. Each source file is parsed into a
Module. Then the in-memory representation becomes
Map<ModuleReference, Module>. At this point, the
fieldin each AST node is dummy.
samlang-core/checkertype checks the modules by a constraint-solving based type inference algorithm. After that, the in-memory representation is still
Map<ModuleReference, Module>, but each node in the AST is guaranteed to have a correct
samlang-core/compilergradually turns the source-level AST into assembly AST. It first lowers the AST into a high-level IR. The high level IR can be translated into other high-level languages without much effort. Then it lowers the AST into mid-level IR that is similar to Appel's IR. Then
samlang-core/compiler/asm-toplevel-generatorperforms instruction selection to translate IR into abstract assembly. In both stages,
samlang-analysiswill perform some dataflow analysis, which will be consumed by
samlang-core/optimizationto perform various optimizations. Register allocation will be performed at the end.
samlang-core/printerprints the assembly AST into assembly files.
samlang-clithen shells out to
runtimefolder that links the assembly against the samlang runtime. Now you get a program that is directly runnable!