;; Core parser helpers — shared by er-parse-expr and er-parse-module. ;; Everything reads/mutates a parser state dict: ;; {:toks TOKS :idx INDEX} (define er-state-make (fn (toks) {:idx 0 :toks toks})) (define er-peek (fn (st offset) (let ((toks (get st :toks)) (idx (+ (get st :idx) offset))) (if (< idx (len toks)) (nth toks idx) (nth toks (- (len toks) 1)))))) (define er-cur (fn (st) (er-peek st 0))) (define er-cur-type (fn (st) (get (er-cur st) :type))) (define er-cur-value (fn (st) (get (er-cur st) :value))) (define er-advance! (fn (st) (dict-set! st :idx (+ (get st :idx) 1)))) (define er-at-eof? (fn (st) (= (er-cur-type st) "eof"))) (define er-is? (fn (st type value) (and (= (er-cur-type st) type) (or (= value nil) (= (er-cur-value st) value))))) (define er-expect! (fn (st type value) (if (er-is? st type value) (let ((t (er-cur st))) (er-advance! st) t) (error (str "Erlang parse: expected " type (if value (str " '" value "'") "") " but got " (er-cur-type st) " '" (er-cur-value st) "' at pos " (get (er-cur st) :pos))))))