(load "syntax.scm")
(load "meval.scm")
(define *meval-warn-define* #t)
(load "environment.scm")
(load "assert.scm")
(define (m-eval exp env)
(cond ((self-evaluating? exp) exp)
((variable? exp) (lookup-variable-value exp env))
((quoted? exp) (text-of-quotation exp))
((assignment? exp) (eval-assignment exp env))
((definition? exp) (eval-definition exp env))
((if? exp) (eval-if exp env))
((lambda? exp)
(make-procedure (lambda-parameters exp) (lambda-body exp) env))
((begin? exp) (eval-sequence (begin-actions exp) env))
((cond? exp) (m-eval (cond->if exp) env))
((let? exp) (m-eval (let->application exp) env))
((until? exp) (eval-until exp env))
((application? exp)
(m-apply (m-eval (operator exp) env)
(list-of-values (operands exp) env)))
(else (error "Unknown expression type -- EVAL" exp))))
(define (until? exp) (tagged-list? exp 'until))
(define (until-test exp) (second exp))
(define (until-expressions exp) (cddr exp))
(define (eval-until exp env)
(cond ((m-eval (until-test exp) env) 'done)
(else (eval-sequence (until-expressions exp) env)
(m-eval exp env))))
(refresh-global-environment)
(m-eval '(define x 10) the-global-environment)
(m-eval '(define numbers-viewed '()) the-global-environment)
(m-eval '(until (= x 0)
(set! numbers-viewed (cons x numbers-viewed))
(set! x (- x 1)))
the-global-environment)
(assert-equal (m-eval 'numbers-viewed the-global-environment)
'(1 2 3 4 5 6 7 8 9 10))