Abstractly, we might evaluate such a tree as a core program with the following psuedocode:
tree_eval(t): if t is a leaf: let a = integer at node return a otherwise, t is an internal node: let binop = binary operation at the node let a = tree_eval(left(t)) let b = tree_eval(right(t)) return binop(a,b)
To realize this psuedocode, let's start by making the tree's representation concrete:
typedef enum {ADD, MUL} binop_t; typedef struct tree_node_s { enum {NUM, BINOP} kind; union { modref_t* num; struct { binop_t binop; modref_t* left; modref_t* right; } binop; } u; } tree_node_t;
The nodes of the tree are represented by the type tree_node_t
. Each tree node contains a kind
which is either NUM
or BINOP
. If the kind is NUM
, the node holds a number in a modref. If the kind is BINOP
, the node contains the type of operation, binop
(of type binop_t
), and two modrefs, left
and right
, which contain pointers to the node's subtrees.
Given this concrete representation, we can write a core program to evaluate a given tree as follows:
afun tree_eval(tree_node_t* node, modref_t* result) { if(node->kind == NUM) { write_num(result, read_num(node->u.num)); } else if(node->kind == BINOP) { modref_t *result_left = modref(); tree_eval(read(node->u.binop.left), result_left); modref_t *result_right = modref(); tree_eval(read(node->u.binop.right), result_right); if(node->u.binop.binop == ADD) { write_num(result, read_num(result_left) + read_num(result_right)); } else if(node->u.binop.binop == MUL) { write_num(result, read_num(result_left) * read_num(result_right)); } else { abort(); } } else { abort(); } }
This code realizes the psuedocode we wrote earlier. It uses two simple macros, read_num
and write_num
, which hide the casting between void*
and int
for read
and write
operations, respectively:
#define read_num(m) ((int) read(m)) #define write_num(m, num) write(m, (void*)(num))
Example: Arithmetic Trees: Full Code contains the full code for this example, including a meta program that changes each leaf node and runs change propagation.