adding read and print support for named characters, e.g. #\space
printing infs and nans in R6RS format making closure print syntax more compact; fn instead of function adding more c[ad]+r functions
This commit is contained in:
		
							parent
							
								
									1a6d9d391f
								
							
						
					
					
						commit
						302ddec770
					
				|  | @ -7,6 +7,11 @@ | |||
| (define vector-set! aset!) | ||||
| (define vector-length length) | ||||
| (define make-vector vector.alloc) | ||||
| (define (vector-fill! v f) | ||||
|   (for 0 (- (length v) 1) | ||||
|        (lambda (i) (aset! v i f))) | ||||
|   #t) | ||||
| (define (vector-map f v) (vector.map f v)) | ||||
| 
 | ||||
| (define array-ref! aref) | ||||
| (define (array-set! a obj i0 . idxs) | ||||
|  | @ -23,18 +28,25 @@ | |||
| (define (exact? x) (integer? x)) | ||||
| (define (inexact? x) (not (exact? x))) | ||||
| (define quotient div0) | ||||
| (define (inexact x) x) | ||||
| (define (exact x) | ||||
|   (if (exact? x) x | ||||
|       (error "exact real numbers not supported"))) | ||||
| (define (finite? x) (and (< x +inf.0) (> x -inf.0))) | ||||
| (define (infinite? x) (or (equal? x +inf.0) (equal? x -inf.0))) | ||||
| (define (nan? x) (or (equal? x +nan.0) (equal? x -nan.0))) | ||||
| 
 | ||||
| (define (char->integer c) (fixnum c)) | ||||
| (define (integer->char i) (wchar i)) | ||||
| (define char-upcase char.upcase) | ||||
| (define char-downcase char.downcase) | ||||
| (define char=? =) | ||||
| (define char=? eqv?) | ||||
| (define char<? <) | ||||
| (define char>? >) | ||||
| (define char<=? <=) | ||||
| (define char>=? >=) | ||||
| 
 | ||||
| (define string=? =) | ||||
| (define string=? eqv?) | ||||
| (define string<? <) | ||||
| (define string>? >) | ||||
| (define string<=? <=) | ||||
|  | @ -44,6 +56,14 @@ | |||
| (define string-length string.count) | ||||
| (define string->symbol symbol) | ||||
| (define (symbol->string s) (string s)) | ||||
| (define symbol=? eq?) | ||||
| (define (make-string k (fill #\space)) | ||||
|   (string.rep fill k)) | ||||
| 
 | ||||
| (define (string-ref s i) | ||||
|   (string.char s (string.inc s 0 i))) | ||||
| 
 | ||||
| (define (input-port? x) (iostream? x)) | ||||
| (define (output-port? x) (iostream? x)) | ||||
| 
 | ||||
| (define (eval-core x) (eval x)) | ||||
|  |  | |||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -89,14 +89,21 @@ static uint32_t curr_frame = 0; | |||
| static value_t *GCHandleStack[N_GC_HANDLES]; | ||||
| static uint32_t N_GCHND = 0; | ||||
| 
 | ||||
| value_t NIL, FL_T, FL_F, LAMBDA, QUOTE, IF, TRYCATCH; | ||||
| value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION; | ||||
| value_t NIL, FL_T, FL_F; | ||||
| value_t IOError, ParseError, TypeError, ArgError, UnboundError, MemoryError; | ||||
| value_t DivideError, BoundsError, Error, KeyError, EnumerationError; | ||||
| value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym; | ||||
| value_t definesym, defmacrosym, forsym, labelsym, printprettysym, setqsym; | ||||
| value_t printwidthsym, printreadablysym; | ||||
| value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym; | ||||
| value_t printwidthsym, printreadablysym, printprettysym; | ||||
| 
 | ||||
| value_t QUOTE; | ||||
| static value_t LAMBDA, IF, TRYCATCH; | ||||
| static value_t BACKQUOTE, COMMA, COMMAAT, COMMADOT, FUNCTION; | ||||
| 
 | ||||
| static value_t pairsym, symbolsym, fixnumsym, vectorsym, builtinsym, vu8sym; | ||||
| static value_t definesym, defmacrosym, forsym, labelsym, setqsym; | ||||
| static value_t tsym, Tsym, fsym, Fsym, booleansym, nullsym, evalsym, fnsym; | ||||
| // for reading characters
 | ||||
| static value_t nulsym, alarmsym, backspacesym, tabsym, linefeedsym, newlinesym; | ||||
| static value_t vtabsym, pagesym, returnsym, escsym, spacesym, deletesym; | ||||
| 
 | ||||
| static value_t apply_cl(uint32_t nargs); | ||||
| static value_t *alloc_words(int n); | ||||
|  | @ -2089,39 +2096,31 @@ static void lisp_init(void) | |||
|     NIL = builtin(OP_THE_EMPTY_LIST); | ||||
|     FL_T = builtin(OP_BOOL_CONST_T); | ||||
|     FL_F = builtin(OP_BOOL_CONST_F); | ||||
|     LAMBDA = symbol("lambda"); | ||||
|     FUNCTION = symbol("function"); | ||||
|     QUOTE = symbol("quote"); | ||||
|     TRYCATCH = symbol("trycatch"); | ||||
|     BACKQUOTE = symbol("backquote"); | ||||
|     COMMA = symbol("*comma*"); | ||||
|     COMMAAT = symbol("*comma-at*"); | ||||
|     COMMADOT = symbol("*comma-dot*"); | ||||
|     IOError = symbol("io-error"); | ||||
|     ParseError = symbol("parse-error"); | ||||
|     TypeError = symbol("type-error"); | ||||
|     ArgError = symbol("arg-error"); | ||||
|     LAMBDA = symbol("lambda");        FUNCTION = symbol("function"); | ||||
|     QUOTE = symbol("quote");          TRYCATCH = symbol("trycatch"); | ||||
|     BACKQUOTE = symbol("backquote");  COMMA = symbol("*comma*"); | ||||
|     COMMAAT = symbol("*comma-at*");   COMMADOT = symbol("*comma-dot*"); | ||||
|     IOError = symbol("io-error");     ParseError = symbol("parse-error"); | ||||
|     TypeError = symbol("type-error"); ArgError = symbol("arg-error"); | ||||
|     UnboundError = symbol("unbound-error"); | ||||
|     KeyError = symbol("key-error"); | ||||
|     MemoryError = symbol("memory-error"); | ||||
|     KeyError = symbol("key-error");   MemoryError = symbol("memory-error"); | ||||
|     BoundsError = symbol("bounds-error"); | ||||
|     DivideError = symbol("divide-error"); | ||||
|     EnumerationError = symbol("enumeration-error"); | ||||
|     Error = symbol("error"); | ||||
|     pairsym = symbol("pair"); | ||||
|     symbolsym = symbol("symbol"); | ||||
|     fixnumsym = symbol("fixnum"); | ||||
|     vectorsym = symbol("vector"); | ||||
|     builtinsym = symbol("builtin"); | ||||
|     booleansym = symbol("boolean"); | ||||
|     nullsym = symbol("null"); | ||||
|     definesym = symbol("define"); | ||||
|     defmacrosym = symbol("define-macro"); | ||||
|     forsym = symbol("for"); | ||||
|     labelsym = symbol("label"); | ||||
|     setqsym = symbol("set!"); | ||||
|     evalsym = symbol("eval"); | ||||
|     vu8sym = symbol("vu8"); | ||||
|     Error = symbol("error");          pairsym = symbol("pair"); | ||||
|     symbolsym = symbol("symbol");     fixnumsym = symbol("fixnum"); | ||||
|     vectorsym = symbol("vector");     builtinsym = symbol("builtin"); | ||||
|     booleansym = symbol("boolean");   nullsym = symbol("null"); | ||||
|     definesym = symbol("define");     defmacrosym = symbol("define-macro"); | ||||
|     forsym = symbol("for");           labelsym = symbol("label"); | ||||
|     setqsym = symbol("set!");         evalsym = symbol("eval"); | ||||
|     vu8sym = symbol("vu8");           fnsym = symbol("fn"); | ||||
|     nulsym = symbol("nul");           alarmsym = symbol("alarm"); | ||||
|     backspacesym = symbol("backspace"); tabsym = symbol("tab"); | ||||
|     linefeedsym = symbol("linefeed"); vtabsym = symbol("vtab"); | ||||
|     pagesym = symbol("page");         returnsym = symbol("return"); | ||||
|     escsym = symbol("esc");           spacesym = symbol("space"); | ||||
|     deletesym = symbol("delete");     newlinesym = symbol("newline"); | ||||
|     tsym = symbol("t"); Tsym = symbol("T"); | ||||
|     fsym = symbol("f"); Fsym = symbol("F"); | ||||
|     set(printprettysym=symbol("*print-pretty*"), FL_T); | ||||
|  |  | |||
|  | @ -253,12 +253,13 @@ typedef float float_t; | |||
| 
 | ||||
| typedef value_t (*builtin_t)(value_t*, uint32_t); | ||||
| 
 | ||||
| extern value_t QUOTE; | ||||
| extern value_t int8sym, uint8sym, int16sym, uint16sym, int32sym, uint32sym; | ||||
| extern value_t int64sym, uint64sym; | ||||
| extern value_t longsym, ulongsym, bytesym, wcharsym; | ||||
| extern value_t structsym, arraysym, enumsym, cfunctionsym, voidsym, pointersym; | ||||
| extern value_t stringtypesym, wcstringtypesym, emptystringsym; | ||||
| extern value_t unionsym, floatsym, doublesym, builtinsym; | ||||
| extern value_t unionsym, floatsym, doublesym; | ||||
| extern fltype_t *bytetype, *wchartype; | ||||
| extern fltype_t *stringtype, *wcstringtype; | ||||
| extern fltype_t *builtintype; | ||||
|  |  | |||
|  | @ -399,7 +399,7 @@ void fl_print_child(ios_t *f, value_t v) | |||
|             if (!print_princ) { | ||||
|                 if (print_circle_prefix(f, v)) return; | ||||
|                 function_t *fn = (function_t*)ptr(v); | ||||
|                 outs("#function(", f); | ||||
|                 outs("#fn(", f); | ||||
|                 char *data = cvalue_data(fn->bcode); | ||||
|                 size_t i, sz = cvalue_len(fn->bcode); | ||||
|                 for(i=0; i < sz; i++) data[i] += 48; | ||||
|  | @ -515,15 +515,28 @@ static void cvalue_printdata(ios_t *f, void *data, size_t len, value_t type, | |||
|     else if (type == wcharsym) { | ||||
|         uint32_t wc = *(uint32_t*)data; | ||||
|         char seq[8]; | ||||
|         if (print_princ || iswprint(wc)) { | ||||
|         size_t nb = u8_toutf8(seq, sizeof(seq), &wc, 1); | ||||
|         seq[nb] = '\0'; | ||||
|         if (print_princ) { | ||||
|             // TODO: better multibyte handling
 | ||||
|             if (!print_princ) outsn("#\\", f, 2); | ||||
|             outs(seq, f); | ||||
|         } | ||||
|         else { | ||||
|             HPOS+=ios_printf(f, "#\\x%04x", (int)wc); | ||||
|             outsn("#\\", f, 2); | ||||
|             if      (wc == 0x00) outsn("nul", f, 3); | ||||
|             else if (wc == 0x07) outsn("alarm", f, 5); | ||||
|             else if (wc == 0x08) outsn("backspace", f, 9); | ||||
|             else if (wc == 0x09) outsn("tab", f, 3); | ||||
|             else if (wc == 0x0A) outsn("linefeed", f, 8); | ||||
|             //else if (wc == 0x0A) outsn("newline", f, 7);
 | ||||
|             else if (wc == 0x0B) outsn("vtab", f, 4); | ||||
|             else if (wc == 0x0C) outsn("page", f, 4); | ||||
|             else if (wc == 0x0D) outsn("return", f, 6); | ||||
|             else if (wc == 0x1B) outsn("esc", f, 3); | ||||
|             else if (wc == 0x20) outsn("space", f, 5); | ||||
|             else if (wc == 0x7F) outsn("delete", f, 6); | ||||
|             else if (iswprint(wc)) outs(seq, f); | ||||
|             else HPOS+=ios_printf(f, "x%04x", (int)wc); | ||||
|         } | ||||
|     } | ||||
|     else if (type == int64sym | ||||
|  | @ -569,9 +582,9 @@ static void cvalue_printdata(ios_t *f, void *data, size_t len, value_t type, | |||
|         if (!DFINITE(d)) { | ||||
|             char *rep; | ||||
|             if (isnan(d)) | ||||
|                 rep = sign_bit(d) ? "-NaN" : "+NaN"; | ||||
|                 rep = sign_bit(d) ? "-nan.0" : "+nan.0"; | ||||
|             else | ||||
|                 rep = sign_bit(d) ? "-Inf" : "+Inf"; | ||||
|                 rep = sign_bit(d) ? "-inf.0" : "+inf.0"; | ||||
|             if (type == floatsym && !print_princ && !weak) | ||||
|                 HPOS+=ios_printf(f, "#%s(%s)", symbol_name(type), rep); | ||||
|             else | ||||
|  |  | |||
|  | @ -216,6 +216,25 @@ static u_int32_t peek() | |||
|                     cval = numval(tokval); | ||||
|                 } | ||||
|             } | ||||
|             else if (cval >= 'a' && cval <= 'z') { | ||||
|                 read_token((char)cval, 0); | ||||
|                 tokval = symbol(buf); | ||||
|                 if (buf[1] == '\0')       /* one character */; | ||||
|                 else if (tokval == nulsym)        cval = 0x00; | ||||
|                 else if (tokval == alarmsym)      cval = 0x07; | ||||
|                 else if (tokval == backspacesym)  cval = 0x08; | ||||
|                 else if (tokval == tabsym)        cval = 0x09; | ||||
|                 else if (tokval == linefeedsym)   cval = 0x0A; | ||||
|                 else if (tokval == newlinesym)    cval = 0x0A; | ||||
|                 else if (tokval == vtabsym)       cval = 0x0B; | ||||
|                 else if (tokval == pagesym)       cval = 0x0C; | ||||
|                 else if (tokval == returnsym)     cval = 0x0D; | ||||
|                 else if (tokval == escsym)        cval = 0x1B; | ||||
|                 else if (tokval == spacesym)      cval = 0x20; | ||||
|                 else if (tokval == deletesym)     cval = 0x7F; | ||||
|                 else | ||||
|                     lerrorf(ParseError, "read: unknown character #\\%s", buf); | ||||
|             } | ||||
|             toktype = TOK_NUM; | ||||
|             tokval = mk_wchar(cval); | ||||
|         } | ||||
|  | @ -580,6 +599,9 @@ static value_t do_read_sexpr(value_t label) | |||
|             sym = arraysym; | ||||
|             Stack[SP-1] = fl_cons(uint8sym, Stack[SP-1]); | ||||
|         } | ||||
|         else if (sym == fnsym) { | ||||
|             sym = FUNCTION; | ||||
|         } | ||||
|         v = symbol_value(sym); | ||||
|         if (v == UNBOUND) | ||||
|             raise(list2(UnboundError, sym)); | ||||
|  |  | |||
|  | @ -147,7 +147,22 @@ | |||
| (define (cdadr x) (cdr (car (cdr x)))) | ||||
| (define (cddar x) (cdr (cdr (car x)))) | ||||
| (define (cdddr x) (cdr (cdr (cdr x)))) | ||||
| (define (caaaar x) (car (car (car (car x))))) | ||||
| (define (caaadr x) (car (car (car (cdr x))))) | ||||
| (define (caadar x) (car (car (cdr (car x))))) | ||||
| (define (caaddr x) (car (car (cdr (cdr x))))) | ||||
| (define (cadaar x) (car (cdr (car (car x))))) | ||||
| (define (cadadr x) (car (cdr (car (cdr x))))) | ||||
| (define (caddar x) (car (cdr (cdr (car x))))) | ||||
| (define (cadddr x) (car (cdr (cdr (cdr x))))) | ||||
| (define (cdaaar x) (cdr (car (car (car x))))) | ||||
| (define (cdaadr x) (cdr (car (car (cdr x))))) | ||||
| (define (cdadar x) (cdr (car (cdr (car x))))) | ||||
| (define (cdaddr x) (cdr (car (cdr (cdr x))))) | ||||
| (define (cddaar x) (cdr (cdr (car (car x))))) | ||||
| (define (cddadr x) (cdr (cdr (car (cdr x))))) | ||||
| (define (cdddar x) (cdr (cdr (cdr (car x))))) | ||||
| (define (cddddr x) (cdr (cdr (cdr (cdr x))))) | ||||
| 
 | ||||
| (let ((*values* (list '*values*))) | ||||
|   (set! values | ||||
|  | @ -511,10 +526,12 @@ | |||
| 		 (for-each write args))) | ||||
| 
 | ||||
| (define (newline) (princ *linefeed*) #t) | ||||
| (define (display x) (princ x) #t) | ||||
| (define (display x (port *output-stream*)) | ||||
|   (with-output-to port (princ x)) | ||||
|   #t) | ||||
| (define (println . args) (prog1 (apply print args) (newline))) | ||||
| 
 | ||||
| (define (io.readline s) (io.readuntil s #\x0a)) | ||||
| (define (io.readline s) (io.readuntil s #\linefeed)) | ||||
| 
 | ||||
| ; call f on a stream until the stream runs out of data | ||||
| (define (read-all-of f s) | ||||
|  |  | |||
|  | @ -643,6 +643,7 @@ low-level functions: | |||
| - (eltype type field [field ...]) | ||||
| - (memcpy dest-cv src-cv) | ||||
| - (memcpy dest doffs src soffs nbytes) | ||||
| - (bswap cvalue) | ||||
| - (c2lisp cvalue)  ; convert to sexpr form | ||||
| * (typeof cvalue) | ||||
| * (sizeof cvalue|type) | ||||
|  | @ -968,7 +969,7 @@ consolidated todo list as of 7/8: | |||
| 
 | ||||
| - evaluator improvements, perf & debugging (below) | ||||
| * fix make-system-image to save aliases of builtins | ||||
| - reading named characters, e.g. #\newline etc. | ||||
| * reading named characters, e.g. #\newline etc. | ||||
| - #+, #- reader macros | ||||
| - printing improvements: *print-big*, keep track of horiz. position | ||||
|   per-stream so indenting works across print calls | ||||
|  | @ -978,6 +979,7 @@ consolidated todo list as of 7/8: | |||
| * optional arguments | ||||
| * keyword arguments | ||||
| - some kind of record, struct, or object system | ||||
| - improve test coverage | ||||
| 
 | ||||
| - special efficient reader for #array | ||||
| - reimplement vectors as (array lispvalue) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 JeffBezanson
						JeffBezanson