summaryrefslogtreecommitdiffstats
path: root/stdlib/awk.tl
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/awk.tl')
-rw-r--r--stdlib/awk.tl143
1 files changed, 79 insertions, 64 deletions
diff --git a/stdlib/awk.tl b/stdlib/awk.tl
index be1c4758..50121736 100644
--- a/stdlib/awk.tl
+++ b/stdlib/awk.tl
@@ -42,11 +42,13 @@
rec orig-rec fields nf
rng-vec (rng-n 0)
par-mode par-mode-fs par-mode-prev-fs
+ rec-to-f
(streams (hash :equal-based))
(:fini (self)
(dohash (#:k v self.streams)
(close-stream v)))
(:postinit (self)
+ self.(upd-rec-to-f)
(set self.inputs (or self.inputs (zap *args*) (list *stdin*)))
(if (plusp self.rng-n)
(set self.rng-vec (vector self.rng-n)))
@@ -68,52 +70,62 @@
rng-exprs
outer-env)
-(defmeth sys:awk-state rec-to-f (self)
- (cond
- (self.fw
- (unless (eq self.fw-prev self.fw)
- (let ((ranges (reduce-left
- (tb ((list . sum) item)
- (let ((ns (+ sum item)))
- ^((,*list #R(,sum ,ns)) . ,ns)))
- self.fw '(nil . 0))))
- (set self.fw-prev self.fw
- self.fw-ranges (car ranges))))
- (let ((i 0) end
- (l (length self.rec)))
- (set self.fields
- (build (each ((r self.fw-ranges))
- (set end (to r))
- (if (>= (from r) l)
- (return nil))
- (add [self.rec r])
- (inc i))
- (if (< end l)
- (add [self.rec end..:])))
- self.nf i)))
- (self.fs
- (when self.ft
- (awk-error "both fs and ft set"))
- (if (and (not self.kfs) (equal self.rec ""))
- (set self.fields nil
- self.nf 0)
- (let ((eff-fs (if self.par-mode
- (if (equal self.fs self.par-mode-prev-fs)
- self.par-mode-fs
- (set self.par-mode-prev-fs self.fs
- self.par-mode-fs
- (regex-compile ^(or ,(if (regexp self.fs)
- (regex-source self.fs)
- self.fs)
- "\n"))))
- self.fs)))
- (set self.fields (split-str self.rec eff-fs self.kfs)
- self.nf (length self.fields)))))
- (self.ft
- (set self.fields (tok-str self.rec self.ft self.kfs)
- self.nf (length self.fields)))
- ((set self.fields (tok-str self.rec #/[^ \t\n]+/ self.kfs)
- self.nf (length self.fields)))))
+(defmeth sys:awk-state upd-rec-to-f (self)
+ (set self.rec-to-f
+ (cond
+ (self.fw
+ (unless (eq self.fw-prev self.fw)
+ (let ((ranges (reduce-left
+ (tb ((list . sum) item)
+ (let ((ns (+ sum item)))
+ ^((,*list #R(,sum ,ns)) . ,ns)))
+ self.fw '(nil . 0))))
+ (set self.fw-prev self.fw
+ self.fw-ranges (car ranges))))
+ (lambda (self)
+ (let ((i 0) end
+ (l (length self.rec)))
+ (set self.fields
+ (build (each ((r self.fw-ranges))
+ (set end (to r))
+ (if (>= (from r) l)
+ (return nil))
+ (add [self.rec r])
+ (inc i))
+ (if (< end l)
+ (add [self.rec end..:])))
+ self.nf i))))
+ (self.fs
+ (when self.ft
+ (awk-error "both fs and ft set"))
+ (let ((eff-fs (if self.par-mode
+ (if (equal self.fs self.par-mode-prev-fs)
+ self.par-mode-fs
+ (set self.par-mode-prev-fs self.fs
+ self.par-mode-fs
+ (regex-compile ^(or ,(if (regexp self.fs)
+ (regex-source self.fs)
+ self.fs)
+ "\n"))))
+ self.fs)))
+ (if self.kfs
+ (lambda (self)
+ (set self.fields (split-str self.rec eff-fs t)
+ self.nf (length self.fields)))
+ (lambda (self)
+ (if (equal self.rec "")
+ (set self.fields nil
+ self.nf 0)
+ (set self.fields (split-str self.rec eff-fs nil)
+ self.nf (length self.fields)))))))
+ (self.ft
+ (lambda (self)
+ (set self.fields (tok-str self.rec self.ft self.kfs)
+ self.nf (length self.fields))))
+ (t
+ (lambda (self)
+ (set self.fields (tok-str self.rec #/[^ \t\n]+/ self.kfs)
+ self.nf (length self.fields)))))))
(defmeth sys:awk-state f-to-rec (self)
(set self.rec `@{self.fields self.ofs}`))
@@ -147,23 +159,26 @@
(set cached-rr
(cond
((and (equal aws.rs "\n") (not aws.krs))
- (set aws.par-mode nil)
- (lambda () (get-line *stdin*)))
+ (set aws.par-mode nil)
+ aws.(upd-rec-to-f)
+ (lambda () (get-line *stdin*)))
((null aws.rs)
- (set aws.par-mode t)
- (let ((rin (record-adapter #/\n[ \n\t]*\n/))
- (flag t))
- (lambda ()
- (let ((r (get-line rin)))
- (cond
- (flag
- (set flag nil)
- (if (equal r "")
- (get-line rin)
- r))
- (t r))))))
+ (set aws.par-mode t)
+ aws.(upd-rec-to-f)
+ (let ((rin (record-adapter #/\n[ \n\t]*\n/))
+ (flag t))
+ (lambda ()
+ (let ((r (get-line rin)))
+ (cond
+ (flag
+ (set flag nil)
+ (if (equal r "")
+ (get-line rin)
+ r))
+ (t r))))))
(t
(set aws.par-mode nil)
+ aws.(upd-rec-to-f)
(let ((rin (record-adapter
(if (regexp aws.rs) aws.rs
(regex-compile ^(compound, aws.rs)))
@@ -377,10 +392,10 @@
(fname (qref ,aws-sym file-name))
(rs (qref ,aws-sym rs))
(krs (qref ,aws-sym krs))
- (fs (qref ,aws-sym fs))
- (ft (qref ,aws-sym ft))
- (fw (qref ,aws-sym fw))
- (kfs (qref ,aws-sym kfs))
+ (fs (usr:rslot ,aws-sym 'fs 'upd-rec-to-f))
+ (ft (usr:rslot ,aws-sym 'ft 'upd-rec-to-f))
+ (fw (usr:rslot ,aws-sym 'fw 'upd-rec-to-f))
+ (kfs (usr:rslot ,aws-sym 'kfs 'upd-rec-to-f))
(ofs (qref ,aws-sym ofs))
(ors (qref ,aws-sym ors)))
(macrolet ((next () '(return-from :awk-rec))