I am learning compiler building using Haskell. I use fixed-point data type recursion to represent abstract syntax trees (ast).
I am learning how to write a type check for a toy language that has simple expressions (numeric and logical constants, binary operations, and local variable declarations).
The type controller is a read-write monad ( RWS):
- because it uses a context consisting of an environment with symbol definitions (a list of symbol associations and its type);
- since it generates a list of error messages;
- I’ll need it later to implement the equivalence of the nominal type, and now I just count how many variables are defined in the program (as a demonstration of its use).
The value returned by the monad is an annotation annotated by types (for expressions) or environments (for declarations).
The function checkeraccepts the input program and leads to the appearance of a new art annotated with the help of the RWSmonad actions , which at startup set the type (if ast is an expression) or environment (if ast is an declaration).
For example, consider an input program
let x = 2 + 3 in 1 + x
with corresponding ast:
Let
|
-----------------------
| |
VarDec: x Bin Add
| |
| ------------
| | |
Bin Add Num 1.0 Var x
|
-----------
| |
Num 2.0 Num 3.0
When checking the type, it will produce the following ast:
action1
Let
|
-----------------------
| |
action2 action3
VarDec: x Bin Add
| |
| ------------
| | |
action4 action5 action6
Bin Add Num 1.0 Var x
|
-----------
| |
action7 action8
Num 2.0 Num 3.0
which is recursively annotated using RWSmonad actions .
, ast ( , ). .
.
, ( let), action1, action2 action3, , action1, action2 action3.
1+x, action3.
, . ( RWS monad) node .
- , ?