(define-module (catbird pushdown) #:use-module (chickadee data array-list) #:use-module (ice-9 match) #:use-module (oop goops) #:export ( make-pushdown-state state-current state-previous state-push! state-pop! state-replace!)) (define-class () (state-stack #:accessor state-stack #:init-form (make-array-list 2))) (define (make-pushdown-state) (make )) (define-method (state-current (state )) (let ((stack (state-stack state))) (if (array-list-empty? stack) #f (array-list-ref stack (- (array-list-size stack) 1))))) (define-method (state-previous (state )) (let* ((stack (state-stack state)) (n (array-list-size stack))) (if (< n 2) #f (array-list-ref stack (- n 2))))) (define-method (state-push! (state ) obj) (array-list-push! (state-stack state) obj)) (define-method (state-pop! (state )) (array-list-pop! (state-stack state))) (define-method (state-replace! (state ) obj) (let ((stack (state-stack state))) (if (array-list-empty? stack) (array-list-push! stack obj) (array-list-set! stack (- (array-list-size stack) 1) obj))))