Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Demo: Expression Evaluator

This demo evaluates arithmetic expressions represented as an AST with constructors for literals, addition, multiplication, and negation. Alongside evaluation, it computes expression depth and performs a small simplification pass, showing how one tree structure can support multiple independent recursive analyses and transformations.

Related reading: Abstract syntax tree.

The code defines one ADT (Expr) and then reuses it across three traversals: eval computes numeric meaning, depth computes structural height, and simplify_once applies a local rewrite rule for double negation. In the final expression block, two sample trees are built, one is simplified once, and the output tuple shows evaluation and depth results side-by-side.

type Expr = Lit i32 | Add Expr Expr | Mul Expr Expr | Neg Expr

fn eval : Expr -> i32 = \e ->
  match e
    when Lit n -> n
    when Add a b -> eval a + eval b
    when Mul a b -> eval a * eval b
    when Neg x -> 0 - eval x

fn depth : Expr -> i32 = \e ->
  match e
    when Lit _ -> 1
    when Add a b ->
      if depth a > depth b then 1 + depth a else 1 + depth b
    when Mul a b ->
      if depth a > depth b then 1 + depth a else 1 + depth b
    when Neg x -> 1 + depth x

fn simplify_once : Expr -> Expr = \e ->
  match e
    when Neg (Neg x) -> x
    when _ -> e

let
  expr1 = Add (Lit 2) (Mul (Lit 3) (Lit 4)),
  expr2 = Neg (Neg (Add (Lit 5) (Mul (Lit 1) (Lit 9))))
in
  let simplified = simplify_once expr2 in
  (eval expr1, depth expr1, eval simplified)