1(require-extension srfi-1)23(define (set-variable env variable)4 (let ((pair (assoc (car variable) env)))5 (if pair6 (begin7 (set-cdr! pair (cdr variable))8 env)9 (cons variable env))))1011(define (ntimes n fn arg)12 (if (> n 0)13 (ntimes (- n 1) fn (fn arg))14 arg))1516(define (variable-name lvalue)17 (assert (eq? (car lvalue) 'var))18 (cdr lvalue))1920(define (variable-value env variable)21 (assert (eq? (car variable) 'var))22 (let ((value (assoc (cdr variable) env)))23 (if value (cdr value) 0)))2425(define (eval-literal literal)26 (assert (eq? (car literal) 'lit))27 (cdr literal))2829(define (eval-operation op)30 (assert (eq? (car op) 'op))31 (let ((o (cdr op)))32 (cond ((eq? o 'plus) +)33 ((eq? o 'minus) -)34 (else (error "invalid operation")))))3536(define (eval-expression env expr)37 (assert (eq? (car expr) 'expr))38 (let ((v1 (eval-rvalue env (second expr)))39 (op (eval-operation (third expr)))40 (v2 (eval-rvalue env (fourth expr))))41 (op v1 v2)))4243(define (eval-rvalue env rvalue)44 (let ((kind (car rvalue)))45 (cond ((eq? kind 'lit)46 (eval-literal rvalue))47 ((eq? kind 'var)48 (variable-value env rvalue))49 ((eq? kind 'expr)50 (eval-expression env rvalue))51 (else (display kind) (newline) (error "invalid rvalue")))))5253(define (eval-assign env lvalue rvalue)54 (set-variable env (cons (variable-name lvalue)55 (eval-rvalue env rvalue))))5657(define (eval-loop env cond body)58 (let ((amount (eval-rvalue env cond)))59 (ntimes amount (lambda (env)60 (eval-loop-prog env body)) env)))6162(define (eval-command comp env)63 (let ((kind (car comp)) (args (cdr comp)))64 (cond ((eq? kind 'loop)65 (eval-loop env (first args) (second args)))66 ((eq? kind 'assign)67 (eval-assign env (first args) (second args)))68 (else (error "invalid command")))))6970(define (eval-loop-prog env prog)71 (fold eval-command env prog))