Make progress on compiler posts
This commit is contained in:
@@ -20,9 +20,9 @@ our own stack, and whenever a graph-building function will want to modify
|
||||
the stack, it will have to call library routines for our stack implementation:
|
||||
|
||||
```C
|
||||
void stack_push(struct stack_s* s, struct node_s* n);
|
||||
struct node_s* stack_slide(struct stack_s* s, size_t c);
|
||||
/* other stack operation */
|
||||
void stack_push(struct stack* s, struct node_s* n);
|
||||
struct node_s* stack_slide(struct stack* s, size_t c);
|
||||
/* other stack operations */
|
||||
```
|
||||
|
||||
Furthermore, we observe that Unwind does a lot of the heavy lifting in our
|
||||
@@ -41,4 +41,28 @@ while(1) {
|
||||
```
|
||||
|
||||
In this implementation, Unwind is in charge. We won't need to insert
|
||||
the Unwind operations at the end of our generated functions.
|
||||
the Unwind operations at the end of our generated functions, and you
|
||||
may have noticed we've already been following this strategy in our
|
||||
implementation of the G-machine compilation.
|
||||
|
||||
We can start working on an implementation of the runtime right now,
|
||||
beginning with the nodes:
|
||||
|
||||
{{< codelines "C++" "compiler/07/runtime.c" 5 46 >}}
|
||||
|
||||
We have a variety of different nodes that can be on the stack, but without
|
||||
the magic of C++'s `vtable` and RTTI, we have to take care of the bookkeeping
|
||||
ourselves. We add an enum, `node_tag`, which we will use to indicate what
|
||||
type of node we're looking at. We also add a "base class" `node_base`, which
|
||||
contains the fields that all nodes must contain (only `tag` at the moment).
|
||||
We then add to the beginning of each node struct a member of type
|
||||
`node_base`. With this, a pointer to a node struct can be interpreted as a pointer
|
||||
to `node_base`, which is our lowest common denominator. To go back, we
|
||||
check the `tag` of `node_base`, and cast the pointer appropriately. This way,
|
||||
we mimic inheritance, in a very basic manner.
|
||||
|
||||
We also add an `alloc_node`, which allocates a region of memory big enough
|
||||
to be any node. We do this because we sometimes mutate nodes (replacing
|
||||
expressions with the results of their evaluation), changing their type.
|
||||
We then want to be able to change a node without reallocating memory.
|
||||
Since the biggest node we have is `node_app`, that's the one we choose.
|
||||
|
||||
Reference in New Issue
Block a user