interpret.scm 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #lang racket
  2. (require racket/match)
  3. (require "utilities.scm")
  4. (require "box.scm")
  5. (require "environment.scm")
  6. (require "syntax.scm")
  7. (provide interpret-program)
  8. ;;; interpreter
  9. ;;
  10. (define (interpret-program prg env)
  11. (if (null? prg)
  12. #t
  13. (match (car prg)
  14. ((list (syx 'id 'define meta-1) (syx 'id name meta-2) exp)
  15. (update-env! env (make-binding name (interpret-exp exp env)))
  16. (interpret-program (cdr prg) env)))))
  17. (define (interpret-exp exp env)
  18. (cond ((syx-atomic? exp) (syx-data exp))
  19. ((syx-id? exp) (env-ref (syx-id exp) env))
  20. ((null? exp) '())
  21. ((and (pair? exp) (syx-special? (car exp)))
  22. (interpret-special exp env))
  23. ((pair? exp)
  24. (apply (interpret-exp (car exp) env)
  25. (map (lambda (e) (interpret-exp e env)) (cdr exp))))
  26. (else (error "interpret-exp: unknown syntax" exp))))
  27. (define (interpret-special exp env)
  28. (match exp
  29. ((list (syx 'special 'lambda meta) params body)
  30. (let ((param-names (map syx-id params)))
  31. (lambda args
  32. (let ((env (extend-env* env (map make-binding param-names args))))
  33. (interpret-exp body env)))))
  34. ((list* (syx 'special 'begin meta) stmts)
  35. (let loop ((stmts stmts))
  36. (if (null? (cdr stmts))
  37. (interpret-exp (car stmts) env)
  38. (begin
  39. (interpret-exp (car stmts) env)
  40. (loop (cdr stmts))))))
  41. ((list (syx 'special 'if meta) t c a)
  42. (if (interpret-exp t env)
  43. (interpret-exp c env)
  44. (interpret-exp a env)))
  45. ((list (syx 'special 'quote meta) d)
  46. d)
  47. (else (error "invalid syntax in interpret special" exp))))