#lang plai ;; AE = arithmetic expression ;; AE = number ;; | + AE AE ;; | - AE AE (define-type AE [num (n number?)] [add (left AE?) (right AE?)] [sub (left AE?) (right AE?)]) ;; parse : s-expr -> AE (define (parse input) (cond ;; [(number? input) (num input)] ;; '{+ } [(and (= 3 (length input)) (eq? (first input) '+)) (add (parse (second input)) (parse (third input)))] ;; '{- } [(and (= 3 (length input)) (eq? (first input) '-)) (sub (parse (second input)) (parse (third input)))] [else (error 'parse "bad syntax: ~a" input)])) (test (parse '1) (num 1)) (test (parse '{+ 1 2}) (add (num 1) (num 2))) (test (parse '{+ {- 5 2} {+ 2 1}}) (add (sub (num 5) (num 2)) (add (num 2) (num 1)))) ;; AE -> num (define (interpret ae) (type-case AE ae [num (n) n] [add (left right) (+ (interpret left) (interpret right))] [sub (left right) (- (interpret left) (interpret right))])) (test (interpret (num 1)) 1) (test (interpret (add (num 1) (num 2))) 3) (test (interpret (parse '{+ 1 1})) 2) (test (interpret (parse '{- 4 1})) 3)