;; Struttura dati "Stack" ;; ;; la pila (stack) e' intesa come variabile di stato ;; ;; Operazioni: ;; ;; (empty-stack) : -> pila ;; ;; (empty? ) : pila -> booleano ;; ;; (top ) : pila -> elemento ;; ;; (push! ) : elemento x pila -> pila ;; ;; (pop! ) : pila -> pila ;; ;; (compute! ) : operazione x pila -> pila ;; Valutazione di espressioni RPN ;; ;; Rivisitazione in termini di transizioni di stato ;; secondo il paradigma imperativo, da confrontare ;; con la versione precedente basata sul paradigma ;; funzionale (define compute-on-stack ; valore numerico (lambda (exp stk) ; exp espressione RPN, stk stack (show! exp stk) ; modifica stato di output (if (null? exp) (top stk) (let ((itm (car exp)) ) (if (number? itm) ; paradigma imperativo (push! itm stk) (compute! (get-operator itm) stk) ) (compute-on-stack (cdr exp) stk) )) )) ;; Per le seguenti procedure resta valida ;; la definizione data precedentemente: ;; ;; (eval-rpn ) ;; ;; (get-operator ) - tutte le varianti ;; Visualizzazione delle configurazioni (define show! (lambda (exp stk) (display exp) (newline) (display (extract (vector-ref stk 0) (cdr (vector->list stk))) ) (newline) (newline) )) (define extract (lambda (n lst) (if (= n 0) null (cons (car lst) (extract (- n 1) (cdr lst))) ) )) ;; Realizzazione della struttura dati "Stack" ;; attraverso il concetto di stato. (define empty-stack (lambda () (let ((stk (make-vector (+ max-size 1))) ) (vector-set! stk 0 0) stk ) )) (define empty? (lambda (stk) (= (vector-ref stk 0) 0) )) (define top (lambda (stk) (vector-ref stk (vector-ref stk 0)) )) (define push! (lambda (itm stk) (let ((sp (+ (vector-ref stk 0) 1)) ) (vector-set! stk 0 sp) (vector-set! stk sp itm) ) )) (define pop! (lambda (stk) (let ((sp (- (vector-ref stk 0) 1)) ) (vector-set! stk 0 sp) ) )) (define compute! (lambda (op stk) (let ((sp (- (vector-ref stk 0) 1))) (let ((1st (vector-ref stk sp)) (2nd (vector-ref stk (+ sp 1))) ) (vector-set! stk 0 sp) (vector-set! stk sp (op 1st 2nd)) )) ))