diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-09-18 17:23:05 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-09-18 17:23:05 -0700 |
commit | 5eb43586824efc00a733df1df6a2420c90bf3eb2 (patch) | |
tree | 368148fd4a052f78f1c59216fba80e9ffa3e4646 /share | |
parent | 0bdd5c59675cce09791d51c8d533a9d14ca8da56 (diff) | |
download | txr-5eb43586824efc00a733df1df6a2420c90bf3eb2.tar.gz txr-5eb43586824efc00a733df1df6a2420c90bf3eb2.tar.bz2 txr-5eb43586824efc00a733df1df6a2420c90bf3eb2.zip |
New awk operator: fconv.
* share/txr/stdlib/awk.tl (sys:awk-let): Add new symbol
macro, fconv.
* share/txr/stdlib/conv.tl: New file.
* txr.1: Documented fconv.
Diffstat (limited to 'share')
-rw-r--r-- | share/txr/stdlib/awk.tl | 6 | ||||
-rw-r--r-- | share/txr/stdlib/conv.tl | 83 |
2 files changed, 88 insertions, 1 deletions
diff --git a/share/txr/stdlib/awk.tl b/share/txr/stdlib/awk.tl index bc5dc9dd..b1e9f509 100644 --- a/share/txr/stdlib/awk.tl +++ b/share/txr/stdlib/awk.tl @@ -23,6 +23,8 @@ ;; AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS ;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +(load "conv.tl") + (defstruct sys:awk-state () (rs "\n") krs fs ft kfs @@ -202,7 +204,9 @@ (set f [(opip ,*opip-args) f]))) (mf (. opip-args) ^(symacrolet ((f (rslot ,',aws-sym 'fields 'f-to-rec))) - (set f (mapcar (opip ,*opip-args) f))))) + (set f (mapcar (opip ,*opip-args) f)))) + (fconv (. conv-args) + ^(set f (sys:conv (,*conv-args) f)))) ,*body))) (defmacro awk (:env e . clauses) diff --git a/share/txr/stdlib/conv.tl b/share/txr/stdlib/conv.tl new file mode 100644 index 00000000..546b8759 --- /dev/null +++ b/share/txr/stdlib/conv.tl @@ -0,0 +1,83 @@ +;; Copyright 2016 +;; Kaz Kylheku <kaz@kylheku.com> +;; Vancouver, Canada +;; All rights reserved. +;; +;; Redistribution of this software in source and binary forms, with or without +;; modification, is permitted provided that the following two conditions are met. +;; +;; Use of this software in any manner constitutes agreement with the disclaimer +;; which follows the two conditions. +;; +;; 1. Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; 2. Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in +;; the documentation and/or other materials provided with the +;; distribution. +;; +;; THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED +;; WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE +;; COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES, HOWEVER CAUSED, +;; AND UNDER ANY THEORY OF LIABILITY, ARISING IN ANY WAY OUT OF THE USE OF THIS +;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +(defun sys:conv-let (. body) + ^(flet ((i (arg : radix) + (toint arg radix)) + (o (arg) + (toint arg 8)) + (x (arg) + (toint arg 16)) + (b (arg) + (toint arg 2)) + (r (arg) + (tofloat arg))) + ,*body)) + +(defun sys:do-conv (lfl mfl tfl nm list) + (while (and list lfl) + (set (car list) (call (car lfl) (car list))) + (set list (cdr list)) + (set lfl (cdr lfl))) + (dotimes (i nm) + (unless list + (return)) + (when mfl + (set (car list) (call (car mfl) (car list))) + (set mfl (cdr mfl))) + (set list (cdr list))) + (while (and list tfl) + (set (car list) (call (car tfl) (car list))) + (set list (cdr list)) + (set tfl (cdr tfl)))) + +(defun sys:conv-expand (form specs list-sym) + (mac-param-bind form (lead : mid trail) + (split* (mapcar [iff (op eq :) + identity + [iff (op eq '-) + (retf '(fun identity)) + (ret ^[identity ,@1])]] + specs) + (op where (op eq :))) + (let ((nl (length lead)) + (nt (length trail))) + (with-gensyms (i nm lfl mfl tfl) + (sys:conv-let + ^(let* ((,nm (- (length ,list-sym) ,(+ nl nt))) + (,lfl (list ,*lead)) + (,mfl (if (plusp ,nm) (repeat (list ,*mid)))) + (,tfl (list ,*trail))) + (sys:do-conv ,lfl ,mfl ,tfl ,nm ,list-sym))))))) + +(defmacro sys:conv (:form form (. specs) list-expr) + (cond + ((null specs) list-expr) + ((atom specs) + (throwf 'eval-error "sys:conv: invalid conversion list: ~s" specs)) + (t (with-gensyms (list-sym) + ^(let ((,list-sym ,list-expr)) + ,(sys:conv-expand form specs list-sym) + ,list-sym))))) |