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';
|
||||
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