Here we describe the abstract syntax tree, in a fashion similar to the one used by Ocaml. Static type-checking is performed computing the typename attribute for every expression.
type ide |
= | string |
| type expr | = | Const of (int * typename) |
|---|---|---|
| | | True of typename | |
| | | False of typename | |
| | | Const of (int * typename) | |
| | | Var of (ide * typename) | |
| | | Binop of (string * expr * expr * typename) | |
| | | Unop of (string * expr * typename) | |
| type comando | = | Skip |
| | | Call of (ide * expr list) | |
| | | Assign of (ide * expr) | |
| | | Read of ide | |
| | | Write of expr | |
| | | If of (expr * comando * comando) | |
| | | While of (expr * comando) | |
| | | Seq of (comando * comando) | |
| type typename | = | Integer |
| | | Boolean | |
| | | Procedure of (ide * typename) list * decls * comando | |
| | | Unknown | |
| type decls | = | Decls of (ide * typename) list |
| type prog | = | (decls * comando) |