Sikau

Build an interpreter · Day 6 · about 35 min

Evaluating expressions

Walk the syntax tree and compute values.

Making it run

Tree walking is not the fastest strategy, but it is the clearest, and every faster design builds on the same ideas.

Many real interpreters started exactly like this — early Ruby and many scripting languages walked their syntax trees directly.

The parser tells you what a program means; now something has to do it. A tree-walking interpreter is the simplest way: a recursive function evaluate(node) that looks at a node's type, evaluates its children, and combines the results. For (1 + (2 * 3)) it evaluates 1, then the inner * node (giving 6), then adds them.

evaluate(parse("1 + 2 * 3"))     // 7
evaluate(parse('"chi" + "ya"'))  // "chiya"
evaluate(parse("!(1 < 2)"))      // false

One case per node type

Chiya values are plain JavaScript values: numbers, strings, true/false and null. That makes the evaluator short. Literals return their value. A Prefix node evaluates its operand and applies - or !. An Infix node evaluates both sides and hands them to an infix(op, a, b) helper. A Program evaluates each statement and keeps the last value.

function evaluate(node) {
  switch (node.type) {
    case "Number": case "String": case "Bool": return node.value;
    case "Prefix": {
      const v = evaluate(node.right);
      if (node.op === "!") return !truthy(v);
      return -v; // after checking it's a number
    }
    case "Infix": return infix(node.op, evaluate(node.left), evaluate(node.right));
  }
}

Decide truthiness once in a truthy(v) helper. In Chiya only false and null are falsy — so 0 and "" count as true, unlike JavaScript.

The rest of this lesson

  • Types and errorsexplain
  • What's the value?predict
  • Chiya's answersmatch
  • Evaluating 1 + 2 * 3order
  • The first evaluatorwrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of Build an interpreter