shithub: femtolisp

Download patch

ref: 923c7d5495a4251bea0e620ec6fcf17d0d0725d1
parent: c1610f0a9f1afa826cc2cbabb0e218fa6437a574
author: JeffBezanson <jeff.bezanson@gmail.com>
date: Fri Feb 27 20:59:01 EST 2009

fixing bug reading negative constants with #b,o,d,x
adding string.trim


--- a/femtolisp/read.c
+++ b/femtolisp/read.c
@@ -288,7 +288,9 @@
             if (((c == 'b' && (base= 2)) ||
                  (c == 'o' && (base= 8)) ||
                  (c == 'd' && (base=10)) ||
-                 (c == 'x' && (base=16))) && isdigit_base(buf[1],base)) {
+                 (c == 'x' && (base=16))) &&
+                (isdigit_base(buf[1],base) ||
+                 buf[1]=='-')) {
                 if (!read_numtok(&buf[1], &tokval, base))
                     lerror(ParseError, "read: invalid base %d constant", base);
                 return (toktype=TOK_NUM);
--- a/femtolisp/system.lsp
+++ b/femtolisp/system.lsp
@@ -515,11 +515,6 @@
                  () t)
     nt))
 
-(define *whitespace*
-  (string.encode #array(wchar 9 10 11 12 13 32 133 160 5760 6158 8192
-			      8193 8194 8195 8196 8197 8198 8199 8200
-			      8201 8202 8232 8233 8239 8287 12288)))
-
 (define (load filename)
   (let ((F (file filename :read)))
     (trycatch
@@ -529,7 +524,8 @@
                  prev
 		 (eval (expand E)))
 	   (begin (io.close F)
-		  (eval (expand E))))) ; evaluate last form in almost-tail position
+		  ; evaluate last form in almost-tail position
+		  (eval (expand E)))))
      (lambda (e)
        (begin
 	 (io.close F)
@@ -546,6 +542,27 @@
 
 " 1))
 
+(define *whitespace*
+  (string.encode #array(wchar 9 10 11 12 13 32 133 160 5760 6158 8192
+			      8193 8194 8195 8196 8197 8198 8199 8200
+			      8201 8202 8232 8233 8239 8287 12288)))
+
+(define (string.trim s at-start at-end)
+  (define (trim-start s chars i L)
+    (if (and (< i L)
+	     (string.find chars (string.char s i)))
+	(trim-start s chars (string.inc s i) L)
+	i))
+  (define (trim-end s chars i)
+    (if (and (> i 0)
+	     (string.find chars (string.char s (string.dec s i))))
+	(trim-end s chars (string.dec s i))
+	i))
+  (let ((L (length s)))
+    (string.sub s
+		(trim-start s at-start 0 L)
+		(trim-end   s at-end   L))))
+
 (define (repl)
   (define (prompt)
     (princ "> ") (io.flush *output-stream*)
@@ -595,7 +612,8 @@
 
 	((and (list? e)
 	      (= (length e) 2))
-	 (io.princ *stderr* (car e) ": " (cadr e)))
+	 (io.print *stderr* (car e))
+	 (io.princ *stderr* ": " (cadr e)))
 
 	(else (io.princ *stderr* "*** Unhandled exception: ")
 	      (io.print *stderr* e)))
--- a/femtolisp/todo
+++ b/femtolisp/todo
@@ -807,6 +807,19 @@
 lerror() should make a lisp string S from the result of sprintf, then
 raise `(,e ,S). first argument e should be a symbol.
 
+
+new expansion process:
+
+get rid of macroexpanding versions of define and define-macro
+macroexpand doesn't expand (define ...)
+  macroexpand implements let-syntax
+add lambda-expand which applies f-body to the bodies of lambdas, then
+  converts defines to set!
+call expand on every form before evaluating
+  (define (expand x) (lambda-expand (macroexpand x)))
+(define (eval x) (%eval (expand x)))
+reload system.lsp with the new eval
+
 -----------------------------------------------------------------------------
 
 String API
@@ -815,17 +828,17 @@
 *string.inc     - (string.inc s i [nchars])
 *string.dec
 *string.count   - # of chars between 2 byte offsets
- string.width   - # columns
 *string.char    - char at byte offset
 *string.sub     - substring between 2 byte offsets
 *string.split   - (string.split s sep-chars)
- string.trim    - (string.trim s chars-at-start chars-at-end)
+*string.trim    - (string.trim s chars-at-start chars-at-end)
 *string.reverse
 *string.find    - (string.find s str|char [offs]), or nil if not found
  string.rfind
- string.map     - (string.map f s)
 *string.encode  - to utf8
 *string.decode  - from utf8 to UCS
+ string.width   - # columns
+ string.map     - (string.map f s)
 
 
 IOStream API