calculator — expression evaluator with ADTs

A tiny tree-walking interpreter for arithmetic expressions. type Expr = | Num x | Add a b | Mul a b | Neg a defines the AST; eval recursively reduces it to an int.

\1 (examples/calculator.rail):


-- calculator.rail — expression evaluator using algebraic data types
--
-- Demonstrates: ADTs (type), pattern matching (match), recursive evaluation,
--               nested constructors

type Expr = | Num x | Add a b | Mul a b | Neg a

eval e = match e
  | Num x -> x
  | Add a b -> eval a + eval b
  | Mul a b -> eval a * eval b
  | Neg a -> 0 - eval a

describe e = match e
  | Num x -> show x
  | Add a b -> "add"
  | Mul a b -> "mul"
  | Neg a -> "neg"

main =
  -- 5
  let e1 = Num 5
  let _ = print (show (eval e1))

  -- 3 + 4 = 7
  let e2 = Add (Num 3) (Num 4)
  let _ = print (show (eval e2))

  -- 6 * 7 = 42
  let e3 = Mul (Num 6) (Num 7)
  let _ = print (show (eval e3))

  -- (2 * 3) + 4 = 10
  let e4 = Add (Mul (Num 2) (Num 3)) (Num 4)
  let _ = print (show (eval e4))

  -- (3 + 4) * (5 + 6) = 77
  let e5 = Mul (Add (Num 3) (Num 4)) (Add (Num 5) (Num 6))
  let _ = print (show (eval e5))

  -- neg(10) + 15 = 5
  let e6 = Add (Neg (Num 10)) (Num 15)
  let _ = print (show (eval e6))

  0

\1


./rail_native run examples/calculator.rail

\1


5
7
42
10
77
5

This is the standard shape of every interpreter you'll write in Rail: an Expr ADT, an eval match that does one arm per constructor, and main building expression trees with the constructors directly.

Rail — self-hosted compiler · All docs · GitHub