-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:hylo-lang/hylo into portable-build-…
…tool
- Loading branch information
Showing
85 changed files
with
2,524 additions
and
492 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
name: Check Markdown links | ||
|
||
on: [pull_request, push] | ||
|
||
jobs: | ||
markdown-link-check: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@master | ||
- uses: gaurav-nelson/github-action-markdown-link-check@v1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Compiler Architecture | ||
|
||
## Project Overview | ||
|
||
The hylo compiler is written in [Swift] and uses [LLVM] as it's code generation | ||
backend. It conforms to the the standard swift project layout: | ||
* [Package.swift] the manifest file used by SPM | ||
* [Sources] all the source code for the compiler | ||
* [Tests] all the test code | ||
|
||
Then there are some extra directories specific to the hylo project: | ||
* [Tools] Scripts to aid in development | ||
* [Examples] Some real world hylo programs | ||
* [Library] The hylo standard (and core) library | ||
|
||
## Stages of compilation | ||
|
||
The hylo compiler goes through the standard stages of compilation: | ||
|
||
1. Tokenisation: Transforms hylo source code (Strings) to stream of distinct | ||
tokens | ||
1. Parsing: Creates an [abstract syntax tree] from the token stream | ||
1. Type-checking: Inspects the abstract syntax tree for type errors | ||
1. IR-lowering: Generates the [intermediate representation] from the abstract | ||
syntax tree | ||
1. LLVM IR generation: Convert hylo IR into [LLVM] IR | ||
1. Machine Code Generation: This is completely handled by [LLVM] | ||
|
||
These top-level stages of the compiler are laid out in [Driver] where you | ||
can see the outline of the compilation phases with their entry points. | ||
Depending on the flags passed to the compiler, the compiler can exit early at | ||
some of these stages. | ||
|
||
### Interesting parts | ||
|
||
Most of the compiler does what you'd expect from the compiltion stages above | ||
but some are worth a deeper look: | ||
|
||
#### Abstract syntax tree | ||
|
||
The abstract syntax tree is made up of an **append-only** array that produces | ||
`NodeID` objects as indices into the array. The `NodeID` allows nodes to refer | ||
to other nodes using their `NodeID`. `NodeID` is generic over node types and | ||
allows us to constrain which nodes are allowed as leaves of other nodes. | ||
|
||
The use of `NodeID` types as indices into an array allows us to define the | ||
existence of a node, by it's `NodeID`, without providing access to the node. | ||
For access you still need the array. This is in contrast to traditional | ||
references that provide existence AND access without allowing separation. | ||
|
||
The use of `NodeID` types are ubiquitous and is often aliased to `.ID` of a | ||
new type (e.g., `FunctionDecl.ID`). | ||
|
||
#### Program Protocol | ||
|
||
After the AST is created the compiler creates property maps that associate | ||
properties to the nodes of the AST. Currently there are two distinct phases of | ||
property creation for these property maps. The first is creating the | ||
connections between scopes and nodes, stored in the `ScopedProgram` struct. The | ||
second is where the majority of the type-checking happens, associating a type | ||
for each expression, declaration etc. Each of these stages is composed of the | ||
previous stage: | ||
|
||
[AST] < [ScopedProgram] < [TypedProgram] < [IR/Program] | ||
|
||
A successfully created `TypedProgram` means the hylo program is well typed. | ||
|
||
#### Hylo IR | ||
|
||
The Hylo IR is composed of instructions defined in the [Instruction] module. | ||
The [Emitter] is the component responsible for creating the `IR` an inserting | ||
it into the [IR/Module], module-by-module and creating an [IR/Program]. | ||
|
||
The hylo IR is only valid after it has gone through some mandatory passes | ||
defined in `Module+*` files of [IR/Analysis]. After these passes the IR should | ||
be valid and executable by a *theortical* hylo VM. Some [more passes] may be | ||
necessary dependent on the target. | ||
|
||
[Swift]: https://en.wikipedia.org/wiki/Swift_(programming_language) | ||
[LLVM]: https://en.wikipedia.org/wiki/LLVM | ||
[SPM]: https://www.swift.org/package-manager/ | ||
[intermediate representation]: https://en.wikipedia.org/wiki/Intermediate_representation | ||
[abstract syntax tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree | ||
|
||
[Driver]: ../Sources/Driver/Driver.swift | ||
[Package.swift]: ../Package.swift | ||
[Sources]: ../Sources | ||
[Tests]: ../Tests | ||
[Tools]: ../Tools | ||
[Examples]: ../Examples | ||
[Library]: ../Library | ||
[AST]: ../Sources/Core/AST/AST.swift | ||
[ScopedProgram]: ../Sources/Core/ScopedProgram.swift | ||
[TypedProgram]: ../Sources/FrontEnd/TypedProgram.swift | ||
[Instruction]: ../Sources/IR/Operands/Instruction/ | ||
[Emitter]: ../Sources/IR/Emitter.swift | ||
[IR/Module]: ../Sources/IR/Module.swift | ||
[IR/Program]: ../Sources/IR/Program.swift | ||
[IR/Analysis]: ../Sources/IR/Analysis/ | ||
[more passes]: ../Sources/IR/Analysis/Module+Depolymorphize.swift |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/// A collection of elements accessible via an indexed subscript. | ||
public trait Collection { | ||
|
||
/// The type of the elements contained in `Self`. | ||
type Element | ||
|
||
/// The type of the positions in `Self`. | ||
type Index: SemiRegular | ||
|
||
/// Returns the position of the first element in `self`, or `end_index()` if `self` is empty. | ||
fun start_index() -> Index | ||
|
||
/// Returns the "past the end" position in `self`, that is, the position immediately after the | ||
/// last element in `self`. | ||
fun end_index() -> Index | ||
|
||
/// Returns the position immediately after `i`. | ||
/// | ||
/// - Requires: `i != end_index()`. | ||
fun index(after i: Index) -> Index | ||
|
||
/// Accesses the elment at position `i`. | ||
subscript(_ i: Index): Element { let } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/// A collection containing a single element. | ||
public type CollectionOfOne<Element: Movable & Deinitializable>: Deinitializable { | ||
|
||
public typealias Index = Bool | ||
|
||
/// The element contained in `self`. | ||
var contents: Element | ||
|
||
/// Creates a collection containing just `contents`. | ||
public init(_ contents: sink Element) { | ||
&self.contents = contents | ||
} | ||
|
||
public fun start_index() -> Bool { false } | ||
|
||
public fun end_index() -> Bool { true } | ||
|
||
public fun index(after i: Bool) -> Bool { true } | ||
|
||
public subscript(_ position: Bool): Element { | ||
let { | ||
// TODO: uncomment when #1046 is implemented | ||
// precondition(!position, "index is out of bounds") | ||
yield contents | ||
} | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.