;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ARITHMETICAL EXPRESSIONS WITH CONDITIONALS ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #lang play #| ::= | (add ) | (sub ) | (if0 ) |# ;; Inductive type for representing arith- ;; metical expressions with conditionals (deftype Expr (num n) (add l r) (sub l r) (if0 c t f)) #| ::= | (list '+ ) | (list '- ) | (list 'if0 ) |# ;; s-expressions used as concrete syntax ;; for writing arithmetical expressions ;; with conditionals ;; parse :: s-expr -> Expr ;; converts s-expressions into Exprs (define (parse s-expr) (match s-expr [ n #:when (number? n) (num n) ] [(list '+ l r) (add (parse l) (parse r))] [(list '- l r) (sub (parse l) (parse r))] [(list 'if0 c t f) (if0 (parse c) (parse t) (parse f))])) ;; calc :: Expr -> number ;; evaluates arithmetical expressions ;; with conditionals (define (calc expr) (match expr [(num n) n] [(add l r) (+ (calc l) (calc r))] [(sub l r) (- (calc l) (calc r))] [(if0 c t f) (if (zero? (calc c)) (calc t) (calc f))])) ;; run :: s-expr -> number ;; evaluates an arithmetical expression with ;; conditionals given in concrete syntax (define (run prog) (calc (parse prog))) ;; some testing... (define my-s-expr '(+ (- 8 6) (if0 0 2 20))) (printf "Input expression: ") my-s-expr (printf "Abstract representation: ") (parse my-s-expr) (printf "Evaluation: ") (run my-s-expr)