From e4ad31de61b548238cb53b6a572dc7f16d93d78f Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 25 Sep 2016 07:57:34 -0700 Subject: awk macro: loop uses closure to read records. * share/txr/stdlib/awk.tl (sys:awk-state loop): Refactor code so that record-processing loop obtains a lambda which is called to extract a record. If rs and krs did not change, then the same lambda is obtained from a variable which caches it. The get-rec-reader local function thus encapsulates the whole record delimiting strategy as well as changes to the variables. With this structure, it will be relatively easy to add support for Awk's paragraph mode, which is notably missing in the implementation. --- share/txr/stdlib/awk.tl | 50 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) (limited to 'share') diff --git a/share/txr/stdlib/awk.tl b/share/txr/stdlib/awk.tl index 404c3aab..9ae7c569 100644 --- a/share/txr/stdlib/awk.tl +++ b/share/txr/stdlib/awk.tl @@ -82,34 +82,38 @@ (inc aws.file-num) (when beg-file-func [beg-file-func aws]) - (flet ((get-stream (stin) - (if (and (equal aws.rs "\n") - (not aws.krs)) - stin - (record-adapter (if (regexp aws.rs) - aws.rs - (regex-compile aws.rs)) - stin - aws.krs)))) - (unwind-protect - (let* ((stin (if (streamp in) in (open-file in))) - (recin (get-stream stin)) - (noted-rs aws.rs) - (noted-krs aws.krs)) - (set aws.file-rec-num 0) - (whilet ((rec (get-line recin))) + (let* ((stin (if (streamp in) in (open-file in))) + (noted-rs (not aws.rs)) + (noted-krs (not aws.krs)) + (cached-rr nil)) + (flet ((get-rec-reader (stin) + (cond + ((and (equal noted-rs aws.rs) (eq noted-krs aws.krs)) + cached-rr) + (t + (set noted-rs aws.rs noted-krs aws.krs) + (set cached-rr + (if (and (equal aws.rs "\n") + (not aws.krs)) + (lambda () (get-line stin)) + (let ((rin (record-adapter (if (regexp aws.rs) + aws.rs + (regex-compile aws.rs)) + stin + aws.krs))) + (lambda () (get-line rin))))))))) + (set aws.file-rec-num 0) + (unwind-protect + (whilet ((rr (get-rec-reader stin)) + (rec (call rr))) (set aws.rec rec aws.orig-rec rec) (inc aws.rec-num) (inc aws.file-rec-num) aws.(rec-to-f) (block :awk-rec - [func aws]) - (unless (and (equal noted-rs aws.rs) - (eq noted-krs aws.krs)) - (set recin (get-stream stin)) - (set noted-rs aws.rs noted-krs aws.krs)))) - (when end-file-func - [end-file-func aws])))))) + [func aws])) + (when end-file-func + [end-file-func aws]))))))) (defmeth sys:awk-state prn (self . args) (cond -- cgit v1.2.3