packages feed

haskeem 0.7.4 → 0.7.5

raw patch · 10 files changed

+370/−26 lines, 10 files

Files

Evaluator.hs view
@@ -19,7 +19,7 @@ along with haskeem; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: evaluator.hs,v 1.31 2009-06-27 21:51:29 uwe Exp $ -}+$Id: evaluator.hs,v 1.32 2009-06-29 03:59:13 uwe Exp $ -}  module Evaluator (evalLisp) where import Prelude@@ -710,6 +710,9 @@ -- (trace 'function #t), but tracing sub-functions needs a special -- form, because it needs access to the current environment rather than -- the top-level environment.+-- We require the literal form '(trace name #t/f), rather than some+-- expression which evaluates to the symbol to trace, because we want+-- to have a name: var is what gets used. Consider relaxing this?  evalLisp env ql (List [Symbol "trace", Symbol var, sw]) =   if isSpecialForm (Symbol var)@@ -756,13 +759,16 @@         getPort _ = progError  -- The generic (function : args) stuff; also macro expansion stuff+-- For macro expansion, we evaluate once to get syntax back from the+-- macro, that's the "evalLisp env ql function", but then we change+-- the environment to evaluate that syntax in the caller's environment.  evalLisp env ql (List (function : args)) =   if isSpecialForm function      then throwError (BadSpecial "bad syntax for special form" function)      else do func <- evalLisp env ql function              if isM func-                then apply ql func args >>=+                then apply ql (chEnv func env) args >>=                      prtTrace (isT func) >>=                      evalLisp env ql                 else mapM (evalLisp env ql) args >>= apply ql func@@ -770,6 +776,8 @@         isM _ = False         isT (Func _ _ _ _ (Just _) _) = True         isT _ = False+        chEnv (Func pars vars bod envo name mac) envn =+          Func pars vars bod envn name mac         prtTrace trace vals =           if trace              then remark ("   ->  " ++ (show vals)) >> return vals
LispData.hs view
@@ -19,7 +19,7 @@ along with haskeem; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: lispdata.hs,v 1.14 2009-06-27 21:51:29 uwe Exp $ -}+$Id: lispdata.hs,v 1.15 2009-06-29 00:23:01 uwe Exp $ -}  module LispData     (LispVal(Symbol, Boolean, Char, Delay, DottedList, IntNumber,@@ -126,7 +126,7 @@               (case varargs of                     Nothing -> ""                     Just arg -> " . " ++ arg) ++ ") " ++-              (unwords (map showVal bd)) ++ lclose+              "..." ++ lclose   in case nm of           Nothing -> inner           Just val -> "(" ++ val ++ " . " ++ inner ++ ")"
+ cpm.scm view
@@ -0,0 +1,113 @@+; Copyright 2009 Uwe Hollerbach <uh@alumni.caltech.edu>+; $Id: cpm.scm,v 1.1 2009-06-29 03:59:41 uwe Exp $+; BSD3++; Continuation-passing macros in the style of "On Lisp" by Paul Graham;+; but the syntax is scheme (well, scheme - call/cc) and any mistakes or+; misunderstandings are mine, mine, all mine!++; Define the continuation variable which gets passed around (and overridden),+; initially just set to the identity, the default top-level continuation.++(define *cont* (lambda (val) val))++; Define the CPS analog of (lambda): the same as (lambda), just with the+; extra continuation argument glued into place.++(defmacro (=lambda params . body)+  (if (symbol? params)+      `(lambda (*cont* . ,params) ,@body)+      `(lambda (*cont* ,@params) ,@body)))++; Define the CPS analog of (apply): the same as apply, just add in the extra+; continuation argument++(defmacro (=apply fn . args)+  `(apply ,fn *cont* ,@args))++; Define the "return a value" macro: instead of actually returning, this+; applies the current continuation to the specified value. I'm not bothering+; with multiple-value return right now, since haskeem only does one value+; at a time.++(defmacro (=return val)+  `(*cont* ,val))++; Define the CPS analog of (define): define a macro that looks like+; the function without the continuation argument, and define the+; function using a generated symbol with the continuation argument.++; This only does the (define (foo args) body) version so far, check+; for (symbol? formals) to capture the (define foo <stuff>) version;+; or just disallow that usage: it's captured above by the =lambda+; stuff.++; NOTE: if it's desirable to (trace) the function, it has to be done+; here inside the (=define) macro, inside each (begin) after the+; (define (,ifn ...) ...). Otherwise, it's tricky to get at it.++(defmacro (=define formals . body)+  (let ((ifn (new-symbol))+	(fn (car formals))+	(args (cdr formals)))+    (if (symbol? args)+	`(begin (defmacro ,formals (,ifn *cont* . ,args))+		(define (,ifn *cont* . ,args) ,@body))+	`(begin (defmacro ,formals (,ifn *cont* ,@args))+		(define (,ifn *cont* ,@args) ,@body)))))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+; Test stuff++; Expect to see this print "5"++(define foo (=lambda (x) (=return (+ 1 x))))+(display (foo *cont* 4))+(newline)++; This should print "10"++(let ((*cont* (lambda (x) (* 2 x))))+  (display (foo *cont* 4))+  (newline))++; This should print "14": the function says to add 10 to the value passed+; in, and the current continuation, which is the default identity, is then+; applied to that value: 4 + 10 -> identity -> 14++(=define (bar x) (=return (+ 10 x)))+(display (bar 4))+(newline)++; Expect to see this print... "15"? the function again adds 10 to what's+; passed in, but here the current continuation has been re-jiggered to+; add 1 to what it receives: 4 + 10 -> 14 -> (+1) -> 15.+; In++(let ((*cont* (lambda (x) (+ 1 x))))+  (display (bar 4))+  (newline))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+; explicit CPS conversion of fibonacci function:++(define (fib-no n)+  (if (< n 2)+      1+      (+ (fib-no (- n 1))+	 (fib-no (- n 2)))))++; becomes++(define (fib-cps k n)+  (if (< n 2)+      (k 1)+      (fib-cps (lambda (fib-of-n-1)+		 (fib-cps (lambda (fib-of-n-2)+			    (k (+ fib-of-n-1 fib-of-n-2)))+			  (- n 2)))+	       (- n 1))))++; and a wrapper which just passes in the identity function as the continuation++(define (fib-yes n) (fib-cps (lambda (x) x) n))
haskeem.cabal view
@@ -1,5 +1,6 @@ Name:             haskeem-Version:          0.7.4+Version:          0.7.5+Homepage:         http://www.korgwal.com/haskeem/ Author:           Uwe Hollerbach <uh@alumni.caltech.edu> Maintainer:       Uwe Hollerbach <uh@alumni.caltech.edu> Synopsis:         A small scheme interpreter
haskeem.doc view
@@ -15,7 +15,7 @@ ; along with haskeem; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -; $Id: haskeem.doc,v 1.35 2009-06-20 03:09:42 uwe Exp $+; $Id: haskeem.doc,v 1.36 2009-06-29 00:25:51 uwe Exp $  ; Input to documentation generator for haskeem. The intent is that this ; does NOT have to be globally ordered, it is possible to just add new@@ -384,3 +384,59 @@  ((data args)) ((function cycle) (args list) (return stream))++((function heap-new) (args pred? size) (return vector))+((function heap-insert) (args vector obj) (return vector))+((function heap-remove) (args vector) (return obj vector))+((macro heap-insert!) (args vector obj) (return vector))+((macro heap-remove!) (args vector) (return obj vector))++((function set-new) (args) (return set))+((function intset-new) (args) (return intset))+((function bitset-new) (args) (return bitset))++((function set-member?) (args set element) (return bool))+((function intset-member?) (args intset element) (return bool))+((function bitset-member?) (args bitset element) (return bool))++((function set-empty?) (args set) (return bool))+((function intset-empty?) (args intset) (return bool))+((function bitset-empty?) (args bitset) (return bool))++((function set-add) (args set element) (return set))+((function intset-add) (args intset element) (return intset))+((function bitset-add) (args bitset element) (return bitset))++((function set-remove) (args set element) (return set))+((function intset-remove) (args intset element) (return intset))+((function bitset-remove) (args bitset element) (return bitset))++((function set-remove-dups) (args set) (return set))+((function intset-remove-dups) (args intset) (return intset))+((function bitset-remove-dups) (args bitset) (return bitset))++((function set-or) (args set set) (return set))+((function intset-or) (args intset intset) (return intset))+((function bitset-or) (args bitset bitset) (return bitset))++((function set-andnot) (args set set) (return set))+((function intset-andnot) (args intset intset) (return intset))+((function bitset-andnot) (args bitset bitset) (return bitset))++((function set-xor) (args set set) (return set))+((function intset-xor) (args intset intset) (return intset))+((function bitset-xor) (args bitset bitset) (return bitset))++((function set-and) (args set set) (return set))+((function intset-and) (args intset intset) (return intset))+((function bitset-and) (args bitset bitset) (return bitset))++((function set-equal?) (args set set) (return bool))+((function intset-equal?) (args intset intset) (return bool))+((function bitset-equal?) (args bitset bitset) (return bool))++((function bitset->list) (args bitset) (return list))++((function set-for-each) (args set fn))+((function intset-for-each) (args intset fn))+((function bitset-for-each) (args bitset fn))
haskeem.hs view
@@ -19,7 +19,7 @@ along with haskeem; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -$Id: haskeem.hs,v 1.33 2009-06-27 20:31:51 uwe Exp $ -}+$Id: haskeem.hs,v 1.34 2009-06-29 04:21:36 uwe Exp $ -}  module Main where import Prelude@@ -43,7 +43,7 @@ -- haskeem version  version :: String-version = "0.7.4"+version = "0.7.5"  -- a variable under which any command-line arguments to a script are -- made available; empty for interactive mode
haskeem_readline.hs view
@@ -43,7 +43,7 @@ -- haskeem version  version :: String-version = "0.7.0"+version = "0.7.5"  -- a variable under which any command-line arguments to a script are -- made available; empty for interactive mode
+ heap.scm view
@@ -0,0 +1,166 @@+; Copyright 2009 Uwe Hollerbach <uh@alumni.caltech.edu>+; $Id: heap.scm,v 1.2 2009-06-29 00:24:24 uwe Exp $+; BSD3++; Priority queues implemented as heaps++; What's a heap? It's a vector containing another vector:+;+;	#(pred? cur-size #(array))+;+; where pred? is a predicate used to maintain the heap structure, cur-size+; is the number of items currently in the heap, and array is the actual+; heap.++; Create a new heap which will use the given predicate for comparisons, and+; set it to initially have the given size. Vectors can be resized, so it's+; not a big deal to get the size wrong.++(define (heap-new pred? size)+  (let ((h (make-vector 3))+	(s (max size 1)))+    (vector-set! h 0 pred?)+    (vector-set! h 1 0)+    (vector-set! h 2 (make-vector s))))++; Insert an item into a heap, maintaining the heap condition;+; Return the modified heap++(define (heap-insert heap item)+  (let* ((pred? (vector-ref heap 0))+	 (k (vector-ref heap 1))+	 (a (vector-ref heap 2))+	 (n (vector-length a))+	 (kp #f)+	 (parent (lambda (j) (quotient (- j 1) 2))))+; make sure there's space for insertion+    (when (= k n)+	  (set! n (* n 2))+	  (vector-resize! a n))+; insert item at end of heap+    (vector-set! a k item)+    (vector-set! heap 1 (+ k 1))+; restore heap condition+    (do ((kp (parent k) (parent k)))+	((or (zero? k) (pred? (vector-ref a kp) item)) #t)+      (vector-set! a k (vector-ref a kp))+      (set! k kp))+    (vector-set! a k item)+; save modified array, which also returns heap to caller+    (vector-set! heap 2 a)))++; Remove the highest-priority item from the heap, maintaining the heap+; condition; return a list of the highest-priority item and the new heap++(define (heap-remove heap)+  (let* ((pred? (vector-ref heap 0))+	 (k (vector-ref heap 1))+	 (a (vector-ref heap 2))+	 (kp 0)+	 (ret (if (zero? k) (raise "heap exhausted!") (vector-ref a kp)))+	 (kc #f)+	 (v #f)+	 (child (lambda (j) (+ 1 (* 2 j)))))+    (set! k (- k 1))+    (vector-set! heap 1 k)+    (set! v (vector-ref a k))+    (vector-set! a kp v)+    (set! k (- k 1))+    (set! kc (child kp))+    (when (and (< kc k) (pred? (vector-ref a (+ kc 1))+			       (vector-ref a kc)))+	  (set! kc (+ kc 1)))+    (while (and (<= (child kp) k) (pred? (vector-ref a kc) v))+	   (vector-set! a kp (vector-ref a kc))+	   (set! kp kc)+	   (set! kc (child kp))+	   (when (and (< kc k) (pred? (vector-ref a (+ kc 1))+				      (vector-ref a kc)))+		 (set! kc (+ kc 1))))+    (vector-set! a kp v)+    (vector-set! heap 2 a)+    (list ret heap)))++; Insert an item into a heap, updating the heap in place++(defmacro (heap-insert! heap item)+  `(set! ,heap (heap-insert ,heap ,item)))++; Remove the highest-priority item from the heap, updating the heap+; in place, and return the highest-priority item++(defmacro (heap-remove! heap)+  (let ((l (new-symbol)))+    `(let ((,l (heap-remove ,heap)))+       (set! ,heap (cadr ,l))+       (car ,l))))++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+; debugging stuff++(define (display-heap heap label)+  (letrec* ((k (vector-ref heap 1))+	    (a (vector-ref heap 2))+	    (i 0)+	    (target 1)+	    (nrows (ilog 2 k))+	    (sp-count (lambda (x)+			(if (zero? x) 1 (+ 2 (* 2 (sp-count (- x 1)))))))+	    (nsp (sp-count nrows)))+    (write-string label #\newline)+    (do ((i 0 (+ i 1)))+	((>= i k) #t)+      (display (vector-ref a i))+      (if (= (+ i 1) target)+	  (begin (newline)+		 (set! target (+ 1 (* 2 target)))+		 (set! nsp (/ (- nsp 2) 2)))+	  (apply write-string (replicate #\space nsp))))+    (newline)))++; Check that the specified heap condition is met at the given index:+; compare value against its parent, which must satisfy (pred? parent child).+; Due to possibility of equality, check for existence of failure condition+; (pred? child parent) instead of success condition (pred? parent child).++(define (heap-check-one heap cur)+  (let ((pred? (vector-ref heap 0))+	(k (vector-ref heap 1))+	(a (vector-ref heap 2))+	(parent (lambda (j) (quotient (- j 1) 2))))+    (cond ((or (negative? cur) (>= cur k))+	   (raise "requested index is out of bounds!"))+	  ((zero? cur) (write-string "heap root\n"))+	  (else (let* ((cp (parent cur))+		       (vc (vector-ref a cur))+		       (vp (vector-ref a cp)))+		  (when (pred? vc vp)+			(write-string "heap condition not satisfied between ")+			(display vp)+			(write-string " at " (number->string cp) " and ")+			(display vc)+			(write-string " at " (number->string cur)+				      #\newline)))))))++; Check that the heap condition is met at all indices++(define (heap-check-all heap)+  (let ((k (vector-ref heap 1))+	(i 1))+    (do ((i 1 (+ i 1)))+	((>= i k) #t)+      (heap-check-one heap i))))++(define (test pred . vals)+  (let ((hp (heap-new pred 10))+	(i #f))+    (until (null? vals)+	   (heap-insert! hp (car vals))+	   (set! vals (cdr vals)))+    (heap-check-all hp)+    (while (positive? (vector-ref hp 1))+	   (set! i (heap-remove! hp))+	   (heap-check-all hp)+	   (write-string "removed ")+	   (display i)+	   (newline))))
regexp.scm view
@@ -1,5 +1,5 @@ ; Copyright 2009 Uwe Hollerbach <uh@alumni.caltech.edu>-; $Id: regexp.scm,v 1.12 2009-06-26 05:22:27 uwe Exp $+; $Id: regexp.scm,v 1.13 2009-06-29 00:25:19 uwe Exp $ ; BSD3... but if you use this for anything serious, you gotta be kidding  ; grammar for regular expressions: precedence is (highest to lowest)@@ -321,7 +321,7 @@ 		      ((>= i n) #t) 		    (set! cur (vector-ref vec i)) 		    (set! new cur)-		    (bitset-foreach+		    (bitset-for-each 		     cur (lambda (j) 			   (set! new (bitset-or new (vector-ref vec j))))) 		    (unless (bitset-equal? new cur)@@ -347,7 +347,7 @@ 	     (lambda (s) 	       (set! eps-union 		     (bitset-or eps-union (find-eps-closure s nfa))))))-    (bitset-foreach set merge-eps-closure)+    (bitset-for-each set merge-eps-closure)     eps-union))  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@@ -417,12 +417,12 @@  ; (bitset-foldl (bitset-or . (find-transitions s nfa)) (bitset-new) eps-union) -    (bitset-foreach eps-union-		    (lambda (s)-		      (set! new-sts-			    (bitset-or new-sts-				       (foldl p-trans (bitset-new)-					      (find-transitions s nfa))))))+    (bitset-for-each eps-union+		     (lambda (s)+		       (set! new-sts+			     (bitset-or new-sts+					(foldl p-trans (bitset-new)+					       (find-transitions s nfa))))))     new-sts))  ; Make a series of transitions@@ -525,10 +525,10 @@       (let ((start #\<)) 	(if (bitset-empty? cur) 	    (write-string start)-	    (bitset-foreach cur (lambda (j)-				  (write-string start)-				  (set! start #\space)-				  (write-string (number->string j)))))+	    (bitset-for-each cur (lambda (j)+				   (write-string start)+				   (set! start #\space)+				   (write-string (number->string j))))) 	(write-string ">"))       (display cur))) 
set.scm view
@@ -1,5 +1,5 @@ ; Copyright 2009 Uwe Hollerbach <uh@alumni.caltech.edu>-; $Id: set.scm,v 1.8 2009-06-26 05:22:27 uwe Exp $+; $Id: set.scm,v 1.9 2009-06-29 00:25:19 uwe Exp $ ; BSD3  ; This could all go into stdlib?@@ -182,11 +182,11 @@  ; Apply a function to each member of a set -(define (set-foreach set fn)+(define (set-for-each set fn)   (map fn set)) -(define (intset-foreach set fn)+(define (intset-for-each set fn)   (map fn set)) -(define (bitset-foreach set fn)+(define (bitset-for-each set fn)   (map fn (bitset->list set)))