I call this one
Wait for it to load -- it's not as fast as m i c h a e l's vids. ("Wait for it ...")
And please don't shoot spitwads at the new substitute! :-)
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Show posts Menu
(dolist x xs
(catch
(let
...something...
(if condition-holds (throw 'escape))
...something...)))
(throw 'tantrum)
(throw 'curveball)
(throw 22)
<img src="Really-long-image-resource-name-that-goes-on-and-on"
height="100" width="150" border="1"/>
;;;; tidy.lsp -- A module to interface TidyLib
;;;; Author: Rick Hanson
;;;; Date: 17 June 2007
(context 'tidy)
;;;---------------------------------------------------------
;;; U S E R C O N F I G U R A T I O N
;;;
;;; Read the desciptions of the following two variables,
;;; and change as appropriate for your needs.
;; This is the location of your TidyLib shared library
;; On Macs it's called libtidy.dylib, on Win32 machines
;; it's called libtidy.dll, on the Penguin and Unices it's
;; called libtidy.so.
(define libtidy "/usr/lib/libtidy.dylib")
;; According to Lutz, you probably don't need to change this.
;; Change it to 64, ONLY IF you know your TidyLib (and probably
;; the rest of your system + newLISP) is LP64.
(define machine-address-size-in-bits 32)
;;;---------------------------------------------------------
;;; B O I L E R P L A T E C O D E F O L L O W S
;;;
;;; (meaning that, if you're
;;; (a) just a user of this module AND
;;; (b) you're lucky,
;;; then you won't need to change the code below this line.)
;;; :-)
(import libtidy "tidyCreate")
(import libtidy "tidyOptSetBool")
(import libtidy "tidySetErrorBuffer")
(import libtidy "tidyParseString")
(import libtidy "tidyCleanAndRepair")
(import libtidy "tidyRunDiagnostics")
(import libtidy "tidySaveBuffer")
(import libtidy "tidyBufFree")
(import libtidy "tidyRelease")
(import libtidy "tidyReleaseDate")
(define machine-address-size-in-bytes
(/ machine-address-size-in-bits 8))
(define size-of-u_int machine-address-size-in-bytes)
(define size-of-address-pointer machine-address-size-in-bytes)
(define tidy-release-date
(let ((pd (parse (get-string (tidy:tidyReleaseDate))))
(months '("Month0" "January" "February" "March" "April"
"May" "June" "July" "August" "September"
"October" "November" "December")))
(if (= (length pd) 4)
(date-value (int (pd 3)) (find (pd 2) months) (int (pd 0)))
(date-value (int (pd 2)) (find (pd 1) months) (int (pd 0))))))
;;; Since TidyBuffer (in buffio.h) changed on 2006-12-29, this code
;;; checks to see if your TidyLib's release date is before or
;;; on-or-after this date, and tries to do the right thing. This
;;; would all be easier if the Tidy developers used version numbers.
;;;
;;; The right thing is the setup of the following two variables:
;;;
;;; empty-TidyBuffer: an allocation of enough space to account
;;; for the size of a TidyBuffer.
;;;
;;; bp-offset: the offset from the start of the TidyBuffer
;;; struct to struct member `bp', where the TidyLib text output
;;; is stored.
(let ((TidyBuffer-change-date (date-value 2006 12 29)))
(cond
((< tidy-release-date TidyBuffer-change-date)
;; struct _TidyBuffer
;; {
;; byte* bp; /**< Pointer to bytes */
;; uint size; /**< # bytes currently in use */
;; uint allocated; /**< # bytes allocated */
;; uint next; /**< Offset of current input position */
;; };
(define empty-TidyBuffer
(dup " 00" (+ size-of-address-pointer
(* 3 size-of-u_int))))
(define bp-offset 0))
(true
;; struct _TidyBuffer
;; {
;; TidyAllocator* allocator; /**< Memory allocator */
;; byte* bp; /**< Pointer to bytes */
;; uint size; /**< # bytes currently in use */
;; uint allocated; /**< # bytes allocated */
;; uint next; /**< Offset of current input position */
;; };
(define empty-TidyBuffer
(dup " 00" (+ (* 2 size-of-address-pointer)
(* 3 size-of-u_int))))
(define bp-offset size-of-address-pointer))))
;;; The following flags are recovered from tidyenum.h of
;;; TidyLib. (Fortunately, the developers did not change the enums
;;; -- the old ones should stay the same from version to version.)
(define TidyXmlOut 22) ; Output XML.
(define TidyXhtmlOut 23) ; Output extensible HTML.
(define TidyHtmlOut 24) ; Output plain HTML, even for XHTML input.
(define TidyForceOutput 64) ; Output document even if errors were found.
(define no 0)
(define yes 1)
(define (tidy:tidy output-type input)
(let ((output empty-TidyBuffer)
(output-contents nil)
(errbuf empty-TidyBuffer)
(rc -1)
(ok nil)
(tdoc (tidyCreate)))
(setq ok (tidyOptSetBool tdoc output-type yes))
(if ok (setq rc (tidySetErrorBuffer tdoc errbuf)))
(if (>= rc 0)
(setq rc (tidyParseString tdoc input)))
(if (>= rc 0)
(setq rc (tidyCleanAndRepair tdoc)))
(if (>= rc 0)
(setq rc (tidyRunDiagnostics tdoc)))
(if (> rc 1)
(setq rc (if (not (= 0 (tidyOptSetBool tdoc
TidyForceOutput
yes)))
rc -1)))
(if (>= rc 0)
(setq rc (tidySaveBuffer tdoc output)))
(if (>= rc 0)
(setq output-contents
(get-string
(first
(unpack "lu"
(bp-offset size-of-address-pointer output)))))
(println (format "A severe error (%d) occurred.n" rc)))
(tidyBufFree output)
(tidyBufFree errbuf)
(tidyRelease tdoc)
output-contents))
(define xml<- (curry tidy TidyXmlOut))
(define xhtml<- (curry tidy TidyXhtmlOut))
(define html<- (curry tidy TidyHtmlOut))
(context MAIN)
> (load "tidy.lsp")
MAIN
> (print (tidy:xhtml<- "<title>Foo</title><p>Foo!"))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content=
"HTML Tidy for Mac OS X (vers 1st December 2004), see www.w3.org" />
<title>Foo</title>
</head>
<body>
<p>Foo!</p>
</body>
</html>
> (load "mixed-radix.lsp")
MAIN
> (mixed-radix:new HHMMSS (hours minutes seconds) (1 60 60))
HHMMSS
> (HHMMSS:to-minutes '(3 34 42))
214.7
> (HHMMSS:to-seconds '(3 34 42))
12882
> (HHMMSS:from-minutes 214.7)
(3 34 42)
> (HHMMSS:from-seconds 12882)
(3 34 42)
> (HHMMSS:+ '(3 34 42) '(1 54 59))
(5 29 41)
;;--------------------------------------
;; Application: Floor plan lengths
(load "mixed-radix.lsp")
(mixed-radix:new ftin (feet inches) (1 12))
(define rawdims '((laundry ((5 5) (2 11) (4 6.5))
((7 1.5)))
(bath ((4 10.5))
((7 1)))
(family-room ((10 4.5) (8 11.5) (0 1))
((12 1) (10 0) (0 1)))))
(define (dim<-rawdim rawdim)
(list (rawdim 0)
(apply ftin:add (rawdim 1))
(apply ftin:add (rawdim 2))))
(define dims (map dim<-rawdim rawdims))
(define (sqft<-dim dim)
(list (dim 0)
(mul (ftin:to-feet (dim 1))
(ftin:to-feet (dim 2)))))
;; Show and tell.
(println "Dimensions:")
(println dims)
(define sqftages (map sqft<-dim dims))
(println "SQ FTages:")
(println sqftages)
(println "Total SQ FT = " (apply add (map last sqftages)))
Dimensions:
((laundry (12 10.5) (7 1.5)) (bath (4 10.5) (7 1)) (family-room (
19 5)
(22 2)))
SQ FTages:
((laundry 91.734375) (bath 34.53125) (family-room 430.4027778))
Total SQ FT = 556.6684028
;;;; mixed-radix.lsp -- Mixed radix numbers for newLISP
;;;; Author: Rick Hanson
;;;; Date: 9 June 2007
(context 'mixed-radix)
;;;-------------------------------------
;;; Slots and Constructor
(define labels '())
(define bases '())
(define-macro (mixed-radix:new mrn-symbol mrn-labels mrn-bases)
(letex (mrn-labels mrn-labels mrn-bases mrn-bases)
(MAIN:new 'mixed-radix mrn-symbol)
(let (ctx (eval mrn-symbol)
unqualify (lambda (symb) (replace ".*:" (string symb) "" 0)))
(setq ctx:labels (quote mrn-labels))
(setq ctx:bases (quote mrn-bases))
;; Setup the conversion functions for new instances.
(dolist (label ctx:labels)
(set (sym (append "to-" (unqualify label)) ctx)
(letex ($$idx $idx fsym (sym 'mid-units<-mixrad ctx))
(curry fsym $$idx)))
(set (sym (append "from-" (unqualify label)) ctx)
(letex ($$idx $idx fsym (sym 'mixrad<-mid-units ctx))
(curry fsym $$idx))))
mrn-symbol)))
;;;-------------------------------------
;;; Utilities used in this context.
(define (compose)
(apply (lambda (f g) (expand (lambda () (f (apply g (args)))) 'f 'g))
(args) 2))
(define-macro (kurry f)
(letex ($f (eval f)
$cargs (map eval (args)))
(lambda () (apply $f (append (quote $cargs) (args))))))
(define (butlast xs) (0 (- (length xs) 1) xs))
;; This version of `unfold' uses `while' and `setq' (for reasons of
;; time and space efficiency) -- "don't pay any attention to the man
;; behind the curtain!" :-)
(define (unfold p f g s post)
(let (acc '())
(while (not (p s))
(push (f s) acc -1)
(setq s (g s)))
(post p f g s acc)))
;;;-------------------------------------
;;; Method Definitions
(define (low-units<-mixrad M (bases bases))
"Convert a mixrad `M' to a scalar in low-order units with respect
to the list of bases `bases'."
(rotate bases -1)
(apply MAIN:add
(map (lambda (i) (mul (M i) (apply mul (i bases))))
(sequence 0 (- (length M) 1)))))
(define (high-units<-mixrad M (bases bases))
"Convert a mixrad `M' to a scalar in high-order units with
respect to the list of bases `bases'."
(div (low-units<-mixrad M) (apply mul bases)))
(define (mid-units<-mixrad mid M)
"Convert a mixrad `M' to a scalar in `mid'-order units with
respect to the list of bases `bases'. `mid' is zero-based. This
function acts as if the radix point of `M' were after the
`mid'-th digit (from the left). For instance to convert 3 hours,
34 minutes, 42 seconds into minutes, say
(mixed-radix:new HHMMSS (hours minutes seconds) (1 60 60))
(HHMMSS:mid-units<-mixrad 1 '(3 34 42))
which yields 214.7, as expected."
(letn (mid+1 (+ mid 1)
basesL (0 mid+1 bases)
digitsL (0 mid+1 M)
basesR (cons 1 (mid+1 bases))
digitsR (cons 0 (mid+1 M)))
(MAIN:add (low-units<-mixrad digitsL basesL)
(high-units<-mixrad digitsR basesR))))
(define (mixrad<-low-units N (bases bases))
"Convert `N', which is a scalar in low-order units, to a mixrad,
with respect to the list of bases 'bases'."
(rotate bases -1)
(unfold (lambda (s) (>= (s 1) (length bases)))
(lambda (s) (/ (s 0) (apply mul ((s 1) bases))))
(lambda (s) (list (mod (s 0) (apply mul ((s 1) bases))) (+ (s 1) 1)))
;; In the seed, keep track of the latest remainder AND an
;; incrementing index with which we use to slice `bases':
(list N 0)
;; In the post-processor, add the last remainder into the
;; last entry in the accumulated list:
(lambda (p f g s res0)
(append (butlast res0) (list (MAIN:add (s 0) (last res0)))))))
;; This is not used by any method or instance conversion function, but
;; is here for completion sake.
(define (mixrad<-high-units N (bases bases))
"Convert `N', which is a scalar in high-order units, to a mixrad,
with respect to the list of bases 'bases'."
(mixrad<-low-units (apply mul (cons N bases))))
(define (mixrad<-mid-units mid N)
"Convert `N', which is a scalar in mid-order units, to a mixrad,
with respect to the list of bases 'bases'."
(mixrad<-low-units (apply mul (cons N ((+ mid 1) bases)))))
;; Now it's easy to define a normalization function.
(define (normalize M)
"Return the canonical representation of mixrad `M' with respect to
the list of bases `bases'."
(mixrad<-low-units (low-units<-mixrad M)))
(define (component-wise-operator op) (compose normalize (kurry map op)))
(define mixed-radix:add (component-wise-operator MAIN:add))
(define mixed-radix:sub (component-wise-operator MAIN:sub))
(define mixed-radix:+ mixed-radix:add)
(define mixed-radix:- mixed-radix:sub)
(context MAIN)
> (define (f x y z) (* x (+ y z)))
> (define f-2-3 (curry f 2 3))
> (f-2-3 4)
value expected in function + : z
called from user defined function f
called from user defined function f-2-3
(define-macro (currie f)
(letex ($f (eval f)
$cargs (map eval (args)))
(lambda () (apply $f (append (quote $cargs) (args))))))
> (define f-2-3 (curry f 2 3))
> (f-2-3 4)
14
(define-macro (+-)
(let (signs (cons 1 (series 1 -1 (- (length (args)) 1))))
(apply 'add (map 'mul (map eval (args)) signs))))
(define (+-)
(let (signs (cons 1 (series 1 -1 (- (length (args)) 1))))
(apply add (map mul signs (args)))))
(load "/path/to/rickyboys/libs/mylib.lsp")
(load "mylib.lsp")
(define-macro (unwind-protect EXPR POSTLUDE)
(letex ($expr EXPR $postlude POSTLUDE)
(let (result nil)
(let (no-throw? (catch (let () $expr) 'result))
$postlude
(if no-throw? result (throw result))))))
(with-open-file (in "myfile" "read') bla bla bla ...)
(define-macro (with-open-file FLIST)
(letex ($fhandle-id (FLIST 0)
$path-file (FLIST 1)
$access-mode (FLIST 2)
$option (FLIST 3)
$body (cons 'begin (args)))
(let ($fhandle-id (open $path-file $access-mode $option))
(unwind-protect
$body
(if (peek $fhandle-id) (close $fhandle-id))))))
> (or nil 42)
42
> (or nil '())
nil
> (collect (x '(1 2 3) y '(4 5 6)) (list y x))
((4 1) (5 2) (6 3))
> (collect (x '(1 2 3) y '(4 5 6)) (println y) x)
4
5
6
(1 2 3)
`(map (fn ,vars ,@body) ,@lists)
(define-macro (collect)
(letn ((parms (args 0))
(plen (length parms))
(vars (list-nth (sequence 0 (- plen 1) 2) parms))
(lists (list-nth (sequence 1 (- plen 1) 2) parms))
(body (1 (args))))
(comma-expand (map (fn ,vars ,@body) ,@lists))))
; where 'list-nth' is defined as:
(define (list-nth indices lisst)
(map (fn (n) (nth n lisst)) indices))
(define-macro (comma-expand form)
(catch
(cond ((quote? form)
(comma-expand-func (eval form) '()))
((list? form)
(eval (comma-expand-func form '())))
(true form))))
(define (comma-expand-func form acc)
(cond
((not (list? form)) form)
((empty? form) (reverse acc))
((lambda? form)
(let ((fn-tail (map (fn (x) x) form))) ; dirty trick.
(append (lambda) (comma-expand-func fn-tail '()))))
((quote? (form 0))
(comma-expand-func
(1 form)
(cons (append '(quote)
(list (comma-expand-func (eval (form 0)) '())))
acc)))
((list? (form 0))
(comma-expand-func (1 form)
(cons (comma-expand-func (form 0) '())
acc)))
((= ', (form 0))
(if (not (symbol? (form 1))) (throw 'CAN-ONLY-EXPAND-SYMBOLS))
(let ((sym-name (name (form 1))))
(if (= "@" (sym-name 0)) ; this means splice is required.
(letn ((var (symbol (1 sym-name)))
(val (eval var)))
(if (not (list? val)) (throw 'CAN-ONLY-SPLICE-LISTS))
(comma-expand-func (2 form) (append (reverse val)
acc)))
(comma-expand-func (2 form) (cons (eval (form 1)) acc)))))
(true
(comma-expand-func (1 form) (cons (form 0) acc)))))
> (time (roman 2006) 1000)
470
(define (roman* n val rep vrlist acc)
(if (not val)
(roman* n ((*ROMAN* 0) 0) ((*ROMAN* 0) 1) (1 *ROMAN*) "")
(= n 0)
acc
(< n val)
(roman* n ((vrlist 0) 0) ((vrlist 0) 1) (1 vrlist) acc)
(roman* (- n val) val rep vrlist (string acc rep))))
> (time (roman* 2006) 1000)
266
(define (roman** n)
(let ((val ((*ROMAN* 0) 0))
(rep ((*ROMAN* 0) 1))
(vrlist (1 *ROMAN*))
(acc ""))
(until (= n 0)
(cond ((< n val)
(set 'val ((vrlist 0) 0) 'rep ((vrlist 0) 1))
(pop vrlist))
(true
(set 'acc (string acc rep) 'n (- n val)))))
acc))
> (time (roman** 2006) 1000)
94
;; translate s-expr to XML
;;
(define (expr2xml expr level)
(cond
((or (atom? expr) (quote? expr))
(print (dup " " level))
(println expr))
((list? (first expr))
(expr2xml (first expr) (+ level 1))
(dolist (s (rest expr)) (expr2xml s (+ level 1))))
((symbol? (first expr))
(print (dup " " level))
(println "<" (first expr) ">")
(dolist (s (rest expr)) (expr2xml s (+ level 1)))
(print (dup " " level))
(println "</" (first expr) ">"))
(true
(print (dup " " level)
(println "<error>" (string expr) "<error>")))
))
(context 'SXML)
(define (element? maybe-element)
(and (list? maybe-element)
(> (length maybe-element) 0)
(symbol? (maybe-element 0))))
(define (has-attrs? maybe-element)
(and (SXML:element? maybe-element)
(> (length maybe-element) 1)
(list? (maybe-element 1))
(= '@ (maybe-element 1 0))))
(define (get-attr-string maybe-element)
(if (SXML:has-attrs? maybe-element)
(let ((attr-alist (1 (maybe-element 1))))
(join (map (lambda (attr-pair)
(string (attr-pair 0) "="
""" (attr-pair 1) """))
attr-alist)
" "))
""))
(define (return-sans-attrs maybe-element)
(if (SXML:has-attrs? maybe-element)
(pop maybe-element 1))
maybe-element)
(define (childless? maybe-element)
(= 1 (length (SXML:return-sans-attrs maybe-element))))
(define (get-children element)
(if (SXML:has-attrs? element) (2 element) (1 element)))
(define (name-in-MAIN symbul)
(if (starts-with (string symbul) "MAIN:")
(name symbul)
(string symbul)))
;; The following function is modified from 'expr2xml' in:
;; http://newlisp.org/index.cgi?page=S-expressions_to_XML
(define (print-xml sxml level)
(let ((level (or level 0)))
(cond ((or (atom? sxml) (quote? sxml))
(print (dup " " level))
(println sxml))
((list? (first sxml))
(dolist (s sxml) (print-xml s (+ level 1))))
((symbol? (first sxml))
(let ((attr-string (SXML:get-attr-string sxml))
(tag-name (SXML:name-in-MAIN (sxml 0))))
(print (dup " " level))
(println "<" tag-name
(if (= attr-string "") "" " ")
attr-string
(if (SXML:childless? sxml) "/" "")
">")
(unless (SXML:childless? sxml)
(let ((kids (SXML:get-children sxml)))
(dolist (k kids) (print-xml k (+ level 1)))
(print (dup " " level))
(println "</" tag-name ">")))))
(true
(print (dup " " level))
(println "<error>" (string sxml) "<error>")))))
(context MAIN)
(SXML:print-xml sxml)
MAP_SHARED Share changes
MAP_PRIVATE Changes are private
MAP_FIXED Interpret addr exactly
MAP_AUTOGROW Implicitly grow object
MAP_LOCAL Do not share with share group
MAP_AUTORESRV Reserve logical swap on demand
MAP_SGI_ANYADDR Use reserved area for mappings