Skip to content

Commit 7c3c0cb

Browse files
author
Ehsan M. Kermani
committed
Content editorial
1 parent 164d3f0 commit 7c3c0cb

File tree

9 files changed

+32
-12
lines changed

9 files changed

+32
-12
lines changed

book/src/01_calculator/ast.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Abstract Syntax Tree (AST)
22

3-
AST comes into picture when we want to go from the string representation of our program like `"-1"` or `"1 + 2"` to something more manageable and easier to work with. Since our program is not a random string (the grammar is for), we can use the structure within the expressions like `"-1"` and `"1 + 2"` to our own advantage and come up with a *new representation* like a [tree](https://en.wikipedia.org/wiki/Tree_structure)
3+
AST comes into picture when we want to go from the string representation of our program like `"-1"` or `"1 + 2"` to something more manageable and easier to work with. Since our program is not a random string (the grammar is for), we can use the structure within the expressions `"-1"` and `"1 + 2"` to our own advantage and come up with a *new representation* like a [tree](https://en.wikipedia.org/wiki/Tree_structure)
44

55
<p align="center">
66
</br>
@@ -73,13 +73,13 @@ in later stages of compilation.
7373

7474
## Interpreter
7575

76-
CPU is the *ultimate interpreter*. That is, it executes opcodes as it goes. After we have changed the representation (aka *lowered* the representation) of our source code `&str` to AST `Node` the a basic interpreter looks and each node of the AST (via any [tree traversal methods](https://en.wikipedia.org/wiki/Tree_traversal)) and simply **evaluates** it *recursively*
76+
CPU is the *ultimate interpreter*. That is, it executes opcodes as it goes. To do that, after we have changed the representation (aka *lowered* the representation) of our source code `&str` to AST `Node`, a basic interpreter looks and each node of the AST (via any [tree traversal methods](https://en.wikipedia.org/wiki/Tree_traversal)) and simply **evaluates** it *recursively*
7777

7878
```rust,ignore
7979
{{#include ../../../calculator/src/compiler/interpreter.rs:interpreter_eval}}
8080
```
8181

82-
To sum up, we can define a `Compile` trait
82+
To sum up, we define a `Compile` trait
8383

8484
```rust,ignore
8585
{{#include ../../../calculator/src/lib.rs:compile_trait}}

book/src/01_calculator/ast_traversal.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Recall from the previous section that JITing our [add function](./basic_llvm.md) was very detailed and cumbersome to write. Fortunately, there are some useful patterns for traversing complicated ASTs (and IRs)
44

55
* **Builder pattern**
6-
* **Visitor pattern** (Will introduce it in chapter 4)
6+
* **Visitor pattern** (Will be introduced in chapter 4)
77

88
### Builder Pattern
99

@@ -26,3 +26,9 @@ and similar to our addition example, we can JIT the builder output
2626
{{#include ../../../calculator/src/compiler/jit.rs:jit_ast}}
2727
```
2828
<span class="filename">Filename: calculator/src/compiler/jit.rs</span>
29+
30+
Finally, we can test it
31+
32+
```rust,ignore
33+
assert_eq!(Jit::from_source("1 + 2").unwrap(), 3)
34+
```

book/src/01_calculator/basic_llvm.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
### Setup
55

6-
The code is available in [`calculator/examples/llvm/src/main.rs`](../../../calculator/examples/llvm/src/main.rs). Because my `llvm-config --version` shows `10.0.0` so I'm using `branch = "llvm=10-0"` in inkwell
6+
The code is available in [`calculator/examples/llvm/src/main.rs`](https://github.com/ehsanmok/create-your-own-lang-with-rust/blob/master/calculator/examples/llvm/src/main.rs). Because my `llvm-config --version` shows `10.0.0` so I'm using `branch = "llvm=10-0"` in inkwell
77

88
```text
99
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm10-0" }
1010
```
1111

12-
Go to [`calculator/examples/llvm` crate](../../../calculator/examples/llvm/) and `cargo run`.
12+
Go to [`calculator/examples/llvm`](https://github.com/ehsanmok/create-your-own-lang-with-rust/blob/master/calculator/examples/llvm/) sub-crate and `cargo run`.
1313

1414

1515
### Add Function
@@ -30,7 +30,7 @@ Here is how to *stitch* our add function in LLVM
3030
{{#include ../../../calculator/examples/llvm/src/main.rs:first}}
3131
```
3232

33-
2. We define the signature of `add(i32, i32) -> i32`, add the function to our module, create a [basic block]((https://thedan64.github.io/inkwell/inkwell/basic_block/index.html)) entry point and a builder to add later parts
33+
2. We define the signature of `add(i32, i32) -> i32`, add the function to our module, create a [basic block](https://thedan64.github.io/inkwell/inkwell/basic_block/index.html) entry point and a builder to add later parts
3434

3535
```rust,ignore
3636

book/src/01_calculator/calc_intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Our first programming language is a simple calculator supporting addition and su
44

55
If you haven't cloned the [GitHub](https://github.com/ehsanmok/create-your-own-lang-with-rust) repo already, please do and navigate to the `calculator` subdirectory.
66

7-
To start, we have `1 + 1;` in [examples/simple.calc](../../../calculator/src/examples/simple.calc) where you can compile with
7+
To start, we have `1 + 1;` in [examples/simple.calc](https://github.com/ehsanmok/create-your-own-lang-with-rust/blob/master/calculator/examples/simple.calc) where you can compile with
88

99
```text
1010
cargo build --bin main // create the CLI executable for Calc

book/src/01_calculator/grammar_lexer_parser.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ and does all the steps of the frontend pipeline that we mentioned so that we can
4141
```rust,ignore
4242
CalcParser::parse(Rule::Program, source)
4343
```
44+
45+
Before doing that, we need to define our Abstract Syntax Tree (AST) in the [next section](./ast.md).

book/src/01_calculator/jit_intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Just-In-Time (JIT) Compiler with LLVM
22

3-
JIT compilation is a combination of Ahead-Of-Time (AOT) compilation and interpretation. As we saw previously, our `Calc` interpreter evaluates AST to values (actual integer `i32` values) but a JIT compiler differs from an interpreter in what it outputs. Intuitively, JIT outputs are like AOT outputs but generated at runtime when traversing the AST (similar to interpreter).
3+
JIT compilation is a combination of Ahead-Of-Time (AOT) compilation and interpretation. As we saw previously, our `Calc` interpreter evaluates AST to values (actual integer `i32` values) but a JIT compiler differs from an interpreter in what it outputs. Intuitively, JIT outputs are like AOT outputs but generated at runtime when traversing the AST.
44

55
### LLVM
66

book/src/01_calculator/repl.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ CTRL-C
8484

8585
## Conclusion
8686

87-
This concludes our [Calculator](./calc_intro.md) chapter. We took advantage of the simplicity of our `Calc` language to cover a lot of topics.
87+
This concludes our [Calculator](./calc_intro.md) chapter. We took advantage of the simplicity of our `Calc` language to touch on a lot of topics.
8888

8989
Thanks for following along and reading up this far!
9090

book/src/01_calculator/vm.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ We define
3939
```
4040
<span class="filename">Filename: calculator/src/compiler/vm/bytecode.rs</span>
4141

42-
and as an example, here is `"1 + 2"` AST to Bytecode conversion pictorially
42+
and pictorially, here is how `"1 + 2"` AST to Bytecode conversion would look like
4343

4444
<p align="center">
4545
</br>
@@ -91,3 +91,15 @@ and with the help of *instruction pointer (IP)*, we execute the Bytecodes as fol
9191
{{#include ../../../calculator/src/compiler/vm/vm.rs:vm_interpreter}}
9292
```
9393
<span class="filename">Filename: calculator/src/compiler/vm/vm.rs</span>
94+
95+
To examine the generated Bytecodes and run our VM, we can do
96+
97+
```rust,ignore
98+
let byte_code = Interpreter::from_source(source);
99+
println!("byte code: {:?}", byte_code);
100+
let mut vm = VM::new(byte_code);
101+
vm.run();
102+
println!("{}", vm.pop_last());
103+
```
104+
105+
Checkout the [next section](./repl.md) on how to create a REPL for our `Calc` and see some samples of computations.

book/src/intro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This book assumes some basic knowledge of Rust language. Please take a look at t
77

88
The accompanying codes and materials for this book are available in [GitHub](https://github.com/ehsanmok/create-your-own-lang-with-rust). To follow along, make sure you have
99

10-
* [Rust installed](https://www.rust-lang.org/tools/install)
10+
* [Rust toolchain installed](https://www.rust-lang.org/tools/install)
1111
* Cloned the repository
1212

1313
```text

0 commit comments

Comments
 (0)