diff --git a/femtolisp/read.c b/femtolisp/read.c index 3ef5dbe..9507dc9 100644 --- a/femtolisp/read.c +++ b/femtolisp/read.c @@ -288,7 +288,9 @@ static u_int32_t peek() 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); diff --git a/femtolisp/system.lsp b/femtolisp/system.lsp index 6f90d03..0aeab28 100644 --- 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))) diff --git a/femtolisp/todo b/femtolisp/todo index f8bc363..7979b82 100644 --- a/femtolisp/todo +++ b/femtolisp/todo @@ -807,6 +807,19 @@ such exceptions can be printed recursively 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 API *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