mirror of
https://github.com/Noratrieb/crapderive.git
synced 2026-01-14 16:45:08 +01:00
doc doc
This commit is contained in:
parent
1722a9ea0f
commit
1d56ed5dac
4 changed files with 26 additions and 28 deletions
|
|
@ -14,49 +14,34 @@
|
|||
[Interpreter] <--> () IO : stdin and stdout
|
||||
----
|
||||
|
||||
Motivation::
|
||||
|
||||
The interpreter follows a classic interpreter architecture. First, the source is tokenized by a lexer, implemented using the `logos` library (https://crates.io/crates/logos).
|
||||
|
||||
The, a handwritten recursive descent parser parses the token stream. The abstract syntax tree is then given to a small compiler, that compiles it down to a smaller and more limited IR. It also resolves jump labels to offsets.
|
||||
Then, a handwritten recursive descent parser parses the token stream. The abstract syntax tree is then given to a small compiler, that compiles it down to a smaller and more limited IR. It also resolves jump labels to offsets.
|
||||
|
||||
The interpreter then executes this lower level IR.
|
||||
|
||||
==== Parser
|
||||
==== Parser `parser.rs`
|
||||
|
||||
Lexes the source code, and then turns those tokens into an abstract syntax tree.
|
||||
Lexes the source code, and then parses those tokens into an abstract syntax tree.
|
||||
|
||||
[source,rust]
|
||||
----
|
||||
include::{sourcedir}/parser.rs[tag=parse]
|
||||
----
|
||||
|
||||
_<(Optional) Quality/Performance Characteristics>_
|
||||
|
||||
_<(Optional) Directory/File Location>_
|
||||
==== Compiler and IR `ir.rs`
|
||||
|
||||
_<(Optional) Fulfilled Requirements>_
|
||||
[source,rust]
|
||||
----
|
||||
include::{sourcedir}/ir.rs[tag=stmt]
|
||||
----
|
||||
|
||||
_<(optional) Open Issues/Problems/Risks>_
|
||||
The compiler compiles the AST into the IR, resolving labels.
|
||||
|
||||
==== Interpreter `interpret.rs`
|
||||
|
||||
|
||||
|
||||
==== <Name black box 2>
|
||||
|
||||
_<black box template>_
|
||||
|
||||
==== <Name black box n>
|
||||
|
||||
_<black box template>_
|
||||
|
||||
|
||||
==== <Name interface 1>
|
||||
|
||||
...
|
||||
|
||||
==== <Name interface m>
|
||||
|
||||
The interpreter interprets the IR and interacts with the outside world through standard input and output.
|
||||
|
||||
|
||||
=== Level 2
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
[[section-design-decisions]]
|
||||
== Architecture Decisions
|
||||
|
||||
=== Use a single binary crate
|
||||
|
||||
Since the project is small and self-contained, using a single binary crate is enough. In the future, it could still be migrated to using a binary+library crate.
|
||||
|
||||
=== Use an IR
|
||||
|
||||
It would be simpler to simply walk over the AST during interpretation, but this presents several problems:
|
||||
|
||||
* The AST is more permissive than the language, therefore it would have to be checked at runtime.
|
||||
|
||||
* The AST is not optimized for interpretation efficiency, because it's not cache efficient.
|
||||
|
||||
* There would still have to be a second pass over the AST to resolve labels.
|
||||
|
||||
Therefore, an IR is used to resolve the labels and interpret it.
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
[[section-technical-risks]]
|
||||
== Risks and Technical Debts
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ pub struct Location {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, DebugPls)]
|
||||
// tag::stmt[]
|
||||
pub enum Stmt {
|
||||
Mov { to: Place, from: Value },
|
||||
Movb { to: Place, from: Value },
|
||||
|
|
@ -45,6 +46,7 @@ pub enum Stmt {
|
|||
Je { to: Location },
|
||||
Cmp { lhs: Value, rhs: Value },
|
||||
}
|
||||
// end::stmt[]
|
||||
|
||||
struct CompileCtx {
|
||||
stmts: Vec<Stmt>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue