Jotter <2026-04-20 Mon>

(ql:quickload '(:iterate
                :metabang-bind
                :metabang-bind-ppcre
                :trivia
                :trivia.quasiquote
                :named-readtables))

(defpackage :advprog
  (:use
    :cl :iterate :metabang-bind
    :trivia :named-readtables))

(in-package :advprog)

(in-readtable :fare-quasiquote)


;;; Some arithmetic expressions

;; 3
;; (+ 3 4)
;; (* 3 5)
;; (+ (* 3 4) (* 5 6))

;;; A first arithmetic interpreter

(defun interpret (ast)
  (cond ((numberp ast) ast)
        ((and (consp ast) (eq '+ (first ast)))
         (+ (interpret (second ast))
            (interpret (third ast))))
        ((and (consp ast) (eq '* (first ast)))
         (* (interpret (second ast))
            (interpret (third ast))))
        (t (error "Unrecognised AST: ~a" ast))))

(interpret 33)

(interpret '(+ 2 3))

(interpret '(* 2 3))

(interpret '(+ (* 3 4) (* 5 6)))

(interpret '(- 5 3))

(interpret "3 + 4")

;;; An arithmetic interpreter using case

(bind ((light 'white))
  (case light
    (red 'stop)
    (amber 'wait)
    (green 'go)))

(bind ((light 'white))
  (ecase light
    (red 'stop)
    (amber 'wait)
    (green 'go)))

(defun interpret (ast)
  (cond ((numberp ast) ast)
        ((consp ast)
         (case (first ast)
           (+ (+ (interpret (second ast))
                 (interpret (third ast))))
           (* (* (interpret (second ast))
                 (interpret (third ast))))
           (t (error "Unrecognised operator: ~a" (first ast)))))
        (t (error "Unrecognised AST: ~a" ast))))

;; with ecase

(defun interpret (ast)
  (cond ((numberp ast) ast)
        ((consp ast)
         (ecase (first ast)
           (+ (+ (interpret (second ast))
                 (interpret (third ast))))
           (* (* (interpret (second ast))
                 (interpret (third ast))))))
        (t (error "Unrecognised AST: ~a" ast))))

;;; An arithmetic interpreter with matching

(defun interpret (ast)
  (match ast
    ((type number) ast)
    (`(+ ,l ,r) (+ (interpret l) (interpret r)))
    (`(* ,l ,r) (* (interpret l) (interpret r)))
    (_ (error "Unrecognized AST: ~a" ast))))

;; with ematch

(defun interpret (ast)
  (ematch ast
    ((type number) ast)
    (`(+ ,l ,r) (+ (interpret l) (interpret r)))
    (`(* ,l ,r) (* (interpret l) (interpret r)))))

Author: Breanndán Ó Nualláin <o@uva.nl>

Date: 2026-05-07 Thu 09:14