adding with-bindings, with-output-to-file, with-output-to

simplifying printing. now based on standard function write,
  removing io.print and io.princ
using same top level exception handler for scripts as repl
This commit is contained in:
JeffBezanson 2009-08-08 00:29:55 +00:00
parent c6a977063e
commit 1a6d9d391f
5 changed files with 81 additions and 67 deletions

File diff suppressed because one or more lines are too long

View File

@ -1962,6 +1962,8 @@ static value_t fl_function(value_t *args, uint32_t nargs)
fn->name = args[3];
}
}
if (isgensym(fn->name))
lerror(ArgError, "function: name should not be a gensym");
}
return fv;
}

View File

@ -179,28 +179,17 @@ value_t fl_iopos(value_t *args, u_int32_t nargs)
return size_wrap((size_t)res);
}
static void do_ioprint(value_t *args, u_int32_t nargs, char *fname)
value_t fl_write(value_t *args, u_int32_t nargs)
{
if (nargs < 2)
argcount(fname, nargs, 2);
ios_t *s = toiostream(args[0], fname);
unsigned i;
for (i=1; i < nargs; i++) {
print(s, args[i]);
}
}
value_t fl_ioprint(value_t *args, u_int32_t nargs)
{
do_ioprint(args, nargs, "io.print");
return args[nargs-1];
}
value_t fl_ioprinc(value_t *args, u_int32_t nargs)
{
value_t oldpr = symbol_value(printreadablysym);
set(printreadablysym, FL_F);
do_ioprint(args, nargs, "io.princ");
set(printreadablysym, oldpr);
return args[nargs-1];
if (nargs < 1 || nargs > 2)
argcount("write", nargs, 1);
ios_t *s;
if (nargs == 2)
s = toiostream(args[1], "write");
else
s = toiostream(symbol_value(outstrsym), "write");
print(s, args[0]);
return args[0];
}
value_t fl_ioread(value_t *args, u_int32_t nargs)
@ -344,8 +333,7 @@ static builtinspec_t iostreamfunc_info[] = {
{ "file", fl_file },
{ "buffer", fl_buffer },
{ "read", fl_read },
{ "io.print", fl_ioprint },
{ "io.princ", fl_ioprinc },
{ "write", fl_write },
{ "io.flush", fl_ioflush },
{ "io.close", fl_ioclose },
{ "io.eof?" , fl_ioeof },

View File

@ -436,6 +436,16 @@
(for-each f (cdr l)))
#t))
(define-macro (with-bindings binds . body)
(let ((vars (map car binds))
(vals (map cadr binds))
(olds (map (lambda (x) (gensym)) binds)))
`(let ,(map list olds vars)
,@(map (lambda (v val) `(set! ,v ,val)) vars vals)
(unwind-protect
(begin ,@body)
(begin ,@(map (lambda (v old) `(set! ,v ,old)) vars olds))))))
; exceptions ------------------------------------------------------------------
(define (error . args) (raise (cons 'error args)))
@ -495,8 +505,10 @@
; text I/O --------------------------------------------------------------------
(define (print . args) (apply io.print *output-stream* args))
(define (princ . args) (apply io.princ *output-stream* args))
(define (print . args) (for-each write args))
(define (princ . args)
(with-bindings ((*print-readably* #f))
(for-each write args)))
(define (newline) (princ *linefeed*) #t)
(define (display x) (princ x) #t)
@ -515,6 +527,17 @@
(define (io.readlines s) (read-all-of io.readline s))
(define (read-all s) (read-all-of read s))
(define-macro (with-output-to stream . body)
`(with-bindings ((*output-stream* ,stream))
,@body))
(define (with-output-to-file name thunk)
(let ((f (file name :write :create :truncate)))
(unwind-protect
(with-bindings ((*output-stream* f))
(thunk))
(io.close f))))
; vector functions ------------------------------------------------------------
(define (list->vector l) (apply vector l))
@ -606,7 +629,7 @@
(define (print-to-string v)
(let ((b (buffer)))
(io.print b v)
(write v b)
(io.tostring! b)))
(define (string.join strlist sep)
@ -708,14 +731,18 @@
(define (reploop)
(when (trycatch (and (prompt) (newline))
(lambda (e)
(print-exception e)
(print-stack-trace (stacktrace))
(top-level-exception-handler e)
#t))
(begin (newline)
(reploop))))
(reploop)
(newline))
(define (top-level-exception-handler e)
(with-output-to *stderr*
(print-exception e)
(print-stack-trace (stacktrace))))
(define (print-stack-trace st)
(define (find-in-f f tgt path)
(let ((path (cons (function:name f) path)))
@ -750,48 +777,46 @@
st)))
(define (print-exception e)
(define (eprinc . args) (apply io.princ *error-stream* args))
(define (eprint . args) (apply io.print *error-stream* args))
(cond ((and (pair? e)
(eq? (car e) 'type-error)
(length= e 4))
(eprinc "type error: " (cadr e) ": expected " (caddr e) ", got ")
(eprint (cadddr e)))
(princ "type error: " (cadr e) ": expected " (caddr e) ", got ")
(print (cadddr e)))
((and (pair? e)
(eq? (car e) 'bounds-error)
(length= e 4))
(eprinc (cadr e) ": index " (cadddr e) " out of bounds for ")
(eprint (caddr e)))
(princ (cadr e) ": index " (cadddr e) " out of bounds for ")
(print (caddr e)))
((and (pair? e)
(eq? (car e) 'unbound-error)
(pair? (cdr e)))
(eprinc "eval: variable " (cadr e) " has no value"))
(princ "eval: variable " (cadr e) " has no value"))
((and (pair? e)
(eq? (car e) 'error))
(eprinc "error: ")
(apply eprinc (cdr e)))
(princ "error: ")
(apply princ (cdr e)))
((and (pair? e)
(eq? (car e) 'load-error))
(print-exception (caddr e))
(eprinc "in file " (cadr e)))
(princ "in file " (cadr e)))
((and (list? e)
(length= e 2))
(eprint (car e))
(eprinc ": ")
(print (car e))
(princ ": ")
(let ((msg (cadr e)))
((if (or (string? msg) (symbol? msg))
eprinc eprint)
princ print)
msg)))
(else (eprinc "*** Unhandled exception: ")
(eprint e)))
(else (princ "*** Unhandled exception: ")
(print e)))
(eprinc *linefeed*))
(princ *linefeed*))
(define (simple-sort l)
(if (or (null? l) (null? (cdr l))) l
@ -804,11 +829,11 @@
(define (make-system-image fname)
(let ((f (file fname :write :create :truncate))
(excludes '(*linefeed* *directory-separator* *argv* that
*print-pretty* *print-width* *print-readably*))
(pp *print-pretty*))
(set! *print-pretty* #f)
(unwind-protect
(let ((syms (filter (lambda (s)
*print-pretty* *print-width* *print-readably*)))
(with-bindings ((*print-pretty* #f)
(*print-readably* #t))
(let ((syms
(filter (lambda (s)
(and (bound? s)
(not (constant? s))
(or (not (builtin? (top-level-value s)))
@ -817,11 +842,9 @@
(not (memq s excludes))
(not (iostream? (top-level-value s)))))
(simple-sort (environment)))))
(io.print f (apply nconc (map list syms (map top-level-value syms))))
(write (apply nconc (map list syms (map top-level-value syms))) f)
(io.write f *linefeed*))
(begin
(io.close f)
(set! *print-pretty* pp)))))
(io.close f))))
; initialize globals that need to be set at load time
(define (__init_globals)
@ -838,7 +861,7 @@
(define (__script fname)
(trycatch (load fname)
(lambda (e) (begin (print-exception e)
(lambda (e) (begin (top-level-exception-handler e)
(exit 1)))))
(define (__start argv)

View File

@ -31,7 +31,7 @@
* fix printing nan and inf
* move to "2.5-bit" type tags
? builtin abs()
- try adding optional arguments, (lambda (x (opt 0)) ...), see if performance
* try adding optional arguments, (lambda (x (opt 0)) ...), see if performance
is acceptable
* (syntax-environment) to return it as an assoc list
* (environment) for variables, constantp
@ -110,7 +110,6 @@ possible optimizations:
* represent lambda environment as a vector (in lispv)
x setq builtin (didn't help)
* list builtin, to use cons_reserve
(- let builtin, to further avoid env consing)
unconventional interpreter builtins that can be used as a compilation
target without moving away from s-expressions:
- (*global* . a) ; special form, don't look in local env first
@ -139,6 +138,7 @@ for internal use:
. and/or add function array.alloc
x preallocate all byte,int8,uint8 values, and some wchars (up to 0x31B7?)
. this made no difference in a string.map microbenchmark
- use faster hash/compare in tables where the keys are eq-comparable
bugs:
* with the fully recursive (simpler) relocate(), the size of cons chains
@ -976,7 +976,7 @@ consolidated todo list as of 7/8:
- remaining cvalues functions
- finish ios
* optional arguments
- keyword arguments
* keyword arguments
- some kind of record, struct, or object system
- special efficient reader for #array
@ -1169,3 +1169,4 @@ what needs more test coverage:
- typeof, copy, podp, builtin()
- bitwise and logical ops
- making a closure in a default value expression for an optional arg
- gc during a catch block, then get stack trace