summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-09-25 07:57:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-09-25 07:57:34 -0700
commite4ad31de61b548238cb53b6a572dc7f16d93d78f (patch)
tree446c39df075843aa44639d04695a98671b94c253 /share
parent0ad39c713f1d0239abda6cece563c0964a1ea5e0 (diff)
downloadtxr-e4ad31de61b548238cb53b6a572dc7f16d93d78f.tar.gz
txr-e4ad31de61b548238cb53b6a572dc7f16d93d78f.tar.bz2
txr-e4ad31de61b548238cb53b6a572dc7f16d93d78f.zip
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.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/awk.tl50
1 files changed, 27 insertions, 23 deletions
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