mirror of
https://github.com/false-schemers/skint.git
synced 2024-12-25 21:58:54 +01:00
faster read
This commit is contained in:
parent
c856b07b17
commit
5285131672
10 changed files with 1375 additions and 773 deletions
153
i.c
153
i.c
|
@ -13,8 +13,6 @@ extern obj cx__2Acurrent_2Dinput_2A;
|
|||
extern obj cx__2Acurrent_2Doutput_2A;
|
||||
extern obj cx__2Acurrent_2Derror_2A;
|
||||
|
||||
//#define istagged(o, t) istagged_inlined(o, t)
|
||||
|
||||
/* forwards */
|
||||
static struct intgtab_entry *lookup_integrable(int sym);
|
||||
static int intgtab_count(void);
|
||||
|
@ -269,8 +267,10 @@ static void _sck(obj *s) {
|
|||
#define is_bytevector(o) isbytevector(o)
|
||||
#define bytevector_len(o) bytevectorlen(o)
|
||||
#define bytevector_ref(o, i) (*bytevectorref(o, i))
|
||||
#define iport_file_obj(fp) hp_pushptr((fp), IPORT_FILE_NTAG)
|
||||
#define iport_file_obj(fp) hp_pushptr(tialloc(fp), IPORT_FILE_NTAG)
|
||||
#define iport_bytefile_obj(fp) hp_pushptr((fp), IPORT_BYTEFILE_NTAG)
|
||||
#define oport_file_obj(fp) hp_pushptr((fp), OPORT_FILE_NTAG)
|
||||
#define oport_bytefile_obj(fp) hp_pushptr((fp), OPORT_BYTEFILE_NTAG)
|
||||
#define iport_string_obj(fp) hp_pushptr((fp), IPORT_STRING_NTAG)
|
||||
#define oport_string_obj(fp) hp_pushptr((fp), OPORT_STRING_NTAG)
|
||||
#define iport_bytevector_obj(fp) hp_pushptr((fp), IPORT_BYTEVECTOR_NTAG)
|
||||
|
@ -1293,9 +1293,11 @@ define_instruction(strp) {
|
|||
}
|
||||
|
||||
define_instruction(str) {
|
||||
int i, n = get_fixnum(*ip++);
|
||||
obj o = string_obj(allocstring(n, ' '));
|
||||
unsigned char *s = (unsigned char *)stringchars(o);
|
||||
int i, n; obj o = *ip++; unsigned char *s;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; n = get_fixnum(o);
|
||||
o = string_obj(allocstring(n, ' '));
|
||||
s = (unsigned char *)stringchars(o);
|
||||
for (i = 0; i < n; ++i) {
|
||||
obj x = sref(i); ckc(x); s[i] = get_char(x);
|
||||
}
|
||||
|
@ -1335,8 +1337,27 @@ define_instruction(sput) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(scat) {
|
||||
obj x = ac, y = spop(); int *d;
|
||||
define_instruction(sapp) {
|
||||
int a, c, i, n, *d; obj o = *ip++;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; c = get_fixnum(o);
|
||||
for (n = 0, a = 0; a < c; ++a) {
|
||||
obj s = sref(a); cks(s);
|
||||
n += string_len(s);
|
||||
}
|
||||
d = allocstring(n, ' ');
|
||||
for (i = 0, a = 0; a < c; ++a) {
|
||||
obj s = sref(a); n = string_len(s);
|
||||
memcpy(sdatachars(d)+i, stringchars(s), n);
|
||||
i += n;
|
||||
}
|
||||
sdrop(c); ac = string_obj(d);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(sapp2) {
|
||||
/* specialized version of sapp; both args on stack */
|
||||
obj x = spop(), y = spop(); int *d;
|
||||
cks(x); cks(y);
|
||||
d = stringcat(stringdata(x), stringdata(y));
|
||||
ac = string_obj(d);
|
||||
|
@ -1398,9 +1419,11 @@ define_instruction(bvecp) {
|
|||
}
|
||||
|
||||
define_instruction(bvec) {
|
||||
int i, n = get_fixnum(*ip++);
|
||||
obj o = bytevector_obj(allocbytevector(n));
|
||||
unsigned char *s = (unsigned char *)bytevectorbytes(o);
|
||||
int i, n; obj o = *ip++; unsigned char *s;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; n = get_fixnum(o);
|
||||
o = bytevector_obj(allocbytevector(n));
|
||||
s = (unsigned char *)bytevectorbytes(o);
|
||||
for (i = 0; i < n; ++i) {
|
||||
obj x = sref(i); ck8(x); s[i] = byte_from_obj(x);
|
||||
}
|
||||
|
@ -1451,6 +1474,25 @@ define_instruction(bsub) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(bapp) {
|
||||
int a, c, i, n, *d; obj o = *ip++;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; c = get_fixnum(o);
|
||||
for (n = 0, a = 0; a < c; ++a) {
|
||||
obj b = sref(a); ckb(b);
|
||||
n += bytevector_len(b);
|
||||
}
|
||||
d = allocbytevector(n);
|
||||
for (i = 0, a = 0; a < c; ++a) {
|
||||
obj b = sref(a); n = bytevector_len(b);
|
||||
memcpy(bvdatabytes(d)+i, bytevectorbytes(b), n);
|
||||
i += n;
|
||||
}
|
||||
sdrop(c); ac = bytevector_obj(d);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
|
||||
define_instruction(beq) {
|
||||
obj x = ac, y = spop(); ckb(x); ckb(y);
|
||||
ac = bool_obj(bytevectoreq(bytevectordata(x), bytevectordata(y)));
|
||||
|
@ -1515,7 +1557,9 @@ define_instruction(vecp) {
|
|||
}
|
||||
|
||||
define_instruction(vec) {
|
||||
int i, n = get_fixnum(*ip++);
|
||||
int i, n; obj o = *ip++;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; n = get_fixnum(o);
|
||||
hp_reserve(vecbsz(n));
|
||||
for (i = n-1; i >= 0; --i) *--hp = sref(i);
|
||||
ac = hend_vec(n);
|
||||
|
@ -1557,8 +1601,27 @@ define_instruction(vput) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(vcat) {
|
||||
obj x = ac, y = sref(0); int n1, n2, n;
|
||||
define_instruction(vapp) {
|
||||
int a, c, n, i; obj o = *ip++;
|
||||
/* special arrangement for handcoded proc */
|
||||
if (!o) o = ac; c = get_fixnum(o);
|
||||
for (n = 0, a = 0; a < c; ++a) {
|
||||
obj v = sref(a); ckv(v);
|
||||
n += vector_len(v);
|
||||
}
|
||||
hp_reserve(vecbsz(n));
|
||||
for (a = c; a > 0; --a) {
|
||||
obj v = sref(a-1); i = vector_len(v);
|
||||
/* NB: vector_ref fails to return pointer to empty vector's start */
|
||||
hp -= i; if (i) objcpy(hp, &vector_ref(v, 0), i);
|
||||
}
|
||||
sdrop(c); ac = hend_vec(n);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(vapp2) {
|
||||
/* specialized version of sapp; both args on stack */
|
||||
obj x = sref(0), y = sref(1); int n1, n2, n;
|
||||
ckv(x); ckv(y);
|
||||
n1 = vector_len(x), n2 = vector_len(y), n = n1 + n2;
|
||||
hp_reserve(vecbsz(n));
|
||||
|
@ -1566,7 +1629,7 @@ define_instruction(vcat) {
|
|||
hp -= n2; if (n2) objcpy(hp, &vector_ref(y, 0), n2);
|
||||
hp -= n1; if (n1) objcpy(hp, &vector_ref(x, 0), n1);
|
||||
ac = hend_vec(n);
|
||||
sdrop(1);
|
||||
sdrop(2);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
|
@ -1619,11 +1682,14 @@ define_instruction(stol) {
|
|||
}
|
||||
|
||||
define_instruction(ltos) {
|
||||
obj l = ac; int n = 0, i, *d;
|
||||
while (is_pair(l)) { l = pair_cdr(l); ++n; }
|
||||
obj l; int n, i, *d;
|
||||
for (n = 0, l = ac; is_pair(l); l = pair_cdr(l)) {
|
||||
obj x = pair_car(ac); ckc(x);
|
||||
++n;
|
||||
}
|
||||
d = allocstring(n, ' ');
|
||||
for (i = 0; i < n; ac = pair_cdr(ac), ++i) {
|
||||
obj x = pair_car(ac); ckc(x);
|
||||
obj x = pair_car(ac);
|
||||
sdatachars(d)[i] = get_char(x);
|
||||
}
|
||||
ac = string_obj(d);
|
||||
|
@ -3237,14 +3303,14 @@ define_instruction(oof) {
|
|||
define_instruction(obif) {
|
||||
FILE *fp; cks(ac);
|
||||
fp = fopen(stringchars(ac), "rb");
|
||||
ac = (fp == NULL) ? bool_obj(0) : iport_file_obj(fp);
|
||||
ac = (fp == NULL) ? bool_obj(0) : iport_bytefile_obj(fp);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(obof) {
|
||||
FILE *fp; cks(ac);
|
||||
fp = fopen(stringchars(ac), "wb");
|
||||
ac = (fp == NULL) ? bool_obj(0) : oport_file_obj(fp);
|
||||
ac = (fp == NULL) ? bool_obj(0) : oport_bytefile_obj(fp);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
|
@ -3310,7 +3376,6 @@ define_instruction(spfc) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
|
||||
define_instruction(gos) {
|
||||
cxtype_oport_t *vt; ckw(ac);
|
||||
vt = ckoportvt(ac);
|
||||
|
@ -3320,6 +3385,7 @@ define_instruction(gos) {
|
|||
} else {
|
||||
cbuf_t *pcb = oportdata(ac);
|
||||
ac = string_obj(newstring(cbdata(pcb)));
|
||||
cbclear(pcb); /* a-la Chez */
|
||||
}
|
||||
gonexti();
|
||||
}
|
||||
|
@ -3338,6 +3404,30 @@ define_instruction(gob) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(gov) {
|
||||
obj c = spop(); cxtype_oport_t *vt = oportvt(ac);
|
||||
int tk; char *s; ckc(c); tk = get_char(c);
|
||||
if (vt != (cxtype_oport_t *)OPORT_STRING_NTAG) failactype("string input port");
|
||||
s = cbdata((cbuf_t*)oportdata(ac));
|
||||
switch (tk) {
|
||||
case 'n': {
|
||||
int radix = 10; long l; double d;
|
||||
switch (strtofxfl(s, radix, &l, &d)) {
|
||||
case 'e': ac = fixnum_obj(l); break;
|
||||
case 'i': ac = flonum_obj(d); break;
|
||||
default : ac = bool_obj(0); break;
|
||||
}
|
||||
} break;
|
||||
case 'c': ac = char_obj(*s); break;
|
||||
case 'y': ac = mksymbol(internsym(s)); break;
|
||||
case 's': ac = string_obj(newstring(s)); break;
|
||||
case '#': case '=': ac = fixnum_obj(atoi(s)); break;
|
||||
case '!': ac = mkshebang(internsym(s)); break;
|
||||
default : ac = bool_obj(0);
|
||||
}
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(rdc) {
|
||||
int c; ckr(ac);
|
||||
c = iportgetc(ac);
|
||||
|
@ -3382,6 +3472,25 @@ define_instruction(rd8r) {
|
|||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(rdln) {
|
||||
int *d = NULL; cxtype_iport_t *vt = iportvt(ac);
|
||||
if (!vt || vt->ctl(CTLOP_RDLN, iportdata(ac), &d) < 0) failactype("text input port");
|
||||
else if (d == NULL) ac = eof_obj();
|
||||
else ac = string_obj(d);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(rdtk) {
|
||||
obj o = spop(); cbuf_t *pcb; int tk;
|
||||
cxtype_iport_t *ivt = iportvt(ac);
|
||||
cxtype_oport_t *bvt = oportvt(o);
|
||||
if (!ivt) failactype("text input port");
|
||||
if (bvt != (cxtype_oport_t *)OPORT_STRING_NTAG) failtype(o, "string output port");
|
||||
pcb = oportdata(o);
|
||||
tk = slex(ivt->getch, ivt->ungetch, iportdata(ac), pcb);
|
||||
ac = (tk <= 0) ? bool_obj(tk < 0) : char_obj(tk);
|
||||
gonexti();
|
||||
}
|
||||
|
||||
define_instruction(eofp) {
|
||||
ac = bool_obj(is_eof(ac));
|
||||
|
@ -4015,7 +4124,7 @@ define_instruction(gccnt) {
|
|||
}
|
||||
|
||||
define_instruction(bumpcnt) {
|
||||
extern size_t cxg_bumpcount;
|
||||
extern int cxg_bumpcount;
|
||||
ac = fixnum_obj((int)cxg_bumpcount);
|
||||
gonexti();
|
||||
}
|
||||
|
|
16
i.h
16
i.h
|
@ -396,14 +396,15 @@ declare_instruction(cigt, "Ci>", 0, "char-ci>?",
|
|||
declare_instruction(cile, "Ci>!", 0, "char-ci<=?", 'c', AUTOGL)
|
||||
declare_instruction(cige, "Ci<!", 0, "char-ci>=?", 'c', AUTOGL)
|
||||
declare_instruction(strp, "S0", 0, "string?", '1', AUTOGL)
|
||||
declare_instruction(str, "S1", 1, "string", '#', "%!0.0X3]1")
|
||||
declare_instruction(str, "S1", 1, "string", '#', "S1(f)]0")
|
||||
declare_instruction(smk, "S2\0'(c )", 0, "make-string", 'b', AUTOGL)
|
||||
declare_instruction(slen, "S3", 0, "string-length", '1', AUTOGL)
|
||||
declare_instruction(sget, "S4", 0, "string-ref", '2', AUTOGL)
|
||||
declare_instruction(sput, "S5", 0, "string-set!", '3', AUTOGL)
|
||||
declare_instruction(scat, "S6", 0, "string-cat", '2', AUTOGL)
|
||||
declare_instruction(ssub, "S7", 0, "substring", '3', AUTOGL)
|
||||
declare_instruction(spos, "S8", 0, "string-position", '2', AUTOGL)
|
||||
declare_instruction(sapp, "Sa", 1, "string-append", '#', "Sa(f)]0")
|
||||
declare_instruction(sapp2, "Sa2", 0, NULL, 0, NULL)
|
||||
declare_instruction(supc, "Su", 0, "string-upcase", '1', AUTOGL)
|
||||
declare_instruction(sdnc, "Sd", 0, "string-downcase", '1', AUTOGL)
|
||||
declare_instruction(sflc, "Sf", 0, "string-foldcase", '1', AUTOGL)
|
||||
|
@ -420,19 +421,21 @@ declare_instruction(sigt, "Si>", 0, "string-ci>?",
|
|||
declare_instruction(sile, "Si>!", 0, "string-ci<=?", 'c', AUTOGL)
|
||||
declare_instruction(sige, "Si<!", 0, "string-ci>=?", 'c', AUTOGL)
|
||||
declare_instruction(vecp, "V0", 0, "vector?", '1', AUTOGL)
|
||||
declare_instruction(vec, "V1", 1, "vector", '#', "%!0.0X1]1")
|
||||
declare_instruction(vec, "V1", 1, "vector", '#', "V1(f)]0")
|
||||
declare_instruction(vmk, "V2\0f", 0, "make-vector", 'b', AUTOGL)
|
||||
declare_instruction(vlen, "V3", 0, "vector-length", '1', AUTOGL)
|
||||
declare_instruction(vget, "V4", 0, "vector-ref", '2', AUTOGL)
|
||||
declare_instruction(vput, "V5", 0, "vector-set!", '3', AUTOGL)
|
||||
declare_instruction(vcat, "V6", 0, "vector-cat", '2', AUTOGL)
|
||||
declare_instruction(vapp, "Va", 1, "vector-append", '#', "Va(f)]0")
|
||||
declare_instruction(vapp2, "Va2", 0, NULL, 0, NULL)
|
||||
declare_instruction(bvecp, "B0", 0, "bytevector?", '1', AUTOGL)
|
||||
declare_instruction(bvec, "B1", 1, "bytevector", '#', "%!0.0E1]1")
|
||||
declare_instruction(bvec, "B1", 1, "bytevector", '#', "B1(f)]0")
|
||||
declare_instruction(bmk, "B2\0'0", 0, "make-bytevector", 'b', AUTOGL)
|
||||
declare_instruction(blen, "B3", 0, "bytevector-length", '1', AUTOGL)
|
||||
declare_instruction(bget, "B4", 0, "bytevector-u8-ref", '2', AUTOGL)
|
||||
declare_instruction(bput, "B5", 0, "bytevector-u8-set!", '3', AUTOGL)
|
||||
declare_instruction(bsub, "B7", 0, "subbytevector", '3', AUTOGL)
|
||||
declare_instruction(bapp, "Ba", 1, "bytevector-append", '#', "Ba(f)]0")
|
||||
declare_instruction(beq, "B=", 0, "bytevector=?", 'c', AUTOGL)
|
||||
declare_instruction(recp, "O0\0Y9", 0, "record?", 'b', AUTOGL)
|
||||
declare_instruction(rmk, "O2\0f", 0, "make-record", 't', AUTOGL)
|
||||
|
@ -493,12 +496,15 @@ declare_instruction(pfc, "P78", 0, "port-fold-case?",
|
|||
declare_instruction(spfc, "P79", 0, "set-port-fold-case!", '2', AUTOGL)
|
||||
declare_instruction(gos, "P90", 0, "get-output-string", '1', AUTOGL)
|
||||
declare_instruction(gob, "P91", 0, "get-output-bytevector", '1', AUTOGL)
|
||||
declare_instruction(gov, "P92", 0, "%get-output-value", '2', AUTOGL)
|
||||
declare_instruction(rdc, "R0\0Pi", 0, "read-char", 'u', AUTOGL)
|
||||
declare_instruction(rdac, "R1\0Pi", 0, "peek-char", 'u', AUTOGL)
|
||||
declare_instruction(rdcr, "R2\0Pi", 0, "char-ready?", 'u', AUTOGL)
|
||||
declare_instruction(rd8, "R3\0Pi", 0, "read-u8", 'u', AUTOGL)
|
||||
declare_instruction(rda8, "R4\0Pi", 0, "peek-u8", 'u', AUTOGL)
|
||||
declare_instruction(rd8r, "R5\0Pi", 0, "u8-ready?", 'u', AUTOGL)
|
||||
declare_instruction(rdln, "R6\0Pi", 0, "read-line", 'u', AUTOGL)
|
||||
declare_instruction(rdtk, "R7", 0, "%read-token", '2', AUTOGL)
|
||||
declare_instruction(eofp, "R8", 0, "eof-object?", '1', AUTOGL)
|
||||
declare_instruction(eof, "R9", 0, "eof-object", '0', AUTOGL)
|
||||
declare_instruction(wrc, "W0\0Po", 0, "write-char", 'b', AUTOGL)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
(import (only (skint) implementation-version))
|
525
n.c
525
n.c
|
@ -478,7 +478,7 @@ static int noputch(int c, void *p) { return EOF; }
|
|||
|
||||
static int noflush(void *p) { return EOF; }
|
||||
|
||||
static int noctl(const char *cmd, void *p, ...) { return -1; }
|
||||
static int noctl(ctlop_t op, void *p, ...) { return -1; }
|
||||
|
||||
static void ffree(void *vp) {
|
||||
/* FILE *fp = vp; assert(fp); cannot fclose(fp) here because of FILE reuse! */ }
|
||||
|
@ -499,6 +499,27 @@ static int sigetch(sifile_t *fp) {
|
|||
static int siungetch(int c, sifile_t *fp) {
|
||||
assert(fp && fp->p); --(fp->p); assert(c == *(fp->p)); return c; }
|
||||
|
||||
static int sictl(ctlop_t op, sifile_t *fp, ...)
|
||||
{
|
||||
if (op == CTLOP_RDLN) {
|
||||
va_list args; int **pd;
|
||||
va_start(args, fp);
|
||||
pd = va_arg(args, int **);
|
||||
if (*(fp->p) == 0) {
|
||||
*pd = NULL;
|
||||
} else {
|
||||
char *s = strchr(fp->p, '\n');
|
||||
if (s) { *pd = newstringn(fp->p, s-fp->p); fp->p = s+1; }
|
||||
else { *pd = newstring(fp->p); fp->p += strlen(fp->p); }
|
||||
}
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bvifile_t *bvialloc(unsigned char *p, unsigned char *e, void *base) {
|
||||
bvifile_t *fp = cxm_cknull(malloc(sizeof(bvifile_t)), "malloc(bvifile)");
|
||||
fp->p = p; fp->e = e; fp->base = base; return fp; }
|
||||
|
@ -516,11 +537,14 @@ static int bvigetch(bvifile_t *fp) {
|
|||
static int bviungetch(int c, bvifile_t *fp) {
|
||||
assert(fp && fp->p && fp->e); --(fp->p); assert(c == *(fp->p)); return c; }
|
||||
|
||||
cbuf_t* cbinit(cbuf_t* pcb) {
|
||||
pcb->fill = pcb->buf = cxm_cknull(malloc(64), "malloc(cbdata)");
|
||||
pcb->end = pcb->buf + 64; return pcb;
|
||||
}
|
||||
|
||||
cbuf_t* newcb(void) {
|
||||
cbuf_t* pcb = cxm_cknull(malloc(sizeof(cbuf_t)), "malloc(cbuf)");
|
||||
pcb->fill = pcb->buf = cxm_cknull(malloc(64), "malloc(cbdata)");
|
||||
pcb->end = pcb->buf + 64; pcb->off = 0;
|
||||
return pcb;
|
||||
return cbinit(pcb);
|
||||
}
|
||||
|
||||
void freecb(cbuf_t* pcb) { if (pcb) { free(pcb->buf); free(pcb); } }
|
||||
|
@ -533,23 +557,18 @@ static void cbgrow(cbuf_t* pcb, size_t n) {
|
|||
pcb->fill = pcb->buf + cnt, pcb->end = pcb->buf + newsz;
|
||||
}
|
||||
|
||||
char* cballoc(cbuf_t* pcb, size_t n) {
|
||||
assert(pcb); /* allow for extra 1 char after n */
|
||||
if (pcb->fill + n+1 > pcb->end) cbgrow(pcb, n+1);
|
||||
pcb->fill += n;
|
||||
return pcb->fill - n;
|
||||
}
|
||||
|
||||
int cbputc(int c, cbuf_t* pcb) {
|
||||
if (pcb->fill == pcb->end) cbgrow(pcb, 1);
|
||||
*(pcb->fill)++ = c; return c;
|
||||
}
|
||||
|
||||
int cbgetc(cbuf_t* pcb) {
|
||||
if (pcb->buf + pcb->off >= pcb->fill) return EOF;
|
||||
return pcb->buf[pcb->off++];
|
||||
}
|
||||
|
||||
int cbungetc(cbuf_t* pcb, int c) {
|
||||
if (!pcb->off) return EOF;
|
||||
pcb->off -= 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
static int cbflush(cbuf_t* pcb) { return 0; }
|
||||
|
||||
static int cbclose(cbuf_t* pcb) { free(pcb->buf); pcb->buf = NULL; return 0; }
|
||||
|
@ -560,65 +579,150 @@ char* cbdata(cbuf_t* pcb) {
|
|||
if (pcb->fill == pcb->end) cbgrow(pcb, 1); *(pcb->fill) = 0; return pcb->buf;
|
||||
}
|
||||
|
||||
cbuf_t *cbclear(cbuf_t *pcb) { pcb->fill = pcb->buf; return pcb; }
|
||||
|
||||
typedef enum { TIF_NONE = 0, TIF_EOF = 1, TIF_CI = 2 } tiflags_t;
|
||||
typedef struct tifile_tag { cbuf_t cb; char *next; FILE *fp; int lno; tiflags_t flags; } tifile_t;
|
||||
|
||||
tifile_t *tialloc(FILE *fp) {
|
||||
tifile_t *tp = cxm_cknull(malloc(sizeof(tifile_t)), "malloc(tifile)");
|
||||
cbinit(&tp->cb); tp->next = tp->cb.buf; *(tp->next) = 0;
|
||||
tp->fp = fp; tp->lno = 0; tp->flags = TIF_NONE;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static void tifree(tifile_t *tp) {
|
||||
assert(tp); cbclose(&tp->cb); ffree(tp->fp); free(tp); }
|
||||
|
||||
static int ticlose(tifile_t *tp) {
|
||||
assert(tp); cbclose(&tp->cb); fclose(tp->fp); return 0; }
|
||||
|
||||
static int tigetch(tifile_t *tp) {
|
||||
int c; retry: c = *(tp->next);
|
||||
if (c != 0) { ++(tp->next); return c; }
|
||||
/* see if we need to return actual 0 or refill the line */
|
||||
if (tp->next < tp->cb.fill) { ++(tp->next); return c; }
|
||||
else if (tp->flags & TIF_EOF || !tp->fp) return EOF;
|
||||
else { /* refill with next line from fp */
|
||||
cbuf_t *pcb = cbclear(&tp->cb); FILE *fp = tp->fp;
|
||||
#if 1
|
||||
char *line = fgets(cballoc(pcb, 256), 256, fp);
|
||||
if (!line) { cbclear(pcb); tp->flags |= TIF_EOF; }
|
||||
else { /* manually add the rest of the line */
|
||||
size_t len = strlen(line); pcb->fill = pcb->buf + len;
|
||||
if (len > 0 && line[len-1] != '\n') {
|
||||
do { c = getc(fp); if (c == EOF) break; cbputc(c, pcb); } while (c != '\n');
|
||||
if (c == EOF) tp->flags |= TIF_EOF;
|
||||
}
|
||||
}
|
||||
#else
|
||||
do { c = getc(fp); if (c == EOF) break; cbputc(c, pcb); } while (c != '\n');
|
||||
if (c == EOF) tp->flags |= TIF_EOF;
|
||||
#endif
|
||||
tp->lno += 1; tp->next = cbdata(pcb); /* 0-term */
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
static int tiungetch(int c, tifile_t *tp) {
|
||||
assert(tp->next > tp->cb.buf && tp->next <= tp->cb.fill);
|
||||
tp->next -= 1; // todo: utf-8
|
||||
return c;
|
||||
}
|
||||
|
||||
static int tictl(ctlop_t op, tifile_t *tp, ...)
|
||||
{
|
||||
if (op == CTLOP_RDLN) {
|
||||
va_list args; int c, n, **pd;
|
||||
va_start(args, tp);
|
||||
pd = va_arg(args, int **);
|
||||
c = tigetch(tp);
|
||||
if (c == EOF) {
|
||||
*pd = NULL;
|
||||
} else {
|
||||
char *s; tiungetch(c, tp);
|
||||
s = tp->next; n = tp->cb.fill - s;
|
||||
if (n > 0 && s[n-1] == '\n') --n;
|
||||
*pd = newstringn(s, n);
|
||||
tp->next = tp->cb.fill;
|
||||
}
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* port type array */
|
||||
|
||||
#define PORTTYPES_MAX 8
|
||||
|
||||
static cxtype_port_t cxt_port_types[PORTTYPES_MAX] = {
|
||||
cxtype_port_t cxt_port_types[PORTTYPES_MAX] = {
|
||||
#define IPORT_CLOSED_PTINDEX 0
|
||||
{ "closed-input-port", (void (*)(void*))nofree,
|
||||
SPT_CLOSED, (int (*)(void*))noclose,
|
||||
SPT_INPUT, (int (*)(void*))noclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define IPORT_FILE_PTINDEX 1
|
||||
{ "file-input-port", ffree,
|
||||
SPT_INPUT, (int (*)(void*))fclose,
|
||||
{ "file-input-port", (void (*)(void*))tifree,
|
||||
SPT_INPUT, (int (*)(void*))ticlose,
|
||||
(int (*)(void*))tigetch, (int (*)(int, void*))tiungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(ctlop_t, void *, ...))tictl },
|
||||
#define IPORT_BYTEFILE_PTINDEX 2
|
||||
{ "binary-file-input-port", ffree,
|
||||
SPT_INPUT|SPT_BINARY, (int (*)(void*))fclose,
|
||||
(int (*)(void*))(fgetc), (int (*)(int, void*))(ungetc),
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define IPORT_STRING_PTINDEX 2
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define IPORT_STRING_PTINDEX 3
|
||||
{ "string-input-port", (void (*)(void*))sifree,
|
||||
SPT_INPUT, (int (*)(void*))siclose,
|
||||
(int (*)(void*))sigetch, (int (*)(int, void*))siungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define IPORT_BYTEVECTOR_PTINDEX 3
|
||||
(int (*)(ctlop_t, void *, ...))sictl },
|
||||
#define IPORT_BYTEVECTOR_PTINDEX 4
|
||||
{ "bytevector-input-port", (void (*)(void*))bvifree,
|
||||
SPT_INPUT, (int (*)(void*))bviclose,
|
||||
SPT_INPUT|SPT_BINARY, (int (*)(void*))bviclose,
|
||||
(int (*)(void*))bvigetch, (int (*)(int, void*))bviungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_CLOSED_PTINDEX 4
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_CLOSED_PTINDEX 5
|
||||
{ "closed-output-port", (void (*)(void*))nofree,
|
||||
SPT_OUTPUT, (int (*)(void*))noclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_FILE_PTINDEX 5
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_FILE_PTINDEX 6
|
||||
{ "file-output-port", ffree,
|
||||
SPT_OUTPUT, (int (*)(void*))fclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))(fputc), (int (*)(void*))fflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_STRING_PTINDEX 6
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_BYTEFILE_PTINDEX 7
|
||||
{ "binary-file-output-port", ffree,
|
||||
SPT_OUTPUT|SPT_BINARY, (int (*)(void*))fclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))(fputc), (int (*)(void*))fflush,
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_STRING_PTINDEX 8
|
||||
{ "string-output-port", (void (*)(void*))freecb,
|
||||
SPT_OUTPUT, (int (*)(void*))cbclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))cbputc, (int (*)(void*))cbflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_BYTEVECTOR_PTINDEX 7
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_BYTEVECTOR_PTINDEX 9
|
||||
{ "bytevector-output-port", (void (*)(void*))freecb,
|
||||
SPT_OUTPUT, (int (*)(void*))cbclose,
|
||||
SPT_OUTPUT|SPT_BINARY, (int (*)(void*))cbclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))cbputc, (int (*)(void*))cbflush,
|
||||
(int (*)(const char *, void *, ...))noctl }
|
||||
(int (*)(ctlop_t, void *, ...))noctl }
|
||||
};
|
||||
|
||||
cxtype_t *IPORT_CLOSED_NTAG = (cxtype_t *)&cxt_port_types[IPORT_CLOSED_PTINDEX];
|
||||
|
||||
cxtype_t *IPORT_FILE_NTAG = (cxtype_t *)&cxt_port_types[IPORT_FILE_PTINDEX];
|
||||
|
||||
cxtype_t *IPORT_BYTEFILE_NTAG = (cxtype_t *)&cxt_port_types[IPORT_BYTEFILE_PTINDEX];
|
||||
|
||||
cxtype_t *IPORT_STRING_NTAG = (cxtype_t *)&cxt_port_types[IPORT_STRING_PTINDEX];
|
||||
|
||||
cxtype_t *IPORT_BYTEVECTOR_NTAG = (cxtype_t *)&cxt_port_types[IPORT_BYTEVECTOR_PTINDEX];
|
||||
|
@ -627,6 +731,8 @@ cxtype_t *OPORT_CLOSED_NTAG = (cxtype_t *)&cxt_port_types[OPORT_CLOSED_PTINDEX];
|
|||
|
||||
cxtype_t *OPORT_FILE_NTAG = (cxtype_t *)&cxt_port_types[OPORT_FILE_PTINDEX];
|
||||
|
||||
cxtype_t *OPORT_BYTEFILE_NTAG = (cxtype_t *)&cxt_port_types[OPORT_BYTEFILE_PTINDEX];
|
||||
|
||||
cxtype_t *OPORT_STRING_NTAG = (cxtype_t *)&cxt_port_types[OPORT_STRING_PTINDEX];
|
||||
|
||||
cxtype_t *OPORT_BYTEVECTOR_NTAG = (cxtype_t *)&cxt_port_types[OPORT_BYTEVECTOR_PTINDEX];
|
||||
|
@ -864,10 +970,29 @@ static void wrs(char *s, wenv_t *e) {
|
|||
assert(vt); while (*s) vt->putch(*s++, pp);
|
||||
}
|
||||
static int cleansymname(char *s) {
|
||||
#if 1
|
||||
static char inisub_map[256] = { /* ini: [a-zA-Z!$%&*:/<=>?@^_~] sub: ini + [0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
char *p = s; while (*p) if (inisub_map[*p++ & 0xFF] == 0) return 0; if (!s[0]) return 0;
|
||||
if (inisub_map[s[0] & 0xFF] == 1) return 1;
|
||||
#else
|
||||
char *inits = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$%&*/:<=>?@^_~";
|
||||
char *subss = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$%&*/:<=>?@^_~0123456789.@+-";
|
||||
if (s[0] == 0 || s[strspn(s, subss)] != 0) return 0; else if (strchr(inits, s[0])) return 1;
|
||||
else if (s[0] == '+' || s[0] == '-') return s[1] == 0 || (s[1] == '.' && s[2] && !isdigit(s[2])) || !isdigit(s[1]);
|
||||
#endif
|
||||
if (s[0] == '+' || s[0] == '-') {
|
||||
if (strcmp_ci(s+1, "inf.0") == 0 || strcmp_ci(s+1, "nan.0") == 0) return 0;
|
||||
if ((s[1] == 'i' || s[1] == 'I') && s[2] == 0) return 0;
|
||||
return s[1] == 0 || (s[1] == '.' && s[2] && !isdigit(s[2])) || (s[1] != '.' && !isdigit(s[1]));
|
||||
}
|
||||
else return s[0] == '.' && s[1] && !isdigit(s[1]);
|
||||
}
|
||||
static void wrdatum(obj o, wenv_t *e) {
|
||||
|
@ -1017,7 +1142,7 @@ void oportputshared(obj x, obj p, int disp) {
|
|||
extern int is_tty_port(obj o)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
if ((cxtype_t*)iportvt(o) == IPORT_FILE_NTAG) fp = (FILE*)iportdata(o);
|
||||
if ((cxtype_t*)iportvt(o) == IPORT_FILE_NTAG) fp = ((tifile_t*)iportdata(o))->fp;
|
||||
else if ((cxtype_t*)oportvt(o) == OPORT_FILE_NTAG) fp = (FILE*)oportdata(o);
|
||||
if (!fp) return 0;
|
||||
return isatty(fileno(fp));
|
||||
|
@ -1085,4 +1210,324 @@ extern int set_cwd(char *cwd)
|
|||
return chdir(cwd);
|
||||
}
|
||||
|
||||
#define TT_FALSE 'f'
|
||||
#define TT_TRUE 't'
|
||||
#define TT_NUMBER 'n'
|
||||
#define TT_CHAR 'c'
|
||||
#define TT_STRING 's'
|
||||
#define TT_SYMBOL 'y'
|
||||
#define TT_OPENLIST 'l'
|
||||
#define TT_OPENVEC 'v'
|
||||
#define TT_OPENU8VEC 'u'
|
||||
#define TT_CLOSE 'r'
|
||||
#define TT_OPENLIST2 'b'
|
||||
#define TT_CLOSE2 'k'
|
||||
#define TT_QUOTE '\''
|
||||
#define TT_QQUOTE '`'
|
||||
#define TT_UNQUOTE ','
|
||||
#define TT_UNQSPL '@'
|
||||
#define TT_DOT '.'
|
||||
#define TT_BOX '&'
|
||||
#define TT_HDEF '='
|
||||
#define TT_HREF '#'
|
||||
#define TT_HSEMI ';'
|
||||
#define TT_SHEBANG '!'
|
||||
#define TT_SHEBANG_FC 'F'
|
||||
#define TT_SHEBANG_NF 'N'
|
||||
#define TT_ERR 0
|
||||
#define TT_EOF -1
|
||||
|
||||
#if 1
|
||||
static char num_map[256] = { /* [#A-Za-z/0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#define is_num(c) (num_map[(c) & 0xFF]) /* NB: eof at num_map[255] */
|
||||
#else
|
||||
static int is_num(int c)
|
||||
{ /* this covers all initials and constituents of prefixed numbers */
|
||||
char *s = "#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/0123456789+-.@";
|
||||
return c != EOF && strchr(s, c) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static char numsym_map[256] = { /* [A-Za-z!$%&*:/<=>?^_~0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#define is_numsym(c) (numsym_map[(c) & 0xFF]) /* NB: eof at numsym_map[255] */
|
||||
#else
|
||||
static int is_numsym(int c)
|
||||
{ /* this covers all initials and constituents of plain symbols and nonprefixed decimals */
|
||||
char *s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*/:<=>?^_~0123456789+-.@";
|
||||
return c != EOF && strchr(s, c) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int is_delimiter(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\t': case '\r': case '\n': case ' ':
|
||||
case '(': case ')': case '[': case ']':
|
||||
case '|': case '\"': case ';': case EOF:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lex_1esc(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'a': return '\a';
|
||||
case 'b': return '\b';
|
||||
case 't': return '\t';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case '|': return '|';
|
||||
case '\"': return '\"';
|
||||
case '\\': return '\\';
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int lex_xesc(int c, int xc)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (xc << 4) + c - '0';
|
||||
if (c >= 'A' && c <= 'F') return (xc << 4) + 10 + c - 'A';
|
||||
if (c >= 'a' && c <= 'f') return (xc << 4) + 10 + c - 'a';
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* slex: splits input into tokens delivered via char buf */
|
||||
int slex(int (*in_getc)(void*), int (*in_ungetc)(int, void*), void *in, cbuf_t *pcb)
|
||||
{
|
||||
int c, xc;
|
||||
next: cbclear(pcb);
|
||||
switch (c = in_getc(in)) {
|
||||
case EOF: return TT_EOF;
|
||||
case ',': goto after_comma;
|
||||
case '`': return TT_QQUOTE;
|
||||
case '\'': return TT_QUOTE;
|
||||
case ']': return TT_CLOSE2;
|
||||
case '[': return TT_OPENLIST2;
|
||||
case ')': return TT_CLOSE;
|
||||
case '(': return TT_OPENLIST;
|
||||
case ';': goto in_linecomm;
|
||||
case '|': goto in_barsym;
|
||||
case '\"': goto in_string;
|
||||
case '#': cbputc(c, pcb); goto after_hash;
|
||||
case '.': cbputc(c, pcb); goto after_dot;
|
||||
default:
|
||||
if (is_numsym(c)) goto in_numsym;
|
||||
if ((c >= '\t' && c <= '\n') || (c >= '\f' && c <= '\r') || c == ' ') goto in_whitespace;
|
||||
in_ungetc(c, in); goto err;
|
||||
}
|
||||
in_whitespace:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_EOF;
|
||||
if ((c >= '\t' && c <= '\n') || (c >= '\f' && c <= '\r') || c == ' ') goto in_whitespace;
|
||||
in_ungetc(c, in); goto next;
|
||||
in_linecomm:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_EOF;
|
||||
if (c != '\n') goto in_linecomm;
|
||||
goto next;
|
||||
in_numsym:
|
||||
while (is_numsym(c)) { cbputc(c, pcb); c = in_getc(in); }
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
if (cleansymname(cbdata(pcb))) return TT_SYMBOL;
|
||||
return TT_NUMBER;
|
||||
after_dot:
|
||||
c = in_getc(in); if (is_numsym(c)) goto in_numsym;
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
return TT_DOT;
|
||||
after_hash:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '(') return TT_OPENVEC;
|
||||
if (c == '\\') { cbclear(pcb); goto in_char; }
|
||||
if (c == '|') { // handcoded
|
||||
int level = 1;
|
||||
normal:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '#': goto after_hashc;
|
||||
case '|': goto after_barc;
|
||||
default: goto normal;
|
||||
}
|
||||
after_hashc:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '#': goto after_hashc;
|
||||
case '|': level++;
|
||||
default: goto normal;
|
||||
}
|
||||
after_barc:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '|': goto after_barc;
|
||||
case '#': if (!--level) goto next;
|
||||
default: goto normal;
|
||||
}
|
||||
}
|
||||
if (c == '!') { cbclear(pcb); goto after_shebang; }
|
||||
if (c == '&') return TT_BOX;
|
||||
if (c == 'u' || c == 'U') { cbputc(tolower(c), cbclear(pcb)); goto after_hashu; }
|
||||
if (c >= '0' && c <= '9') { cbputc(c, cbclear(pcb)); goto in_hashnum; }
|
||||
if (c == 'B' || (c >= 'D' && c <= 'E') || c == 'I' || c == 'O' || c == 'X' ||
|
||||
c == 'b' || (c >= 'd' && c <= 'e') || c == 'i' || c == 'o' || c == 'x')
|
||||
{ cbputc(tolower(c), pcb); goto in_hashradixie; }
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(tolower(c), cbclear(pcb)); goto in_hashname; }
|
||||
if (c == ';') { cbclear(pcb); return TT_HSEMI; } // todo: skip S-exp
|
||||
in_ungetc(c, in); goto err;
|
||||
after_comma:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_UNQUOTE;
|
||||
if (c == '@') return TT_UNQSPL;
|
||||
in_ungetc(c, in); return TT_UNQUOTE;
|
||||
in_char:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
if (c == 'x' || c == 'X') goto in_char_xesc;
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) goto in_char_name;
|
||||
cbputc(c, pcb); // todo: parse utf-8
|
||||
c = in_getc(in); if (c != EOF) in_ungetc(c, in);
|
||||
if (!is_delimiter(c)) goto err;
|
||||
return TT_CHAR;
|
||||
in_char_name:
|
||||
while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(c, pcb); c = in_getc(in); }
|
||||
if (cblen(pcb) > 1) {
|
||||
char *s = cbdata(pcb); int x = EOF;
|
||||
if (0 == strcmp(s, "null")) x = '\0';
|
||||
else if (0 == strcmp(s, "alarm")) x = '\a';
|
||||
else if (0 == strcmp(s, "backspace")) x = '\b';
|
||||
else if (0 == strcmp(s, "delete")) x = '\x7F';
|
||||
else if (0 == strcmp(s, "escape")) x = '\x1B';
|
||||
else if (0 == strcmp(s, "newline")) x = '\n';
|
||||
else if (0 == strcmp(s, "return")) x = '\r';
|
||||
else if (0 == strcmp(s, "space")) x = ' ';
|
||||
else if (0 == strcmp(s, "tab")) x = '\t';
|
||||
else if (0 == strcmp(s, "vtab")) x = '\v'; //++
|
||||
else if (0 == strcmp(s, "page")) x = '\f'; //++
|
||||
else if (0 == strcmp(s, "linefeed")) x = '\n'; //++
|
||||
if (x == EOF) goto err;
|
||||
cbputc(x, cbclear(pcb));
|
||||
}
|
||||
if (c != EOF) in_ungetc(c, in);
|
||||
if (!is_delimiter(c)) goto err;
|
||||
return TT_CHAR;
|
||||
in_char_xesc:
|
||||
xc = c; c = in_getc(in);
|
||||
if (is_delimiter(c)) { if (c != EOF) in_ungetc(c, in); cbputc(xc, pcb); return TT_CHAR; }
|
||||
else xc = 0;
|
||||
while (!is_delimiter(c) && (xc = lex_xesc(c, xc)) != EOF) c = in_getc(in);
|
||||
if (!is_delimiter(c) || xc == EOF) goto err;
|
||||
if (c != EOF) in_ungetc(c, in); cbputc(xc, pcb); return TT_CHAR; // todo: cbput8c
|
||||
in_barsym:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
else if (c == '|') return TT_SYMBOL;
|
||||
else if (c == '\\') goto in_barsym_esc;
|
||||
cbputc(c, pcb); goto in_barsym; // todo: parse utf-8
|
||||
in_barsym_esc:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == 'x' || c == 'X') goto in_barsym_xesc;
|
||||
xc = lex_1esc(c); if (xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_barsym; // todo: cbput8c
|
||||
in_barsym_xesc:
|
||||
xc = 0; do c = in_getc(in);
|
||||
while (c != ';' && (xc = lex_xesc(c, xc)) != EOF);
|
||||
if (c != ';' || xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_barsym; // todo: cbput8c
|
||||
in_string:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
else if (c == '\"') return TT_STRING;
|
||||
else if (c == '\\') goto in_str_esc;
|
||||
cbputc(c, pcb); goto in_string; // todo: parse utf-8
|
||||
in_str_esc:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == 'x' || c == 'X') goto in_str_xesc;
|
||||
if (c == '\t' || c == ' ' || c == '\r' || c == '\n') goto in_str_sesc;
|
||||
xc = lex_1esc(c); if (xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_string; // todo: cbput8c
|
||||
in_str_sesc:
|
||||
while (c == '\t' || c == ' ' || c == '\r') c = in_getc(in);
|
||||
if (c != '\n') goto err;
|
||||
do c = in_getc(in); while (c == '\t' || c == ' ');
|
||||
if (c == EOF) goto err;
|
||||
in_ungetc(c, in); goto in_string;
|
||||
in_str_xesc:
|
||||
xc = 0; do c = in_getc(in);
|
||||
while (c != ';' && (xc = lex_xesc(c, xc)) != EOF);
|
||||
if (c != ';' || xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_string; // todo: cbput8c
|
||||
in_hashradixie:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
while (is_num(c)) { cbputc(tolower(c), pcb); c = in_getc(in); }
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
return TT_NUMBER;
|
||||
in_hashname:
|
||||
c = in_getc(in);
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(tolower(c), pcb); goto in_hashname; }
|
||||
if (is_delimiter(c)) {
|
||||
char *s = cbdata(pcb); if (c != EOF) in_ungetc(c, in);
|
||||
if (0 == strcmp(s, "t")) return TT_TRUE;
|
||||
else if (0 == strcmp(s, "true")) return TT_TRUE;
|
||||
else if (0 == strcmp(s, "f")) return TT_FALSE;
|
||||
else if (0 == strcmp(s, "false")) return TT_FALSE;
|
||||
}
|
||||
goto err;
|
||||
in_hashnum:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '#') return TT_HREF;
|
||||
if (c == '=') return TT_HDEF;
|
||||
if (c >= '0' && c <= '9') { cbputc(c, pcb); goto in_hashnum; }
|
||||
in_ungetc(c, in); goto err;
|
||||
after_hashu:
|
||||
c = in_getc(in);
|
||||
if (c == '8') { cbclear(pcb); goto after_hashu8; }
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(tolower(c), pcb); goto in_hashname; }
|
||||
in_ungetc(c, in); goto err;
|
||||
after_hashu8:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '(') return TT_OPENU8VEC;
|
||||
in_ungetc(c, in); goto err;
|
||||
after_shebang:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == ' ' || c == '\t') goto in_shebang_line;
|
||||
else if (c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(c, pcb); goto in_shebang_name; }
|
||||
in_ungetc(c, in); goto err;
|
||||
in_shebang_line:
|
||||
while (c == ' ' || c == '\t') c = in_getc(in);
|
||||
while (c != EOF && c != '\n') { cbputc(c, pcb); c = in_getc(in); }
|
||||
while (pcb->fill > pcb->buf && (pcb->fill[-1] == ' ' || pcb->fill[-1] == '\t')) pcb->fill -= 1;
|
||||
return TT_SHEBANG;
|
||||
in_shebang_name:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) goto in_shebang_pre;
|
||||
else if (c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(c, pcb); goto in_shebang_name; }
|
||||
else { in_ungetc(c, in); goto in_shebang_pre; }
|
||||
in_shebang_pre: {
|
||||
char *s = cbdata(pcb);
|
||||
if (strcmp_ci(s, "fold-case") == 0) return TT_SHEBANG_FC;
|
||||
if (strcmp_ci(s, "no-fold-case") == 0) return TT_SHEBANG_NF;
|
||||
return TT_SHEBANG;
|
||||
}
|
||||
err:
|
||||
eoferr:
|
||||
return TT_ERR;
|
||||
}
|
||||
|
||||
|
|
30
n.h
30
n.h
|
@ -400,28 +400,33 @@ extern obj* procedureref(obj o, int i);
|
|||
#define mkshebang(i) mkimm(i, SHEBANG_ITAG)
|
||||
#define getshebang(o) getimmu(o, SHEBANG_ITAG)
|
||||
/* input/output ports */
|
||||
typedef enum { CTLOP_RDLN } ctlop_t;
|
||||
typedef struct { /* extends cxtype_t */
|
||||
const char *tname;
|
||||
void (*free)(void*);
|
||||
enum { SPT_CLOSED = 0, SPT_INPUT = 1, SPT_OUTPUT = 2, SPT_IO = 3 } spt;
|
||||
enum { SPT_INPUT = 1, SPT_OUTPUT = 2, SPT_IO = 3, SPT_BINARY = 4 } spt;
|
||||
int (*close)(void*);
|
||||
int (*getch)(void*);
|
||||
int (*ungetch)(int, void*);
|
||||
int (*putch)(int, void*);
|
||||
int (*flush)(void*);
|
||||
int (*ctl)(const char*, void*, ...);
|
||||
int (*ctl)(ctlop_t, void*, ...);
|
||||
} cxtype_port_t, cxtype_iport_t, cxtype_oport_t;
|
||||
#define PORTTYPES_MAX 10
|
||||
extern cxtype_port_t cxt_port_types[PORTTYPES_MAX];
|
||||
/* input ports */
|
||||
extern cxtype_t *IPORT_CLOSED_NTAG;
|
||||
extern cxtype_t *IPORT_FILE_NTAG;
|
||||
extern cxtype_t *IPORT_BYTEFILE_NTAG;
|
||||
extern cxtype_t *IPORT_STRING_NTAG;
|
||||
extern cxtype_t *IPORT_BYTEVECTOR_NTAG;
|
||||
static cxtype_iport_t *iportvt(obj o) {
|
||||
cxtype_t *pt; if (!isobjptr(o)) return NULL;
|
||||
pt = (cxtype_t*)objptr_from_obj(o)[-1];
|
||||
if (pt != IPORT_CLOSED_NTAG && pt != IPORT_FILE_NTAG &&
|
||||
pt != IPORT_STRING_NTAG && pt != IPORT_BYTEVECTOR_NTAG) return NULL;
|
||||
else return (cxtype_iport_t*)pt; }
|
||||
if (pt >= (cxtype_t*)&cxt_port_types[0] &&
|
||||
pt < (cxtype_t*)&cxt_port_types[PORTTYPES_MAX] &&
|
||||
(((cxtype_port_t*)pt)->spt & SPT_INPUT))
|
||||
return (cxtype_iport_t*)pt; else return NULL; }
|
||||
#define ckiportvt(o) ((cxtype_iport_t*)cxm_cknull(iportvt(o), "iportvt"))
|
||||
#define isiport(o) (iportvt(o) != NULL)
|
||||
#define iportdata(o) ((void*)(*objptr_from_obj(o)))
|
||||
|
@ -434,6 +439,8 @@ static int iportpeekc(obj o) {
|
|||
assert(vt); c = vt->getch(pp); if (c != EOF) vt->ungetch(c, pp); return c;
|
||||
}
|
||||
/* file input ports */
|
||||
typedef struct tifile_tag tifile_t;
|
||||
extern tifile_t *tialloc(FILE *fp);
|
||||
#define mkiport_file(l, fp) hpushptr(fp, IPORT_FILE_NTAG, l)
|
||||
/* string input ports */
|
||||
typedef struct { char *p; void *base; } sifile_t;
|
||||
|
@ -446,14 +453,16 @@ extern bvifile_t *bvialloc(unsigned char *p, unsigned char *e, void *base);
|
|||
/* output ports */
|
||||
extern cxtype_t *OPORT_CLOSED_NTAG;
|
||||
extern cxtype_t *OPORT_FILE_NTAG;
|
||||
extern cxtype_t *OPORT_BYTEFILE_NTAG;
|
||||
extern cxtype_t *OPORT_STRING_NTAG;
|
||||
extern cxtype_t *OPORT_BYTEVECTOR_NTAG;
|
||||
static cxtype_oport_t *oportvt(obj o) {
|
||||
cxtype_t *pt; if (!isobjptr(o)) return NULL;
|
||||
pt = (cxtype_t*)objptr_from_obj(o)[-1];
|
||||
if (pt != OPORT_CLOSED_NTAG && pt != OPORT_FILE_NTAG &&
|
||||
pt != OPORT_STRING_NTAG && pt != OPORT_BYTEVECTOR_NTAG) return NULL;
|
||||
else return (cxtype_oport_t*)pt; }
|
||||
if (pt >= (cxtype_t*)&cxt_port_types[0] &&
|
||||
pt < (cxtype_t*)&cxt_port_types[PORTTYPES_MAX] &&
|
||||
(((cxtype_port_t*)pt)->spt & SPT_OUTPUT))
|
||||
return (cxtype_oport_t*)pt; else return NULL; }
|
||||
#define ckoportvt(o) ((cxtype_oport_t*)cxm_cknull(oportvt(o), "oportvt"))
|
||||
#define isoport(o) (oportvt(o) != NULL)
|
||||
#define oportdata(o) ((void*)(*objptr_from_obj(o)))
|
||||
|
@ -476,7 +485,7 @@ static void oportflush(obj o) {
|
|||
/* file output ports */
|
||||
#define mkoport_file(l, fp) hpushptr(fp, OPORT_FILE_NTAG, l)
|
||||
/* string output ports */
|
||||
typedef struct cbuf_tag { char *buf; char *fill; char *end; size_t off; } cbuf_t;
|
||||
typedef struct cbuf_tag { char *buf; char *fill; char *end; } cbuf_t;
|
||||
extern cbuf_t* newcb(void);
|
||||
extern void freecb(cbuf_t* pcb);
|
||||
extern int cbputc(int c, cbuf_t* pcb);
|
||||
|
@ -484,6 +493,7 @@ extern int cbgetc(cbuf_t* pcb);
|
|||
extern int cbungetc(cbuf_t* pcb, int c);
|
||||
extern size_t cblen(cbuf_t* pcb);
|
||||
extern char* cbdata(cbuf_t* pcb);
|
||||
extern cbuf_t* cbclear(cbuf_t *pcb);
|
||||
#define mkoport_string(l, fp) hpushptr(fp, OPORT_STRING_NTAG, l)
|
||||
/* bytevector output ports */
|
||||
#define mkoport_bytevector(l, fp) hpushptr(fp, OPORT_BYTEVECTOR_NTAG, l)
|
||||
|
@ -498,3 +508,5 @@ extern obj isassoc(obj x, obj l);
|
|||
extern void oportputsimple(obj x, obj p, int disp);
|
||||
extern void oportputcircular(obj x, obj p, int disp);
|
||||
extern void oportputshared(obj x, obj p, int disp);
|
||||
/* S-expression tokenizer */
|
||||
extern int slex(int (*in_getc)(void*), int (*in_ungetc)(int, void*), void *in, cbuf_t *pcb);
|
||||
|
|
537
pre/n.sf
537
pre/n.sf
|
@ -887,17 +887,20 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
; i/o ports
|
||||
|
||||
(%definition "/* input/output ports */")
|
||||
(%definition "typedef enum { CTLOP_RDLN } ctlop_t;")
|
||||
(%definition "typedef struct { /* extends cxtype_t */
|
||||
const char *tname;
|
||||
void (*free)(void*);
|
||||
enum { SPT_CLOSED = 0, SPT_INPUT = 1, SPT_OUTPUT = 2, SPT_IO = 3 } spt;
|
||||
enum { SPT_INPUT = 1, SPT_OUTPUT = 2, SPT_IO = 3, SPT_BINARY = 4 } spt;
|
||||
int (*close)(void*);
|
||||
int (*getch)(void*);
|
||||
int (*ungetch)(int, void*);
|
||||
int (*putch)(int, void*);
|
||||
int (*flush)(void*);
|
||||
int (*ctl)(const char*, void*, ...);
|
||||
int (*ctl)(ctlop_t, void*, ...);
|
||||
} cxtype_port_t, cxtype_iport_t, cxtype_oport_t;")
|
||||
(%definition "#define PORTTYPES_MAX 10")
|
||||
(%definition "extern cxtype_port_t cxt_port_types[PORTTYPES_MAX];")
|
||||
(%localdef "/* shared generic methods */")
|
||||
(%localdef "static void nofree(void *p) {}")
|
||||
(%localdef "static int noclose(void *p) { return 0; }")
|
||||
|
@ -905,21 +908,23 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
(%localdef "static int noungetch(int c) { return c; }")
|
||||
(%localdef "static int noputch(int c, void *p) { return EOF; }")
|
||||
(%localdef "static int noflush(void *p) { return EOF; }")
|
||||
(%localdef "static int noctl(const char *cmd, void *p, ...) { return -1; }")
|
||||
(%localdef "static int noctl(ctlop_t op, void *p, ...) { return -1; }")
|
||||
|
||||
; input ports
|
||||
|
||||
(%definition "/* input ports */")
|
||||
(%definition "extern cxtype_t *IPORT_CLOSED_NTAG;")
|
||||
(%definition "extern cxtype_t *IPORT_FILE_NTAG;")
|
||||
(%definition "extern cxtype_t *IPORT_BYTEFILE_NTAG;")
|
||||
(%definition "extern cxtype_t *IPORT_STRING_NTAG;")
|
||||
(%definition "extern cxtype_t *IPORT_BYTEVECTOR_NTAG;")
|
||||
(%definition "static cxtype_iport_t *iportvt(obj o) {
|
||||
cxtype_t *pt; if (!isobjptr(o)) return NULL;
|
||||
pt = (cxtype_t*)objptr_from_obj(o)[-1];
|
||||
if (pt != IPORT_CLOSED_NTAG && pt != IPORT_FILE_NTAG &&
|
||||
pt != IPORT_STRING_NTAG && pt != IPORT_BYTEVECTOR_NTAG) return NULL;
|
||||
else return (cxtype_iport_t*)pt; }")
|
||||
if (pt >= (cxtype_t*)&cxt_port_types[0] &&
|
||||
pt < (cxtype_t*)&cxt_port_types[PORTTYPES_MAX] &&
|
||||
(((cxtype_port_t*)pt)->spt & SPT_INPUT))
|
||||
return (cxtype_iport_t*)pt; else return NULL; }")
|
||||
(%definition "#define ckiportvt(o) ((cxtype_iport_t*)cxm_cknull(iportvt(o), \"iportvt\"))")
|
||||
(%definition "#define isiport(o) (iportvt(o) != NULL)")
|
||||
(%definition "#define iportdata(o) ((void*)(*objptr_from_obj(o)))")
|
||||
|
@ -936,6 +941,8 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
; file input ports
|
||||
|
||||
(%definition "/* file input ports */")
|
||||
(%definition "typedef struct tifile_tag tifile_t;")
|
||||
(%definition "extern tifile_t *tialloc(FILE *fp);")
|
||||
(%localdef "static void ffree(void *vp) {
|
||||
/* FILE *fp = vp; assert(fp); cannot fclose(fp) here because of FILE reuse! */ }")
|
||||
(%definition "#define mkiport_file(l, fp) hpushptr(fp, IPORT_FILE_NTAG, l)")
|
||||
|
@ -956,6 +963,21 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
int c; assert(fp && fp->p); if (!(c = *(fp->p))) return EOF; ++(fp->p); return c; }")
|
||||
(%localdef "static int siungetch(int c, sifile_t *fp) {
|
||||
assert(fp && fp->p); --(fp->p); assert(c == *(fp->p)); return c; }")
|
||||
(%localdef "static int sictl(ctlop_t op, sifile_t *fp, ...) {
|
||||
if (op == CTLOP_RDLN) {
|
||||
va_list args; int **pd; va_start(args, fp);
|
||||
pd = va_arg(args, int **);
|
||||
if (*(fp->p) == 0) *pd = NULL;
|
||||
else {
|
||||
char *s = strchr(fp->p, '\n');
|
||||
if (s) { *pd = newstringn(fp->p, s-fp->p); fp->p = s+1; }
|
||||
else { *pd = newstring(fp->p); fp->p += strlen(fp->p); }
|
||||
}
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}")
|
||||
(%definition "#define mkiport_string(l, fp) hpushptr(fp, IPORT_STRING_NTAG, l)")
|
||||
|
||||
; bytevector input ports
|
||||
|
@ -982,14 +1004,16 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
(%definition "/* output ports */")
|
||||
(%definition "extern cxtype_t *OPORT_CLOSED_NTAG;")
|
||||
(%definition "extern cxtype_t *OPORT_FILE_NTAG;")
|
||||
(%definition "extern cxtype_t *OPORT_BYTEFILE_NTAG;")
|
||||
(%definition "extern cxtype_t *OPORT_STRING_NTAG;")
|
||||
(%definition "extern cxtype_t *OPORT_BYTEVECTOR_NTAG;")
|
||||
(%definition "static cxtype_oport_t *oportvt(obj o) {
|
||||
cxtype_t *pt; if (!isobjptr(o)) return NULL;
|
||||
pt = (cxtype_t*)objptr_from_obj(o)[-1];
|
||||
if (pt != OPORT_CLOSED_NTAG && pt != OPORT_FILE_NTAG &&
|
||||
pt != OPORT_STRING_NTAG && pt != OPORT_BYTEVECTOR_NTAG) return NULL;
|
||||
else return (cxtype_oport_t*)pt; }")
|
||||
if (pt >= (cxtype_t*)&cxt_port_types[0] &&
|
||||
pt < (cxtype_t*)&cxt_port_types[PORTTYPES_MAX] &&
|
||||
(((cxtype_port_t*)pt)->spt & SPT_OUTPUT))
|
||||
return (cxtype_oport_t*)pt; else return NULL; }")
|
||||
(%definition "#define ckoportvt(o) ((cxtype_oport_t*)cxm_cknull(oportvt(o), \"oportvt\"))")
|
||||
(%definition "#define isoport(o) (oportvt(o) != NULL)")
|
||||
(%definition "#define oportdata(o) ((void*)(*objptr_from_obj(o)))")
|
||||
|
@ -1018,11 +1042,14 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
|
||||
(%definition "/* string output ports */")
|
||||
(%definition "typedef struct cbuf_tag { char *buf; char *fill; char *end; } cbuf_t;")
|
||||
(%definition "extern cbuf_t* newcb(void);")
|
||||
(%localdef "cbuf_t* newcb(void) {
|
||||
cbuf_t* pcb = cxm_cknull(malloc(sizeof(cbuf_t)), \"malloc(cbuf)\");
|
||||
(%definition "extern cbuf_t* newcb(void);")
|
||||
(%localdef "cbuf_t* cbinit(cbuf_t* pcb) {
|
||||
pcb->fill = pcb->buf = cxm_cknull(malloc(64), \"malloc(cbdata)\");
|
||||
pcb->end = pcb->buf + 64; return pcb;
|
||||
}")
|
||||
(%localdef "cbuf_t* newcb(void) {
|
||||
cbuf_t* pcb = cxm_cknull(malloc(sizeof(cbuf_t)), \"malloc(cbuf)\");
|
||||
return cbinit(pcb);
|
||||
}")
|
||||
(%definition "extern void freecb(cbuf_t* pcb);")
|
||||
(%localdef "void freecb(cbuf_t* pcb) { if (pcb) { free(pcb->buf); free(pcb); } }")
|
||||
|
@ -1033,9 +1060,17 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
pcb->buf = cxm_cknull(realloc(pcb->buf, newsz), \"realloc(cbdata)\");
|
||||
pcb->fill = pcb->buf + cnt, pcb->end = pcb->buf + newsz;
|
||||
}")
|
||||
(%definition "extern char* cballoc(cbuf_t* pcb, size_t n);")
|
||||
(%localdef "char* cballoc(cbuf_t* pcb, size_t n) {
|
||||
assert(pcb); /* allow for extra 1 char after n */
|
||||
if (pcb->fill + n+1 > pcb->end) cbgrow(pcb, n+1);
|
||||
pcb->fill += n;
|
||||
return pcb->fill - n;
|
||||
}")
|
||||
(%definition "extern int cbputc(int c, cbuf_t* pcb);")
|
||||
(%localdef "int cbputc(int c, cbuf_t* pcb) {
|
||||
if ((pcb)->fill == (pcb)->end) cbgrow(pcb, 1); *((pcb)->fill)++ = c; return c;
|
||||
if (pcb->fill == pcb->end) cbgrow(pcb, 1);
|
||||
*(pcb->fill)++ = c; return c;
|
||||
}")
|
||||
(%localdef "static int cbflush(cbuf_t* pcb) { return 0; }")
|
||||
(%localdef "static int cbclose(cbuf_t* pcb) { free(pcb->buf); pcb->buf = NULL; return 0; }")
|
||||
|
@ -1045,6 +1080,8 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
(%localdef "char* cbdata(cbuf_t* pcb) {
|
||||
if (pcb->fill == pcb->end) cbgrow(pcb, 1); *(pcb->fill) = 0; return pcb->buf;
|
||||
}")
|
||||
(%definition "extern cbuf_t* cbclear(cbuf_t* pcb);")
|
||||
(%localdef "cbuf_t *cbclear(cbuf_t *pcb) { pcb->fill = pcb->buf; return pcb; }")
|
||||
(%definition "#define mkoport_string(l, fp) hpushptr(fp, OPORT_STRING_NTAG, l)")
|
||||
|
||||
; bytevector output ports
|
||||
|
@ -1052,66 +1089,150 @@ unsigned char* bytevectorref(obj o, int i) {
|
|||
(%definition "/* bytevector output ports */")
|
||||
(%definition "#define mkoport_bytevector(l, fp) hpushptr(fp, OPORT_BYTEVECTOR_NTAG, l)")
|
||||
|
||||
; text input port (uses cbuf)
|
||||
|
||||
(%localdef "buf_t *cbclear(cbuf_t *pcb) { pcb->fill = pcb->buf; return pcb; }
|
||||
|
||||
typedef enum { TIF_NONE = 0, TIF_EOF = 1, TIF_CI = 2 } tiflags_t;
|
||||
struct tifile_tag { cbuf_t cb; char *next; FILE *fp; int lno; tiflags_t flags; };
|
||||
|
||||
tifile_t *tialloc(FILE *fp) {
|
||||
tifile_t *tp = cxm_cknull(malloc(sizeof(tifile_t)), \"malloc(tifile)\");
|
||||
cbinit(&tp->cb); tp->next = tp->cb.buf; *(tp->next) = 0;
|
||||
tp->fp = fp; tp->lno = 0; tp->flags = TIF_NONE;
|
||||
return tp;
|
||||
}
|
||||
|
||||
static void tifree(tifile_t *tp) {
|
||||
assert(tp); cbclose(&tp->cb); ffree(tp->fp); free(tp); }
|
||||
|
||||
static int ticlose(tifile_t *tp) {
|
||||
assert(tp); cbclose(&tp->cb); fclose(tp->fp); return 0; }
|
||||
|
||||
static int tigetch(tifile_t *tp) {
|
||||
int c; retry: c = *(tp->next);
|
||||
if (c != 0) { ++(tp->next); return c; }
|
||||
/* see if we need to return actual 0 or refill the line */
|
||||
if (tp->next < tp->cb.fill) { ++(tp->next); return c; }
|
||||
else if (tp->flags & TIF_EOF || !tp->fp) return EOF;
|
||||
else { /* refill with next line from fp */
|
||||
cbuf_t *pcb = cbclear(&tp->cb); FILE *fp = tp->fp;
|
||||
char *line = fgets(cballoc(pcb, 256), 256, fp);
|
||||
if (!line) { cbclear(pcb); tp->flags |= TIF_EOF; }
|
||||
else { /* manually add the rest of the line */
|
||||
size_t len = strlen(line); pcb->fill = pcb->buf + len;
|
||||
if (len > 0 && line[len-1] != '\n') {
|
||||
do { c = getc(fp); if (c == EOF) break; cbputc(c, pcb); } while (c != '\n');
|
||||
if (c == EOF) tp->flags |= TIF_EOF;
|
||||
}
|
||||
}
|
||||
tp->lno += 1; tp->next = cbdata(pcb); /* 0-term */
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
static int tiungetch(int c, tifile_t *tp) {
|
||||
assert(tp->next > tp->cb.buf && tp->next <= tp->cb.fill);
|
||||
tp->next -= 1; // todo: utf-8
|
||||
return c;
|
||||
}
|
||||
|
||||
static int tictl(ctlop_t op, tifile_t *tp, ...) {
|
||||
if (op == CTLOP_RDLN) {
|
||||
va_list args; int c, n, **pd;
|
||||
va_start(args, tp);
|
||||
pd = va_arg(args, int **);
|
||||
c = tigetch(tp);
|
||||
if (c == EOF) {
|
||||
*pd = NULL;
|
||||
} else {
|
||||
char *s; tiungetch(c, tp);
|
||||
s = tp->next; n = tp->cb.fill - s;
|
||||
if (n > 0 && s[n-1] == '\n') --n;
|
||||
*pd = newstringn(s, n);
|
||||
tp->next = tp->cb.fill;
|
||||
}
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}")
|
||||
|
||||
|
||||
|
||||
; port data, predicates and standard opening/closing convenience ops
|
||||
|
||||
(%localdef "/* port type array */")
|
||||
(%localdef "#define PORTTYPES_MAX 8")
|
||||
(%localdef "static cxtype_port_t cxt_port_types[PORTTYPES_MAX] = {
|
||||
(%localdef "cxtype_port_t cxt_port_types[PORTTYPES_MAX] = {
|
||||
#define IPORT_CLOSED_PTINDEX 0
|
||||
{ \"closed-input-port\", (void (*)(void*))nofree,
|
||||
SPT_CLOSED, (int (*)(void*))noclose,
|
||||
SPT_INPUT, (int (*)(void*))noclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define IPORT_FILE_PTINDEX 1
|
||||
{ \"file-input-port\", ffree,
|
||||
SPT_INPUT, (int (*)(void*))fclose,
|
||||
{ \"file-input-port\", (void (*)(void*))tifree,
|
||||
SPT_INPUT, (int (*)(void*))ticlose,
|
||||
(int (*)(void*))tigetch, (int (*)(int, void*))tiungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(ctlop_t, void *, ...))tictl },
|
||||
#define IPORT_BYTEFILE_PTINDEX 2
|
||||
{ \"binary-file-input-port\", ffree,
|
||||
SPT_INPUT|SPT_BINARY, (int (*)(void*))fclose,
|
||||
(int (*)(void*))(fgetc), (int (*)(int, void*))(ungetc),
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define IPORT_STRING_PTINDEX 2
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define IPORT_STRING_PTINDEX 3
|
||||
{ \"string-input-port\", (void (*)(void*))sifree,
|
||||
SPT_INPUT, (int (*)(void*))siclose,
|
||||
(int (*)(void*))sigetch, (int (*)(int, void*))siungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define IPORT_BYTEVECTOR_PTINDEX 3
|
||||
(int (*)(ctlop_t, void *, ...))sictl },
|
||||
#define IPORT_BYTEVECTOR_PTINDEX 4
|
||||
{ \"bytevector-input-port\", (void (*)(void*))bvifree,
|
||||
SPT_INPUT, (int (*)(void*))bviclose,
|
||||
SPT_INPUT|SPT_BINARY, (int (*)(void*))bviclose,
|
||||
(int (*)(void*))bvigetch, (int (*)(int, void*))bviungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_CLOSED_PTINDEX 4
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_CLOSED_PTINDEX 5
|
||||
{ \"closed-output-port\", (void (*)(void*))nofree,
|
||||
SPT_OUTPUT, (int (*)(void*))noclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))noputch, (int (*)(void*))noflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_FILE_PTINDEX 5
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_FILE_PTINDEX 6
|
||||
{ \"file-output-port\", ffree,
|
||||
SPT_OUTPUT, (int (*)(void*))fclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))(fputc), (int (*)(void*))fflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_STRING_PTINDEX 6
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_BYTEFILE_PTINDEX 7
|
||||
{ \"binary-file-output-port\", ffree,
|
||||
SPT_OUTPUT|SPT_BINARY, (int (*)(void*))fclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))(fputc), (int (*)(void*))fflush,
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_STRING_PTINDEX 8
|
||||
{ \"string-output-port\", (void (*)(void*))freecb,
|
||||
SPT_OUTPUT, (int (*)(void*))cbclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))cbputc, (int (*)(void*))cbflush,
|
||||
(int (*)(const char *, void *, ...))noctl },
|
||||
#define OPORT_BYTEVECTOR_PTINDEX 7
|
||||
(int (*)(ctlop_t, void *, ...))noctl },
|
||||
#define OPORT_BYTEVECTOR_PTINDEX 9
|
||||
{ \"bytevector-output-port\", (void (*)(void*))freecb,
|
||||
SPT_OUTPUT, (int (*)(void*))cbclose,
|
||||
SPT_OUTPUT|SPT_BINARY, (int (*)(void*))cbclose,
|
||||
(int (*)(void*))nogetch, (int (*)(int, void*))noungetch,
|
||||
(int (*)(int, void*))cbputc, (int (*)(void*))cbflush,
|
||||
(int (*)(const char *, void *, ...))noctl }
|
||||
(int (*)(ctlop_t, void *, ...))noctl }
|
||||
};")
|
||||
(%localdef "cxtype_t *IPORT_CLOSED_NTAG = (cxtype_t *)&cxt_port_types[IPORT_CLOSED_PTINDEX];")
|
||||
(%localdef "cxtype_t *IPORT_FILE_NTAG = (cxtype_t *)&cxt_port_types[IPORT_FILE_PTINDEX];")
|
||||
(%localdef "cxtype_t *IPORT_BYTEFILE_NTAG = (cxtype_t *)&cxt_port_types[IPORT_BYTEFILE_PTINDEX];")
|
||||
(%localdef "cxtype_t *IPORT_STRING_NTAG = (cxtype_t *)&cxt_port_types[IPORT_STRING_PTINDEX];")
|
||||
(%localdef "cxtype_t *IPORT_BYTEVECTOR_NTAG = (cxtype_t *)&cxt_port_types[IPORT_BYTEVECTOR_PTINDEX];")
|
||||
(%localdef "cxtype_t *OPORT_CLOSED_NTAG = (cxtype_t *)&cxt_port_types[OPORT_CLOSED_PTINDEX];")
|
||||
(%localdef "cxtype_t *OPORT_FILE_NTAG = (cxtype_t *)&cxt_port_types[OPORT_FILE_PTINDEX];")
|
||||
(%localdef "cxtype_t *OPORT_BYTEFILE_NTAG = (cxtype_t *)&cxt_port_types[OPORT_BYTEFILE_PTINDEX];")
|
||||
(%localdef "cxtype_t *OPORT_STRING_NTAG = (cxtype_t *)&cxt_port_types[OPORT_STRING_PTINDEX];")
|
||||
(%localdef "cxtype_t *OPORT_BYTEVECTOR_NTAG = (cxtype_t *)&cxt_port_types[OPORT_BYTEVECTOR_PTINDEX];")
|
||||
|
||||
|
@ -1365,10 +1486,23 @@ static void wrs(char *s, wenv_t *e) {
|
|||
assert(vt); while (*s) vt->putch(*s++, pp);
|
||||
}
|
||||
static int cleansymname(char *s) {
|
||||
char *inits = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$%&*/:<=>?@^_~\";
|
||||
char *subss = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!$%&*/:<=>?@^_~0123456789.@+-\";
|
||||
if (s[0] == 0 || s[strspn(s, subss)] != 0) return 0; else if (strchr(inits, s[0])) return 1;
|
||||
else if (s[0] == '+' || s[0] == '-') return s[1] == 0 || (s[1] == '.' && s[2] && !isdigit(s[2])) || !isdigit(s[1]);
|
||||
static char inisub_map[256] = { /* ini: [a-zA-Z!$%&*:/<=>?@^_~] sub: ini + [0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
char *p = s; while (*p) if (inisub_map[*p++ & 0xFF] == 0) return 0; if (!s[0]) return 0;
|
||||
if (inisub_map[s[0] & 0xFF] == 1) return 1;
|
||||
if (s[0] == '+' || s[0] == '-') {
|
||||
if (strcmp_ci(s+1, \"inf.0\") == 0 || strcmp_ci(s+1, \"nan.0\") == 0) return 0;
|
||||
if ((s[1] == 'i' || s[1] == 'I') && s[2] == 0) return 0;
|
||||
return s[1] == 0 || (s[1] == '.' && s[2] && !isdigit(s[2])) || (s[1] != '.' && !isdigit(s[1]));
|
||||
}
|
||||
else return s[0] == '.' && s[1] && !isdigit(s[1]);
|
||||
}
|
||||
static void wrdatum(obj o, wenv_t *e) {
|
||||
|
@ -1498,6 +1632,8 @@ static void wrdatum(obj o, wenv_t *e) {
|
|||
extern void oportputsimple(obj x, obj p, int disp);
|
||||
extern void oportputcircular(obj x, obj p, int disp);
|
||||
extern void oportputshared(obj x, obj p, int disp);")
|
||||
(%definition "/* S-expression tokenizer */
|
||||
extern int slex(int (*in_getc)(void*), int (*in_ungetc)(int, void*), void *in, cbuf_t *pcb);")
|
||||
|
||||
(%localdef "/* S-expression writers */
|
||||
void oportputsimple(obj x, obj p, int disp) {
|
||||
|
@ -1531,7 +1667,7 @@ void oportputshared(obj x, obj p, int disp) {
|
|||
extern int is_tty_port(obj o)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
if ((cxtype_t*)iportvt(o) == IPORT_FILE_NTAG) fp = (FILE*)iportdata(o);
|
||||
if ((cxtype_t*)iportvt(o) == IPORT_FILE_NTAG) fp = ((tifile_t*)iportdata(o))->fp;
|
||||
else if ((cxtype_t*)oportvt(o) == OPORT_FILE_NTAG) fp = (FILE*)oportdata(o);
|
||||
if (!fp) return 0;
|
||||
return isatty(fileno(fp));
|
||||
|
@ -1539,8 +1675,10 @@ extern int is_tty_port(obj o)
|
|||
|
||||
#ifdef WIN32
|
||||
int dirsep = '\\\\';
|
||||
int pathsep = ';';
|
||||
#else
|
||||
int dirsep = '/';
|
||||
int pathsep = ':';
|
||||
#endif
|
||||
|
||||
#ifdef LIBPATH
|
||||
|
@ -1596,4 +1734,325 @@ extern int set_cwd(char *cwd)
|
|||
{
|
||||
return chdir(cwd);
|
||||
}
|
||||
|
||||
define TT_FALSE 'f'
|
||||
#define TT_TRUE 't'
|
||||
#define TT_NUMBER 'n'
|
||||
#define TT_CHAR 'c'
|
||||
#define TT_STRING 's'
|
||||
#define TT_SYMBOL 'y'
|
||||
#define TT_OPENLIST 'l'
|
||||
#define TT_OPENVEC 'v'
|
||||
#define TT_OPENU8VEC 'u'
|
||||
#define TT_CLOSE 'r'
|
||||
#define TT_OPENLIST2 'b'
|
||||
#define TT_CLOSE2 'k'
|
||||
#define TT_QUOTE '\\''
|
||||
#define TT_QQUOTE '`'
|
||||
#define TT_UNQUOTE ','
|
||||
#define TT_UNQSPL '@'
|
||||
#define TT_DOT '.'
|
||||
#define TT_BOX '&'
|
||||
#define TT_HDEF '='
|
||||
#define TT_HREF '#'
|
||||
#define TT_HSEMI ';'
|
||||
#define TT_SHEBANG '!'
|
||||
#define TT_SHEBANG_FC 'F'
|
||||
#define TT_SHEBANG_NF 'N'
|
||||
#define TT_ERR 0
|
||||
#define TT_EOF -1
|
||||
|
||||
#if 1
|
||||
static char num_map[256] = { /* [#A-Za-z/0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#define is_num(c) (num_map[(c) & 0xFF]) /* NB: eof at num_map[255] */
|
||||
#else
|
||||
static int is_num(int c)
|
||||
{ /* this covers all initials and constituents of prefixed numbers */
|
||||
char *s = \"#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/0123456789+-.@\";
|
||||
return c != EOF && strchr(s, c) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
static char numsym_map[256] = { /* [A-Za-z!$%&*:/<=>?^_~0123456789.@+-] */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#define is_numsym(c) (numsym_map[(c) & 0xFF]) /* NB: eof at numsym_map[255] */
|
||||
#else
|
||||
static int is_numsym(int c)
|
||||
{ /* this covers all initials and constituents of plain symbols and nonprefixed decimals */
|
||||
char *s = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*/:<=>?^_~0123456789+-.@\";
|
||||
return c != EOF && strchr(s, c) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int is_delimiter(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case '\\t': case '\\r': case '\\n': case ' ':
|
||||
case '(': case ')': case '[': case ']':
|
||||
case '|': case '\\\"': case ';': case EOF:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lex_1esc(int c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'a': return '\\a';
|
||||
case 'b': return '\\b';
|
||||
case 't': return '\\t';
|
||||
case 'n': return '\\n';
|
||||
case 'r': return '\\r';
|
||||
case '|': return '|';
|
||||
case '\\\"': return '\\\"';
|
||||
case '\\\\': return '\\\\';
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int lex_xesc(int c, int xc)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (xc << 4) + c - '0';
|
||||
if (c >= 'A' && c <= 'F') return (xc << 4) + 10 + c - 'A';
|
||||
if (c >= 'a' && c <= 'f') return (xc << 4) + 10 + c - 'a';
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* slex: splits input into tokens delivered via char buf */
|
||||
int slex(int (*in_getc)(void*), int (*in_ungetc)(int, void*), void *in, cbuf_t *pcb)
|
||||
{
|
||||
int c, xc;
|
||||
next: cbclear(pcb);
|
||||
switch (c = in_getc(in)) {
|
||||
case EOF: return TT_EOF;
|
||||
case ',': goto after_comma;
|
||||
case '`': return TT_QQUOTE;
|
||||
case '\\'': return TT_QUOTE;
|
||||
case ']': return TT_CLOSE2;
|
||||
case '[': return TT_OPENLIST2;
|
||||
case ')': return TT_CLOSE;
|
||||
case '(': return TT_OPENLIST;
|
||||
case ';': goto in_linecomm;
|
||||
case '|': goto in_barsym;
|
||||
case '\\\"': goto in_string;
|
||||
case '#': cbputc(c, pcb); goto after_hash;
|
||||
case '.': cbputc(c, pcb); goto after_dot;
|
||||
default:
|
||||
if (is_numsym(c)) goto in_numsym;
|
||||
if ((c >= '\\t' && c <= '\\n') || (c >= '\\f' && c <= '\\r') || c == ' ') goto in_whitespace;
|
||||
in_ungetc(c, in); goto err;
|
||||
}
|
||||
in_whitespace:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_EOF;
|
||||
if ((c >= '\\t' && c <= '\\n') || (c >= '\\f' && c <= '\\r') || c == ' ') goto in_whitespace;
|
||||
in_ungetc(c, in); goto next;
|
||||
in_linecomm:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_EOF;
|
||||
if (c != '\\n') goto in_linecomm;
|
||||
goto next;
|
||||
in_numsym:
|
||||
while (is_numsym(c)) { cbputc(c, pcb); c = in_getc(in); }
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
if (cleansymname(cbdata(pcb))) return TT_SYMBOL;
|
||||
return TT_NUMBER;
|
||||
after_dot:
|
||||
c = in_getc(in); if (is_numsym(c)) goto in_numsym;
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
return TT_DOT;
|
||||
after_hash:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '(') return TT_OPENVEC;
|
||||
if (c == '\\\\') { cbclear(pcb); goto in_char; }
|
||||
if (c == '|') { // handcoded
|
||||
int level = 1;
|
||||
normal:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '#': goto after_hashc;
|
||||
case '|': goto after_barc;
|
||||
default: goto normal;
|
||||
}
|
||||
after_hashc:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '#': goto after_hashc;
|
||||
case '|': level++;
|
||||
default: goto normal;
|
||||
}
|
||||
after_barc:
|
||||
switch (in_getc(in)) {
|
||||
case EOF: goto err;
|
||||
case '|': goto after_barc;
|
||||
case '#': if (!--level) goto next;
|
||||
default: goto normal;
|
||||
}
|
||||
}
|
||||
if (c == '!') { cbclear(pcb); goto after_shebang; }
|
||||
if (c == '&') return TT_BOX;
|
||||
if (c == 'u' || c == 'U') { cbputc(tolower(c), cbclear(pcb)); goto after_hashu; }
|
||||
if (c >= '0' && c <= '9') { cbputc(c, cbclear(pcb)); goto in_hashnum; }
|
||||
if (c == 'B' || (c >= 'D' && c <= 'E') || c == 'I' || c == 'O' || c == 'X' ||
|
||||
c == 'b' || (c >= 'd' && c <= 'e') || c == 'i' || c == 'o' || c == 'x')
|
||||
{ cbputc(tolower(c), pcb); goto in_hashradixie; }
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(tolower(c), cbclear(pcb)); goto in_hashname; }
|
||||
if (c == ';') { cbclear(pcb); return TT_HSEMI; } // todo: skip S-exp
|
||||
in_ungetc(c, in); goto err;
|
||||
after_comma:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) return TT_UNQUOTE;
|
||||
if (c == '@') return TT_UNQSPL;
|
||||
in_ungetc(c, in); return TT_UNQUOTE;
|
||||
in_char:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
if (c == 'x' || c == 'X') goto in_char_xesc;
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) goto in_char_name;
|
||||
cbputc(c, pcb); // todo: parse utf-8
|
||||
c = in_getc(in); if (c != EOF) in_ungetc(c, in);
|
||||
if (!is_delimiter(c)) goto err;
|
||||
return TT_CHAR;
|
||||
in_char_name:
|
||||
while ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(c, pcb); c = in_getc(in); }
|
||||
if (cblen(pcb) > 1) {
|
||||
char *s = cbdata(pcb); int x = EOF;
|
||||
if (0 == strcmp(s, \"null\")) x = '\\0';
|
||||
else if (0 == strcmp(s, \"alarm\")) x = '\\a';
|
||||
else if (0 == strcmp(s, \"backspace\")) x = '\\b';
|
||||
else if (0 == strcmp(s, \"delete\")) x = '\\x7F';
|
||||
else if (0 == strcmp(s, \"escape\")) x = '\\x1B';
|
||||
else if (0 == strcmp(s, \"newline\")) x = '\\n';
|
||||
else if (0 == strcmp(s, \"return\")) x = '\\r';
|
||||
else if (0 == strcmp(s, \"space\")) x = ' ';
|
||||
else if (0 == strcmp(s, \"tab\")) x = '\\t';
|
||||
else if (0 == strcmp(s, \"vtab\")) x = '\\v'; //++
|
||||
else if (0 == strcmp(s, \"page\")) x = '\\f'; //++
|
||||
else if (0 == strcmp(s, \"linefeed\")) x = '\\n'; //++
|
||||
if (x == EOF) goto err;
|
||||
cbputc(x, cbclear(pcb));
|
||||
}
|
||||
if (c != EOF) in_ungetc(c, in);
|
||||
if (!is_delimiter(c)) goto err;
|
||||
return TT_CHAR;
|
||||
in_char_xesc:
|
||||
xc = c; c = in_getc(in);
|
||||
if (is_delimiter(c)) { if (c != EOF) in_ungetc(c, in); cbputc(xc, pcb); return TT_CHAR; }
|
||||
else xc = 0;
|
||||
while (!is_delimiter(c) && (xc = lex_xesc(c, xc)) != EOF) c = in_getc(in);
|
||||
if (!is_delimiter(c) || xc == EOF) goto err;
|
||||
if (c != EOF) in_ungetc(c, in); cbputc(xc, pcb); return TT_CHAR; // todo: cbput8c
|
||||
in_barsym:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
else if (c == '|') return TT_SYMBOL;
|
||||
else if (c == '\\\\') goto in_barsym_esc;
|
||||
cbputc(c, pcb); goto in_barsym; // todo: parse utf-8
|
||||
in_barsym_esc:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == 'x' || c == 'X') goto in_barsym_xesc;
|
||||
xc = lex_1esc(c); if (xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_barsym; // todo: cbput8c
|
||||
in_barsym_xesc:
|
||||
xc = 0; do c = in_getc(in);
|
||||
while (c != ';' && (xc = lex_xesc(c, xc)) != EOF);
|
||||
if (c != ';' || xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_barsym; // todo: cbput8c
|
||||
in_string:
|
||||
c = in_getc(in); if (c == EOF) goto eoferr;
|
||||
else if (c == '\\\"') return TT_STRING;
|
||||
else if (c == '\\\\') goto in_str_esc;
|
||||
cbputc(c, pcb); goto in_string; // todo: parse utf-8
|
||||
in_str_esc:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == 'x' || c == 'X') goto in_str_xesc;
|
||||
if (c == '\\t' || c == ' ' || c == '\\r' || c == '\\n') goto in_str_sesc;
|
||||
xc = lex_1esc(c); if (xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_string; // todo: cbput8c
|
||||
in_str_sesc:
|
||||
while (c == '\\t' || c == ' ' || c == '\\r') c = in_getc(in);
|
||||
if (c != '\\n') goto err;
|
||||
do c = in_getc(in); while (c == '\\t' || c == ' ');
|
||||
if (c == EOF) goto err;
|
||||
in_ungetc(c, in); goto in_string;
|
||||
in_str_xesc:
|
||||
xc = 0; do c = in_getc(in);
|
||||
while (c != ';' && (xc = lex_xesc(c, xc)) != EOF);
|
||||
if (c != ';' || xc == EOF) goto err;
|
||||
cbputc(xc, pcb); goto in_string; // todo: cbput8c
|
||||
in_hashradixie:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
while (is_num(c)) { cbputc(tolower(c), pcb); c = in_getc(in); }
|
||||
if (!is_delimiter(c)) goto err; if (c != EOF) in_ungetc(c, in);
|
||||
return TT_NUMBER;
|
||||
in_hashname:
|
||||
c = in_getc(in);
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(tolower(c), pcb); goto in_hashname; }
|
||||
if (is_delimiter(c)) {
|
||||
char *s = cbdata(pcb); if (c != EOF) in_ungetc(c, in);
|
||||
if (0 == strcmp(s, \"t\")) return TT_TRUE;
|
||||
else if (0 == strcmp(s, \"true\")) return TT_TRUE;
|
||||
else if (0 == strcmp(s, \"f\")) return TT_FALSE;
|
||||
else if (0 == strcmp(s, \"false\")) return TT_FALSE;
|
||||
}
|
||||
goto err;
|
||||
in_hashnum:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '#') return TT_HREF;
|
||||
if (c == '=') return TT_HDEF;
|
||||
if (c >= '0' && c <= '9') { cbputc(c, pcb); goto in_hashnum; }
|
||||
in_ungetc(c, in); goto err;
|
||||
after_hashu:
|
||||
c = in_getc(in);
|
||||
if (c == '8') { cbclear(pcb); goto after_hashu8; }
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { cbputc(tolower(c), pcb); goto in_hashname; }
|
||||
in_ungetc(c, in); goto err;
|
||||
after_hashu8:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == '(') return TT_OPENU8VEC;
|
||||
in_ungetc(c, in); goto err;
|
||||
after_shebang:
|
||||
c = in_getc(in); if (c == EOF) goto err;
|
||||
if (c == ' ' || c == '\\t') goto in_shebang_line;
|
||||
else if (c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(c, pcb); goto in_shebang_name; }
|
||||
in_ungetc(c, in); goto err;
|
||||
in_shebang_line:
|
||||
while (c == ' ' || c == '\\t') c = in_getc(in);
|
||||
while (c != EOF && c != '\\n') { cbputc(c, pcb); c = in_getc(in); }
|
||||
while (pcb->fill > pcb->buf && (pcb->fill[-1] == ' ' || pcb->fill[-1] == '\\t')) pcb->fill -= 1;
|
||||
return TT_SHEBANG;
|
||||
in_shebang_name:
|
||||
c = in_getc(in);
|
||||
if (c == EOF) goto in_shebang_pre;
|
||||
else if (c == '-' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z'))
|
||||
{ cbputc(c, pcb); goto in_shebang_name; }
|
||||
else { in_ungetc(c, in); goto in_shebang_pre; }
|
||||
in_shebang_pre: {
|
||||
char *s = cbdata(pcb);
|
||||
if (strcmp_ci(s, \"fold-case\") == 0) return TT_SHEBANG_FC;
|
||||
if (strcmp_ci(s, \"no-fold-case\") == 0) return TT_SHEBANG_NF;
|
||||
return TT_SHEBANG;
|
||||
}
|
||||
err:
|
||||
eoferr:
|
||||
return TT_ERR;
|
||||
}
|
||||
")
|
||||
|
|
548
pre/s.scm
548
pre/s.scm
|
@ -274,8 +274,8 @@
|
|||
; check that now relies on block tag being a non-immediate object, so we'll better put
|
||||
; some pseudo-unique immediate object here -- and we don't have to be fast doing that
|
||||
(let loop ([fl (cons name fields)] [sl '("rtd://")])
|
||||
; NB: can't do (apply string-append ..) -- they are defined w/cover syntax below!
|
||||
(cond [(null? fl) (string->symbol (apply-to-list %string-append (reverse sl)))]
|
||||
; NB: can't do (apply string-append ..) -- apply is defined w/cover syntax below!
|
||||
(cond [(null? fl) (string->symbol (apply-to-list string-append (reverse sl)))]
|
||||
[(null? (cdr fl)) (loop (cdr fl) (cons (symbol->string (car fl)) sl))]
|
||||
[else (loop (cdr fl) (cons ":" (cons (symbol->string (car fl)) sl)))])))
|
||||
|
||||
|
@ -743,7 +743,7 @@
|
|||
(string->symbol (string-foldcase s)))
|
||||
|
||||
(define (symbol-append . syms) ; +
|
||||
(string->symbol (apply-to-list %string-append (%map1 symbol->string syms))))
|
||||
(string->symbol (apply-to-list string-append (%map1 symbol->string syms))))
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------------------------
|
||||
|
@ -792,7 +792,7 @@
|
|||
; (string-set! x i v)
|
||||
; (list->string l)
|
||||
; (%string->list1 s) +
|
||||
; (string-cat s1 s2) +
|
||||
; (string-append s ...)
|
||||
; (substring s from to)
|
||||
; (string-position s c) +
|
||||
; (string-cmp s1 s2) +
|
||||
|
@ -873,29 +873,6 @@
|
|||
[(str start) (substring->vector str start (string-length str))]
|
||||
[(str start end) (substring->vector str start end)]))
|
||||
|
||||
(define (strings-sum-length strs)
|
||||
(let loop ([strs strs] [l 0])
|
||||
(if (null? strs) l (loop (cdr strs) (fx+ l (string-length (car strs)))))))
|
||||
|
||||
(define (strings-copy-into! to strs)
|
||||
(let loop ([strs strs] [i 0])
|
||||
(if (null? strs)
|
||||
to
|
||||
(let ([str (car strs)] [strs (cdr strs)])
|
||||
(let ([len (string-length str)])
|
||||
(substring-copy! to i str 0 len)
|
||||
(loop strs (fx+ i len)))))))
|
||||
|
||||
(define (%string-append . strs)
|
||||
(strings-copy-into! (make-string (strings-sum-length strs)) strs))
|
||||
|
||||
(define-syntax string-append
|
||||
(syntax-rules ()
|
||||
[(_) ""] [(_ x) (%cks x)]
|
||||
[(_ x y) (string-cat x y)]
|
||||
[(_ . r) (%string-append . r)]
|
||||
[_ %string-append]))
|
||||
|
||||
(define (string-trim-whitespace s) ; +
|
||||
(let floop ([from 0] [len (string-length s)])
|
||||
(if (and (< from len) (char-whitespace? (string-ref s from)))
|
||||
|
@ -922,7 +899,7 @@
|
|||
; (vector-set! v i x)
|
||||
; (%vector->list1 v) +
|
||||
; (list->vector l)
|
||||
; (vector-cat v1 v2) +
|
||||
; (vector-append v ...)
|
||||
|
||||
(define (subvector->list vec start end)
|
||||
(let loop ([i (fx- end 1)] [l '()])
|
||||
|
@ -991,29 +968,6 @@
|
|||
[(vec start) (subvector->string vec start (vector-length vec))]
|
||||
[(vec start end) (subvector->string vec start end)]))
|
||||
|
||||
(define (vectors-sum-length vecs)
|
||||
(let loop ([vecs vecs] [l 0])
|
||||
(if (null? vecs) l (loop (cdr vecs) (fx+ l (vector-length (car vecs)))))))
|
||||
|
||||
(define (vectors-copy-into! to vecs)
|
||||
(let loop ([vecs vecs] [i 0])
|
||||
(if (null? vecs)
|
||||
to
|
||||
(let ([vec (car vecs)] [vecs (cdr vecs)])
|
||||
(let ([len (vector-length vec)])
|
||||
(subvector-copy! to i vec 0 len)
|
||||
(loop vecs (fx+ i len)))))))
|
||||
|
||||
(define (%vector-append . vecs)
|
||||
(vectors-copy-into! (make-vector (vectors-sum-length vecs)) vecs))
|
||||
|
||||
(define-syntax vector-append
|
||||
(syntax-rules ()
|
||||
[(_) '#()] [(_ x) (%ckv x)]
|
||||
[(_ x y) (vector-cat x y)]
|
||||
[(_ . r) (%vector-append . r)]
|
||||
[_ %vector-append]))
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------------------------
|
||||
; Bytevectors
|
||||
|
@ -1027,6 +981,7 @@
|
|||
; (bytevector-length b)
|
||||
; (bytevector-u8-ref b i)
|
||||
; (bytevector-u8-set! b i u8)
|
||||
; (bytevector-append b ...)
|
||||
; (list->bytevector l) +
|
||||
; (subbytevector b from to) +
|
||||
; (bytevector=? b1 b2 b ...)
|
||||
|
@ -1072,21 +1027,6 @@
|
|||
[(bvec b start) (subbytevector-fill! bvec b start (bytevector-length bvec))]
|
||||
[(bvec b start end) (subbytevector-fill! bvec b start end)]))
|
||||
|
||||
(define (%bytevectors-sum-length bvecs)
|
||||
(let loop ([bvecs bvecs] [l 0])
|
||||
(if (null? bvecs) l (loop (cdr bvecs) (fx+ l (bytevector-length (car bvecs)))))))
|
||||
|
||||
(define (%bytevectors-copy-into! to bvecs)
|
||||
(let loop ([bvecs bvecs] [i 0])
|
||||
(if (null? bvecs) to
|
||||
(let ([bvec (car bvecs)] [bvecs (cdr bvecs)])
|
||||
(let ([len (bytevector-length bvec)])
|
||||
(subbytevector-copy! to i bvec 0 len)
|
||||
(loop bvecs (fx+ i len)))))))
|
||||
|
||||
(define (bytevector-append . bvecs)
|
||||
(%bytevectors-copy-into! (make-bytevector (%bytevectors-sum-length bvecs)) bvecs))
|
||||
|
||||
(define (subutf8->string vec start end)
|
||||
(let ([p (open-output-string)])
|
||||
(write-subbytevector vec start end p)
|
||||
|
@ -1526,23 +1466,10 @@
|
|||
; (read-u8 (p (current-input-port)))
|
||||
; (peek-u8 (p (current-input-port)))
|
||||
; (u8-ready? (p (current-input-port)))
|
||||
; (read-line (p (current-input-port)))
|
||||
; (eof-object? x)
|
||||
; (eof-object)
|
||||
|
||||
(define (read-line . ?p)
|
||||
(let ([p (if (null? ?p) (current-input-port) (car ?p))]
|
||||
[op (open-output-string)])
|
||||
(let loop ([read-nothing? #t])
|
||||
(let ([c (read-char p)])
|
||||
(cond [(or (eof-object? c) (char=? c #\newline))
|
||||
(if (and (eof-object? c) read-nothing?)
|
||||
c
|
||||
(let ([s (get-output-string op)])
|
||||
(close-output-port op)
|
||||
s))]
|
||||
[(char=? c #\return) (loop #f)]
|
||||
[else (write-char c op) (loop #f)])))))
|
||||
|
||||
(define (read-substring! str start end p)
|
||||
(let loop ([i start])
|
||||
(if (fx>=? i end) (fx- i start)
|
||||
|
@ -1593,352 +1520,121 @@
|
|||
[(k) (read-subbytevector k (current-input-port))]
|
||||
[(k p) (read-subbytevector k p)]))
|
||||
|
||||
(define (%read port simple? ci?)
|
||||
(define-syntax r-error
|
||||
(syntax-rules () [(_ p msg a ...) (read-error msg a ... 'port: p)]))
|
||||
(define fold-case? (or ci? (port-fold-case? port)))
|
||||
(define shared '())
|
||||
(define (make-shared-ref loc) (lambda () (unbox loc)))
|
||||
(define (shared-ref? form) (procedure? form))
|
||||
(define (patch-ref! form) (if (procedure? form) (patch-ref! (form)) form))
|
||||
(define (patch-shared! form)
|
||||
(cond [(pair? form)
|
||||
(if (procedure? (car form))
|
||||
(set-car! form (patch-ref! (car form)))
|
||||
(patch-shared! (car form)))
|
||||
(if (procedure? (cdr form))
|
||||
(set-cdr! form (patch-ref! (cdr form)))
|
||||
(patch-shared! (cdr form)))]
|
||||
[(vector? form)
|
||||
(let loop ([i 0])
|
||||
(when (fx<? i (vector-length form))
|
||||
(let ([fi (vector-ref form i)])
|
||||
(if (procedure? fi)
|
||||
(vector-set! form i (patch-ref! fi))
|
||||
(patch-shared! fi)))
|
||||
(loop (fx+ i 1))))]
|
||||
[(box? form)
|
||||
(if (procedure? (unbox form))
|
||||
(set-box! form (patch-shared! (unbox form)))
|
||||
(patch-shared! (unbox form)))]))
|
||||
(define (patch-shared form) (patch-shared! form) form)
|
||||
|
||||
(define reader-token-marker #f)
|
||||
(define close-paren #f)
|
||||
(define close-bracket #f)
|
||||
(define dot #f)
|
||||
(define () ; idless
|
||||
(let ([rtm (list 'reader-token)])
|
||||
(set! reader-token-marker rtm)
|
||||
(set! close-paren (cons rtm "right parenthesis"))
|
||||
(set! close-bracket (cons rtm "right bracket"))
|
||||
(set! dot (cons rtm "\" . \""))))
|
||||
|
||||
(define (reader-token? form)
|
||||
(and (pair? form) (eq? (car form) reader-token-marker)))
|
||||
|
||||
(define (char-symbolic? c)
|
||||
(string-position c
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!$%&*/:<=>?^_~0123456789+-.@"))
|
||||
|
||||
(define (char-hex-digit? c)
|
||||
(let ([scalar-value (char->integer c)])
|
||||
(or (and (>= scalar-value 48) (<= scalar-value 57))
|
||||
(and (>= scalar-value 65) (<= scalar-value 70))
|
||||
(and (>= scalar-value 97) (<= scalar-value 102)))))
|
||||
|
||||
(define (char-delimiter? c)
|
||||
(or (char-whitespace? c)
|
||||
(char=? c #\)) (char=? c #\()
|
||||
(char=? c #\]) (char=? c #\[)
|
||||
(char=? c #\") (char=? c #\;)))
|
||||
|
||||
(define (sub-read-carefully p)
|
||||
(let ([form (sub-read p)])
|
||||
(cond [(eof-object? form)
|
||||
(r-error p "unexpected end of file")]
|
||||
[(reader-token? form)
|
||||
(r-error p "unexpected token:" (cdr form))]
|
||||
[else form])))
|
||||
|
||||
(define (sub-read-shebang p)
|
||||
(if (eqv? (peek-char p) #\space)
|
||||
(string->symbol (string-trim-whitespace (read-line p)))
|
||||
(sub-read-carefully p)))
|
||||
|
||||
(define (sub-read p)
|
||||
(let ([c (read-char p)])
|
||||
(cond [(eof-object? c) c]
|
||||
[(char-whitespace? c) (sub-read p)]
|
||||
[(char=? c #\() (sub-read-list c p close-paren #t)]
|
||||
[(char=? c #\)) close-paren]
|
||||
[(char=? c #\[) (sub-read-list c p close-bracket #t)]
|
||||
[(char=? c #\]) close-bracket]
|
||||
[(char=? c #\') (list 'quote (sub-read-carefully p))]
|
||||
[(char=? c #\`) (list 'quasiquote (sub-read-carefully p))]
|
||||
[(char-symbolic? c) (sub-read-number-or-symbol c p)]
|
||||
[(char=? c #\;)
|
||||
(let loop ([c (read-char p)])
|
||||
(or (eof-object? c) (char=? c #\newline)
|
||||
(loop (read-char p))))
|
||||
(sub-read p)]
|
||||
[(char=? c #\,)
|
||||
(let ([next (peek-char p)])
|
||||
(cond [(eof-object? next)
|
||||
(r-error p "end of file after ,")]
|
||||
[(char=? next #\@)
|
||||
(read-char p)
|
||||
(list 'unquote-splicing (sub-read-carefully p))]
|
||||
[else (list 'unquote (sub-read-carefully p))]))]
|
||||
[(char=? c #\")
|
||||
(let loop ([l '()])
|
||||
(let ([c (read-char p)])
|
||||
(cond [(eof-object? c)
|
||||
(r-error p "end of file within a string")]
|
||||
[(char=? c #\\)
|
||||
(let ([e (sub-read-strsym-char-escape p 'string)])
|
||||
(loop (if e (cons e l) l)))]
|
||||
[(char=? c #\") (list->string (reverse! l))]
|
||||
[else (loop (cons c l))])))]
|
||||
[(char=? c #\|)
|
||||
(let loop ([l '()])
|
||||
(let ([c (read-char p)])
|
||||
(cond [(eof-object? c)
|
||||
(r-error p "end of file within a |symbol|")]
|
||||
[(char=? c #\\)
|
||||
(let ([e (sub-read-strsym-char-escape p 'symbol)])
|
||||
(loop (if e (cons e l) l)))]
|
||||
[(char=? c #\|) (string->symbol (list->string (reverse! l)))]
|
||||
[else (loop (cons c l))])))]
|
||||
[(char=? c #\#)
|
||||
(let ([c (peek-char p)])
|
||||
(cond [(eof-object? c) (r-error p "end of file after #")]
|
||||
[(char=? c #\!)
|
||||
(read-char p)
|
||||
(let ([name (sub-read-shebang p)])
|
||||
(case name
|
||||
[(fold-case no-fold-case)
|
||||
(set! fold-case? (eq? name 'fold-case))
|
||||
(set-port-fold-case! p fold-case?)
|
||||
(sub-read p)]
|
||||
[else (if (symbol? name)
|
||||
(symbol->shebang name)
|
||||
(r-error p "unexpected name after #!" name))]))]
|
||||
[(or (char-ci=? c #\t) (char-ci=? c #\f))
|
||||
(let ([name (sub-read-carefully p)])
|
||||
(case name [(t true) #t] [(f false) #f]
|
||||
[else (r-error p "unexpected name after #" name)]))]
|
||||
[(or (char-ci=? c #\b) (char-ci=? c #\o)
|
||||
(char-ci=? c #\d) (char-ci=? c #\x)
|
||||
(char-ci=? c #\i) (char-ci=? c #\e))
|
||||
(sub-read-number-or-symbol #\# p)]
|
||||
[(char=? c #\&)
|
||||
(read-char p)
|
||||
(box (sub-read-carefully p))]
|
||||
[(char=? c #\;)
|
||||
(read-char p)
|
||||
(sub-read-carefully p)
|
||||
(sub-read p)]
|
||||
[(char=? c #\|)
|
||||
(read-char p)
|
||||
(let recur () ;starts right after opening #|
|
||||
(let ([next (read-char p)])
|
||||
(cond
|
||||
[(eof-object? next)
|
||||
(r-error p "end of file in #| comment")]
|
||||
[(char=? next #\|)
|
||||
(let ([next (peek-char p)])
|
||||
(cond
|
||||
[(eof-object? next)
|
||||
(r-error p "end of file in #| comment")]
|
||||
[(char=? next #\#) (read-char p)]
|
||||
[else (recur)]))]
|
||||
[(char=? next #\#)
|
||||
(let ([next (peek-char p)])
|
||||
(cond
|
||||
[(eof-object? next)
|
||||
(r-error p "end of file in #| comment")]
|
||||
[(char=? next #\|) (read-char p) (recur) (recur)]
|
||||
[else (recur)]))]
|
||||
[else (recur)])))
|
||||
(sub-read p)]
|
||||
[(char=? c #\() ;)
|
||||
(read-char p)
|
||||
(list->vector (sub-read-list c p close-paren #f))]
|
||||
[(char=? c #\u)
|
||||
(read-char p)
|
||||
(if (and (eq? (read-char p) #\8) (eq? (read-char p) #\())
|
||||
(list->bytevector (sub-read-byte-list p))
|
||||
(r-error p "invalid bytevector syntax"))]
|
||||
[(char=? c #\\)
|
||||
(read-char p)
|
||||
(let ([c (peek-char p)])
|
||||
(cond
|
||||
[(eof-object? c)
|
||||
(r-error p "end of file after #\\")]
|
||||
[(char=? #\x c)
|
||||
(read-char p)
|
||||
(if (char-delimiter? (peek-char p))
|
||||
c
|
||||
(sub-read-x-char-escape p #f))]
|
||||
[(char-alphabetic? c)
|
||||
(let ([name (sub-read-carefully p)])
|
||||
(if (= (string-length (symbol->string name)) 1)
|
||||
c
|
||||
(case name
|
||||
[(null) (integer->char #x00)]
|
||||
[(space) #\space]
|
||||
[(alarm) #\alarm]
|
||||
[(backspace) #\backspace]
|
||||
[(delete) (integer->char #x7F)] ; todo: support by SFC
|
||||
[(escape) (integer->char #x1B)]
|
||||
[(tab) #\tab]
|
||||
[(newline linefeed) #\newline]
|
||||
[(vtab) #\vtab]
|
||||
[(page) #\page]
|
||||
[(return) #\return]
|
||||
[else (r-error p "unknown #\\ name" name)])))]
|
||||
[else (read-char p) c]))]
|
||||
[(char-numeric? c)
|
||||
(when simple? (r-error p "#N=/#N# notation is not allowed in this mode"))
|
||||
(let loop ([l '()])
|
||||
(let ([c (read-char p)])
|
||||
(cond [(eof-object? c)
|
||||
(r-error p "end of file within a #N notation")]
|
||||
[(char-numeric? c)
|
||||
(loop (cons c l))]
|
||||
[(char=? c #\#)
|
||||
(let* ([s (list->string (reverse! l))] [n (string->number s)])
|
||||
(cond [(and (fixnum? n) (assq n shared)) => cdr]
|
||||
[else (r-error "unknown #n# reference:" s)]))]
|
||||
[(char=? c #\=)
|
||||
(let* ([s (list->string (reverse! l))] [n (string->number s)])
|
||||
(cond [(not (fixnum? n)) (r-error "invalid #n= reference:" s)]
|
||||
[(assq n shared) (r-error "duplicate #n= tag:" n)])
|
||||
(let ([loc (box #f)])
|
||||
(set! shared (cons (cons n (make-shared-ref loc)) shared))
|
||||
(let ([form (sub-read-carefully p)])
|
||||
(cond [(shared-ref? form) (r-error "#n= has another label as target" s)]
|
||||
[else (set-box! loc form) form]))))]
|
||||
[else (r-error p "invalid terminator for #N notation")])))]
|
||||
[else (r-error p "unknown # syntax" c)]))]
|
||||
[else (r-error p "illegal character read" c)])))
|
||||
|
||||
(define (sub-read-list c p close-token dot?)
|
||||
(let ([form (sub-read p)])
|
||||
(if (eq? form dot)
|
||||
(r-error p "missing car -- ( immediately followed by .") ;)
|
||||
(let recur ([form form])
|
||||
(cond [(eof-object? form)
|
||||
(r-error p "eof inside list -- unbalanced parentheses")]
|
||||
[(eq? form close-token) '()]
|
||||
[(eq? form dot)
|
||||
(if dot?
|
||||
(let* ([last-form (sub-read-carefully p)]
|
||||
[another-form (sub-read p)])
|
||||
(if (eq? another-form close-token)
|
||||
last-form
|
||||
(r-error p "randomness after form after dot" another-form)))
|
||||
(r-error p "dot in #(...)"))]
|
||||
[(reader-token? form)
|
||||
(r-error p "error inside list --" (cdr form))]
|
||||
[else (cons form (recur (sub-read p)))])))))
|
||||
|
||||
(define (sub-read-byte-list p)
|
||||
(let recur ([form (sub-read p)])
|
||||
(cond [(eof-object? form)
|
||||
(r-error p "eof inside bytevector")]
|
||||
[(eq? form close-paren) '()]
|
||||
[(reader-token? form)
|
||||
(r-error p "error inside bytevector --" (cdr form))]
|
||||
[(or (not (fixnum? form)) (fx<? form 0) (fx>? form 255))
|
||||
(r-error p "invalid byte inside bytevector --" form)]
|
||||
[else (cons form (recur (sub-read p)))])))
|
||||
|
||||
(define (sub-read-strsym-char-escape p what)
|
||||
(let ([c (read-char p)])
|
||||
(if (eof-object? c)
|
||||
(r-error p "end of file within a" what))
|
||||
(cond [(or (char=? c #\\) (char=? c #\") (char=? c #\|)) c]
|
||||
[(char=? c #\a) #\alarm]
|
||||
[(char=? c #\b) #\backspace]
|
||||
[(char=? c #\t) #\tab]
|
||||
[(char=? c #\n) #\newline]
|
||||
[(char=? c #\v) #\vtab]
|
||||
[(char=? c #\f) #\page]
|
||||
[(char=? c #\r) #\return]
|
||||
[(char=? c #\x) (sub-read-x-char-escape p #t)]
|
||||
[(and (eq? what 'string) (char-whitespace? c))
|
||||
(let loop ([gotnl (char=? c #\newline)] [nc (peek-char p)])
|
||||
(cond [(or (eof-object? nc) (not (char-whitespace? nc)))
|
||||
(if gotnl #f (r-error p "no newline in line ending escape"))]
|
||||
[(and gotnl (char=? nc #\newline)) #f]
|
||||
[else (read-char p) (loop (or gotnl (char=? nc #\newline)) (peek-char p))]))]
|
||||
[else (r-error p "invalid char escape in" what ': c)])))
|
||||
|
||||
(define (sub-read-x-char-escape p in-string?)
|
||||
(define (rev-digits->char l)
|
||||
(if (null? l)
|
||||
(r-error p "\\x escape sequence is too short")
|
||||
(integer->char (string->fixnum (list->string (reverse! l)) 16))))
|
||||
(let loop ([c (peek-char p)] [l '()] [cc 0])
|
||||
(cond [(eof-object? c)
|
||||
(if in-string?
|
||||
(r-error p "end of file within a string")
|
||||
(rev-digits->char l))]
|
||||
[(and in-string? (char=? c #\;))
|
||||
(read-char p)
|
||||
(rev-digits->char l)]
|
||||
[(and (not in-string?) (char-delimiter? c))
|
||||
(rev-digits->char l)]
|
||||
[(not (char-hex-digit? c))
|
||||
(r-error p "unexpected char in \\x escape sequence" c)]
|
||||
[(> cc 2)
|
||||
(r-error p "\\x escape sequence is too long")]
|
||||
[else
|
||||
(read-char p)
|
||||
(loop (peek-char p) (cons c l) (+ cc 1))])))
|
||||
|
||||
(define (suspect-number-or-symbol-peculiar? hash? c l s)
|
||||
(cond [(or hash? (char-numeric? c)) #f]
|
||||
[(or (string-ci=? s "+i") (string-ci=? s "-i")) #f]
|
||||
[(or (string-ci=? s "+nan.0") (string-ci=? s "-nan.0")) #f]
|
||||
[(or (string-ci=? s "+inf.0") (string-ci=? s "-inf.0")) #f]
|
||||
[(or (char=? c #\+) (char=? c #\-))
|
||||
(cond [(null? (cdr l)) #t]
|
||||
[(char=? (cadr l) #\.) (and (pair? (cddr l)) (not (char-numeric? (caddr l))))]
|
||||
[else (not (char-numeric? (cadr l)))])]
|
||||
[else (and (char=? c #\.) (pair? (cdr l)) (not (char-numeric? (cadr l))))]))
|
||||
|
||||
(define (sub-read-number-or-symbol c p)
|
||||
(let loop ([c (peek-char p)] [l (list c)] [hash? (char=? c #\#)])
|
||||
(cond [(or (eof-object? c) (char-delimiter? c))
|
||||
(let* ([l (reverse! l)] [c (car l)] [s (list->string l)])
|
||||
(if (or hash? (char-numeric? c)
|
||||
(char=? c #\+) (char=? c #\-) (char=? c #\.))
|
||||
(cond [(string=? s ".") dot]
|
||||
[(suspect-number-or-symbol-peculiar? hash? c l s)
|
||||
(if fold-case?
|
||||
(string->symbol (string-foldcase s))
|
||||
(string->symbol s))]
|
||||
[(string->number s)]
|
||||
[else (r-error p "unsupported number syntax (implementation restriction)" s)])
|
||||
(if fold-case?
|
||||
(string->symbol (string-foldcase s))
|
||||
(string->symbol s))))]
|
||||
[(char=? c #\#)
|
||||
(read-char p)
|
||||
(loop (peek-char p) (cons c l) #t)]
|
||||
[(char-symbolic? c)
|
||||
(read-char p)
|
||||
(loop (peek-char p) (cons c l) hash?)]
|
||||
[else (r-error p "unexpected number/symbol char" c)])))
|
||||
|
||||
; body of %read
|
||||
(let ([form (sub-read port)])
|
||||
(if (not (reader-token? form))
|
||||
(if (null? shared) form (patch-shared form))
|
||||
(r-error port "unexpected token:" (cdr form)))))
|
||||
(define %read
|
||||
(body
|
||||
; support for sharing (use procedures that can't be read)
|
||||
(define (make-shared-ref loc) (lambda () (unbox loc)))
|
||||
(define (shared-ref? form) (procedure? form))
|
||||
(define (patch-ref! form) (if (procedure? form) (patch-ref! (form)) form))
|
||||
(define (patch-shared! form)
|
||||
(cond [(pair? form)
|
||||
(if (procedure? (car form))
|
||||
(set-car! form (patch-ref! (car form)))
|
||||
(patch-shared! (car form)))
|
||||
(if (procedure? (cdr form))
|
||||
(set-cdr! form (patch-ref! (cdr form)))
|
||||
(patch-shared! (cdr form)))]
|
||||
[(vector? form)
|
||||
(let loop ([i 0])
|
||||
(when (fx<? i (vector-length form))
|
||||
(let ([fi (vector-ref form i)])
|
||||
(if (procedure? fi)
|
||||
(vector-set! form i (patch-ref! fi))
|
||||
(patch-shared! fi)))
|
||||
(loop (fx+ i 1))))]
|
||||
[(box? form)
|
||||
(if (procedure? (unbox form))
|
||||
(set-box! form (patch-shared! (unbox form)))
|
||||
(patch-shared! (unbox form)))]))
|
||||
(define (patch-shared form) (patch-shared! form) form)
|
||||
; special tokens (can't be read, but different from procedures)
|
||||
(define close-paren (make-record 'token 1 "right parenthesis"))
|
||||
(define close-bracket (make-record 'token 1 "right bracket"))
|
||||
(define dot (make-record 'token 1 "\" . \""))
|
||||
(define-syntax reader-token? record?)
|
||||
(define-syntax reader-token-name (syntax-lambda (x) (record-ref x 0)))
|
||||
; main entry point
|
||||
(lambda (port simple? ci?)
|
||||
(define fold-case? (or ci? (port-fold-case? port)))
|
||||
(define buf (open-output-string))
|
||||
(define-syntax r-error
|
||||
(syntax-rules () [(_ msg a ...) (read-error msg a ... 'port: port)]))
|
||||
(define shared '())
|
||||
(define (sub-read)
|
||||
(let ([tk (%read-token port buf)])
|
||||
(cond [(eq? tk #t) (eof-object)]
|
||||
[(eq? tk #f) (r-error "invalid token")]
|
||||
[(char=? tk #\f) #f]
|
||||
[(char=? tk #\t) #t]
|
||||
[(char=? tk #\n)
|
||||
(or (%get-output-value buf #\n)
|
||||
(read-error "unsupported number syntax (implementation restriction)"
|
||||
(get-output-string buf)))]
|
||||
[(char=? tk #\y)
|
||||
(if fold-case?
|
||||
(string-ci->symbol (get-output-string buf))
|
||||
(%get-output-value buf #\y))]
|
||||
[(or (char=? tk #\c) (char=? tk #\s) (char=? tk #\!)) (%get-output-value buf tk)]
|
||||
[(char=? tk #\;) (sub-read-carefully) (sub-read)]
|
||||
[(char=? tk #\l) (sub-read-list close-paren #t #f)]
|
||||
[(char=? tk #\v) (list->vector (sub-read-list close-paren #f #f))]
|
||||
[(char=? tk #\u) (list->bytevector (sub-read-list close-paren #f #t))]
|
||||
[(char=? tk #\r) close-paren]
|
||||
[(char=? tk #\b) (sub-read-list close-bracket #t #f)]
|
||||
[(char=? tk #\k) close-bracket]
|
||||
[(char=? tk #\.) dot]
|
||||
[(char=? tk #\') (list 'quote (sub-read-carefully))]
|
||||
[(char=? tk #\`) (list 'quasiquote (sub-read-carefully))]
|
||||
[(char=? tk #\,) (list 'unquote (sub-read-carefully))]
|
||||
[(char=? tk #\@) (list 'unquote-splicing (sub-read-carefully))]
|
||||
[(char=? tk #\&) (box (sub-read-carefully))]
|
||||
[(or (char=? tk #\F) (char=? tk #\N))
|
||||
(set! fold-case? (char=? tk #\F))
|
||||
(set-port-fold-case! port fold-case?)
|
||||
(sub-read)]
|
||||
[(or (char=? tk #\#) (char=? tk #\=))
|
||||
(when simple? (r-error "#N=/#N# notation is not allowed in this mode"))
|
||||
(let ([n (%get-output-value buf #\n)])
|
||||
(if (char=? tk #\#)
|
||||
(cond [(and (fixnum? n) (assq n shared)) => cdr]
|
||||
[else (r-error "unknown #n# reference" n)])
|
||||
(cond [(not (fixnum? n)) (r-error "invalid #n= reference" n)]
|
||||
[(assq n shared) (r-error "duplicate #n= tag:" n)]
|
||||
[else
|
||||
(let ([loc (box #f)])
|
||||
(set! shared (cons (cons n (make-shared-ref loc)) shared))
|
||||
(let ([form (sub-read-carefully)])
|
||||
(cond [(shared-ref? form) (r-error "#n= has a label as target" n)]
|
||||
[else (set-box! loc form) form])))])))]
|
||||
[else (r-error "invalid token" tk (get-output-string buf))])))
|
||||
(define (sub-read-carefully)
|
||||
(let ([form (sub-read)])
|
||||
(cond [(eof-object? form)
|
||||
(r-error "unexpected end of file")]
|
||||
[(reader-token? form) ; special reader token
|
||||
(r-error (string-append "unexpected token: " (reader-token-name form)))]
|
||||
[else form])))
|
||||
(define (sub-read-list close-token dot? byte?)
|
||||
(let loop ([form (sub-read)] [l #f] [lp #f])
|
||||
(cond [(eof-object? form) (r-error "eof inside list -- unbalanced parentheses")]
|
||||
[(eq? form close-token) (if lp l '())]
|
||||
[(and dot? (eq? form dot))
|
||||
(let* ([form (sub-read-carefully)] [another-form (sub-read)])
|
||||
(if (eq? another-form close-token)
|
||||
(cond [lp (set-cdr! lp form) l] [else (r-error "unexpected dot")])
|
||||
(r-error "too many forms after dot" another-form)))]
|
||||
[(eq? form dot) (r-error "unexpected dot notation")]
|
||||
[(reader-token? form) ; other special reader token
|
||||
(r-error (string-append "unexpected token: " (reader-token-name form)))]
|
||||
[(and byte? (or (not (fixnum? form)) (fx<? form 0) (fx>? form 255)))
|
||||
(r-error "invalid byte inside bytevector" form)]
|
||||
[(not lp) (let ([l (list form)]) (loop (sub-read) l l))]
|
||||
[else (let ([nlp (list form)]) (set-cdr! lp nlp) (loop (sub-read) l nlp))])))
|
||||
; body of %read
|
||||
(let ([form (sub-read)])
|
||||
(if (not (reader-token? form))
|
||||
(if (null? shared) form (patch-shared form))
|
||||
(r-error (string-append "unexpected token: " (reader-token-name form))))))))
|
||||
|
||||
(define read
|
||||
(case-lambda
|
||||
|
|
|
@ -2758,7 +2758,7 @@
|
|||
[help "-h" "--help" #f "Display this help"]
|
||||
))
|
||||
|
||||
(define *skint-version* "0.4.9")
|
||||
(define *skint-version* "0.6.2")
|
||||
|
||||
(define (implementation-version) *skint-version*)
|
||||
(define (implementation-name) "SKINT")
|
||||
|
|
231
s.c
231
s.c
|
@ -193,9 +193,9 @@ char *s_code[] = {
|
|||
":body;;;",
|
||||
|
||||
"P", "new-record-type",
|
||||
"%2'(l1:s6:rtd://;),.2,.2c,,#0.0,&1{%2.0u?{${.3A8,@(y14:%25string-appen"
|
||||
"d),@(y13:apply-to-list)[02}X5]2}.0du?{.1,.1aX4c,.1d,:0^[22}.1,.1aX4c,'"
|
||||
"(s1::)c,.1d,:0^[22}.!0.0^_1[22",
|
||||
"%2'(l1:s6:rtd://;),.2,.2c,,#0.0,&1{%2.0u?{${.3A8,@(y13:string-append),"
|
||||
"@(y13:apply-to-list)[02}X5]2}.0du?{.1,.1aX4c,.1d,:0^[22}.1,.1aX4c,'(s1"
|
||||
"::)c,.1d,:0^[22}.!0.0^_1[22",
|
||||
|
||||
"S", "%id-eq??",
|
||||
"l3:y12:syntax-rules;n;l2:l5:y1:_;y2:id;y1:b;y2:kt;y2:kf;;l3:l3:y13:syn"
|
||||
|
@ -358,8 +358,8 @@ char *s_code[] = {
|
|||
"%1.0SfX5]1",
|
||||
|
||||
"P", "symbol-append",
|
||||
"%!0${${.4,@(y14:symbol->string),@(y5:%25map1)[02},@(y14:%25string-appe"
|
||||
"nd),@(y13:apply-to-list)[02}X5]1",
|
||||
"%!0${${.4,@(y14:symbol->string),@(y5:%25map1)[02},@(y13:string-append)"
|
||||
",@(y13:apply-to-list)[02}X5]1",
|
||||
|
||||
"P", "substring->list",
|
||||
"%3n,'1,.4I-,,#0.3,.1,.6,&3{%2:0,.1I<?{.1]2}.1,.1,:2S4c,'1,.2I-,:1^[22}"
|
||||
|
@ -411,22 +411,6 @@ char *s_code[] = {
|
|||
"string->vector)[23}%x,&0{%1.0S3,'0,.2,@(y17:substring->vector)[13}%x,&"
|
||||
"3{|10|21|32%%}@!(y14:string->vector)",
|
||||
|
||||
"P", "strings-sum-length",
|
||||
"%1'0,.1,,#0.0,&1{%2.0u?{.1]2}.0aS3,.2I+,.1d,:0^[22}.!0.0^_1[12",
|
||||
|
||||
"P", "strings-copy-into!",
|
||||
"%2'0,.2,,#0.0,.4,&2{%2.0u?{:0]2}.0d,.1a,.0S3,${.2,'0,.5,.9,:0,@(y15:su"
|
||||
"bstring-copy!)[05}.0,.5I+,.3,:1^[52}.!0.0^_1[22",
|
||||
|
||||
"P", "%string-append",
|
||||
"%!0.0,'(c ),${.4,@(y18:strings-sum-length)[01}S2,@(y18:strings-copy-in"
|
||||
"to!)[12",
|
||||
|
||||
"S", "string-append",
|
||||
"l7:y12:syntax-rules;n;l2:l1:y1:_;;s0:;;l2:l2:y1:_;y1:x;;l2:y4:%25cks;y"
|
||||
"1:x;;;l2:l3:y1:_;y1:x;y1:y;;l3:y10:string-cat;y1:x;y1:y;;;l2:py1:_;y1:"
|
||||
"r;;py14:%25string-append;y1:r;;;l2:y1:_;y14:%25string-append;;",
|
||||
|
||||
"P", "string-trim-whitespace",
|
||||
"%1.0S3,'0,,#0.3,.1,&2{%2.1,.1<?{.0,:1S4C1}{f}?{.1,'1,.2+,:0^[22}.1,,#0"
|
||||
".2,:1,.5,.3,&4{%1:3,.1>?{'1,.1-,:2S4C1}{f}?{'1,.1-,:0^[11}'0,:3=?{:1,."
|
||||
|
@ -486,23 +470,6 @@ char *s_code[] = {
|
|||
"vector->string)[23}%x,&0{%1.0V3,'0,.2,@(y17:subvector->string)[13}%x,&"
|
||||
"3{|10|21|32%%}@!(y14:vector->string)",
|
||||
|
||||
"P", "vectors-sum-length",
|
||||
"%1'0,.1,,#0.0,&1{%2.0u?{.1]2}.0aV3,.2I+,.1d,:0^[22}.!0.0^_1[12",
|
||||
|
||||
"P", "vectors-copy-into!",
|
||||
"%2'0,.2,,#0.0,.4,&2{%2.0u?{:0]2}.0d,.1a,.0V3,${.2,'0,.5,.9,:0,@(y15:su"
|
||||
"bvector-copy!)[05}.0,.5I+,.3,:1^[52}.!0.0^_1[22",
|
||||
|
||||
"P", "%vector-append",
|
||||
"%!0.0,f,${.4,@(y18:vectors-sum-length)[01}V2,@(y18:vectors-copy-into!)"
|
||||
"[12",
|
||||
|
||||
"S", "vector-append",
|
||||
"l7:y12:syntax-rules;n;l2:l1:y1:_;;l2:y5:quote;v0:;;;l2:l2:y1:_;y1:x;;l"
|
||||
"2:y4:%25ckv;y1:x;;;l2:l3:y1:_;y1:x;y1:y;;l3:y10:vector-cat;y1:x;y1:y;;"
|
||||
";l2:py1:_;y1:r;;py14:%25vector-append;y1:r;;;l2:y1:_;y14:%25vector-app"
|
||||
"end;;",
|
||||
|
||||
"P", "subbytevector->list",
|
||||
"%3n,'1,.4I-,,#0.3,.1,.6,&3{%2:0,.1I<?{.1]2}.1,.1,:2B4c,'1,.2I-,:1^[22}"
|
||||
".!0.0^_1[32",
|
||||
|
@ -536,17 +503,6 @@ char *s_code[] = {
|
|||
"(y19:subbytevector-fill!)[34}%x,&0{%2.0B3,'0,.3,.3,@(y19:subbytevector"
|
||||
"-fill!)[24}%x,&3{|20|31|42%%}@!(y16:bytevector-fill!)",
|
||||
|
||||
"P", "%bytevectors-sum-length",
|
||||
"%1'0,.1,,#0.0,&1{%2.0u?{.1]2}.0aB3,.2I+,.1d,:0^[22}.!0.0^_1[12",
|
||||
|
||||
"P", "%bytevectors-copy-into!",
|
||||
"%2'0,.2,,#0.0,.4,&2{%2.0u?{:0]2}.0d,.1a,.0B3,${.2,'0,.5,.9,:0,@(y19:su"
|
||||
"bbytevector-copy!)[05}.0,.5I+,.3,:1^[52}.!0.0^_1[22",
|
||||
|
||||
"P", "bytevector-append",
|
||||
"%!0.0,'0,${.4,@(y23:%25bytevectors-sum-length)[01}B2,@(y23:%25bytevect"
|
||||
"ors-copy-into!)[12",
|
||||
|
||||
"P", "subutf8->string",
|
||||
"%3P51,${.2,.6,.6,.6,@(y19:write-subbytevector)[04}.0P90,.1P61.0]5",
|
||||
|
||||
|
@ -843,11 +799,6 @@ char *s_code[] = {
|
|||
"%2.1,&1{%1:0,.1,@(y19:with-output-to-port)[12},.1,@(y21:call-with-outp"
|
||||
"ut-file)[22",
|
||||
|
||||
"P", "read-line",
|
||||
"%!0P51,.1u?{Pi}{.1a},t,,#0.2,.4,.2,&3{%1:2R0,.0R8,.0?{.0}{'(c%0a),.2C="
|
||||
"}_1?{.0R8?{.1}{f}?{.0]2}:1P90,:1P61.0]3}'(c%0d),.1C=?{f,:0^[21}:1,.1W0"
|
||||
"f,:0^[21}.!0.0^_1[31",
|
||||
|
||||
"P", "read-substring!",
|
||||
"%4.1,,#0.5,.4,.4,.3,.8,&5{%1:0,.1I<!?{:3,.1I-]1}:4R0,.0R8?{:3,.2I=?{.0"
|
||||
"]2}:3,.2I-]2}.0,.2,:2S5'1,.2I+,:1^[21}.!0.0^_1[41",
|
||||
|
@ -884,130 +835,54 @@ char *s_code[] = {
|
|||
"&0{%2.1,.1,@(y18:read-subbytevector)[22}%x,&0{%1Pi,.1,@(y18:read-subby"
|
||||
"tevector)[12}%x,&2{|10|21%%}@!(y15:read-bytevector)",
|
||||
|
||||
"P", "%read",
|
||||
"%3,,,,,,,,,,,,,,,,,,,,,,,,#0#1#2#3#4#5#6#7#8#9#(i10)#(i11)#(i12)#(i13)"
|
||||
"#(i14)#(i15)#(i16)#(i17)#(i18)#(i19)#(i20)#(i21)#(i22)#(i23).(i26),.0?"
|
||||
"{.0}{.(i25)P78}_1.!0n.!1&0{%1.0,&1{%0:0z]0}]1}.!2&0{%1.0K0]1}.!3.4,&1{"
|
||||
"%1.0K0?{${.2[00},:0^[11}.0]1}.!4.5,.5,&2{%1.0p?{.0aK0?{${.2a,:0^[01},."
|
||||
"C", 0,
|
||||
",,,,,,,,#0#1#2#3#4#5#6#7&0{%1.0,&1{%0:0z]0}]1}.!0&0{%1.0K0]1}.!1.2,&1{"
|
||||
"%1.0K0?{${.2[00},:0^[11}.0]1}.!2.3,.3,&2{%1.0p?{.0aK0?{${.2a,:0^[01},."
|
||||
"1sa}{${.2a,:1^[01}}.0dK0?{${.2d,:0^[01},.1sd]1}.0d,:1^[11}.0V0?{'0,,#0"
|
||||
".2,:0,:1,.3,&4{%1:3V3,.1I<?{.0,:3V4,.0K0?{${.2,:2^[01},.2,:3V5}{${.2,:"
|
||||
"1^[01}}_1'1,.1I+,:0^[11}]1}.!0.0^_1[11}.0Y2?{.0zK0?{${.2z,:1^[01},.1sz"
|
||||
"]1}.0z,:1^[11}f]1}.!5.5,&1{%1${.2,:0^[01}.0]1}.!6f.!7f.!8f.!9f.!(i10)'"
|
||||
"(y12:reader-token),l1,.0.!8'(s17:right parenthesis),.1c.!9'(s13:right "
|
||||
"bracket),.1c.!(i10)'(s5:%22 . %22),.1c.!(i11)_1.7,&1{%1.0p?{:0^,.1aq]1"
|
||||
"}f]1}.!(i11)&0{%1'(s80:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu"
|
||||
"vwxyz!$%25&*/:<=>?^_~0123456789+-.@),.1S8]1}.!(i12)&0{%1.0X8,'(i48),.1"
|
||||
"<!?{'(i57),.1>!}{f},.0?{.0]3}'(i65),.2<!?{'(i70),.2>!}{f},.0?{.0]4}'(i"
|
||||
"97),.3<!?{'(i102),.3>!]4}f]4}.!(i13)&0{%1.0C1,.0?{.0]2}'(c)),.2C=,.0?{"
|
||||
".0]3}'(c(),.3C=,.0?{.0]4}'(c]),.4C=,.0?{.0]5}'(c[),.5C=,.0?{.0]6}'(c%2"
|
||||
"2),.6C=,.0?{.0]7}'(c;),.7C=]7}.!(i14).(i17),.(i12),&2{%1${.2,:1^[01},."
|
||||
"0R8?{.1,'(y5:port:),'(s22:unexpected end of file),@(y10:read-error)[23"
|
||||
"}${.2,:0^[01}?{.1,'(y5:port:),.2d,'(s17:unexpected token:),@(y10:read-"
|
||||
"error)[24}.0]2}.!(i15).(i15),&1{%1'(c ),.1R1v?{${${.4,@(y9:read-line)["
|
||||
"01},@(y22:string-trim-whitespace)[01}X5]1}.0,:0^[11}.!(i16).9,.(i13),."
|
||||
"(i22),.3,.(i20),.(i28),.(i23),.(i15),.(i26),.(i28),.(i31),.(i25),.(i15"
|
||||
"),.(i28),.(i16),.(i16),.(i41),&(i17){%1.0R0,.0R8?{.0]2}.0C1?{.1,:(i10)"
|
||||
"^[21}'(c(),.1C=?{t,:9^,.3,.3,:8^[24}'(c)),.1C=?{:9^]2}'(c[),.1C=?{t,:("
|
||||
"i16)^,.3,.3,:8^[24}'(c]),.1C=?{:(i16)^]2}'(c'),.1C=?{${.3,:3^[01},'(y5"
|
||||
":quote),l2]2}'(c`),.1C=?{${.3,:3^[01},'(y10:quasiquote),l2]2}${.2,:(i1"
|
||||
"5)^[01}?{.1,.1,:(i11)^[22}'(c;),.1C=?{${.3R0,,#0.5,.1,&2{%1.0R8,.0?{.0"
|
||||
"]2}'(c%0a),.2C=,.0?{.0]3}:1R0,:0^[31}.!0.0^_1[01}.1,:(i10)^[21}'(c,),."
|
||||
"1C=?{.1R1,.0R8?{.2,'(y5:port:),'(s19:end of file after ,),@(y10:read-e"
|
||||
"rror)[33}'(c@),.1C=?{.2R0${.4,:3^[01},'(y16:unquote-splicing),l2]3}${."
|
||||
"4,:3^[01},'(y7:unquote),l2]3}'(c%22),.1C=?{n,,#0.3,:(i14),.2,&3{%1:2R0"
|
||||
",.0R8?{:2,'(y5:port:),'(s27:end of file within a string),@(y10:read-er"
|
||||
"ror)[23}'(c%5c),.1C=?{${'(y6:string),:2,:1^[02},.0?{.2,.1c}{.2},:0^[31"
|
||||
"}'(c%22),.1C=?{.1A9X3]2}.1,.1c,:0^[21}.!0.0^_1[21}'(c|),.1C=?{n,,#0.3,"
|
||||
":(i14),.2,&3{%1:2R0,.0R8?{:2,'(y5:port:),'(s29:end of file within a |s"
|
||||
"ymbol|),@(y10:read-error)[23}'(c%5c),.1C=?{${'(y6:symbol),:2,:1^[02},."
|
||||
"0?{.2,.1c}{.2},:0^[31}'(c|),.1C=?{.1A9X3X5]2}.1,.1c,:0^[21}.!0.0^_1[21"
|
||||
"}'(c#),.1C=?{.1R1,.0R8?{.2,'(y5:port:),'(s19:end of file after #),@(y1"
|
||||
"0:read-error)[33}'(c!),.1C=?{.2R0${.4,:(i12)^[01},.0,'(l2:y9:fold-case"
|
||||
";y12:no-fold-case;),.1A1?{'(y9:fold-case),.2q:!(i13):(i13)^,.5P79.4,:("
|
||||
"i10)^[51}.1Y0?{.1Y6]5}.4,'(y5:port:),.3,'(s24:unexpected name after #!"
|
||||
"),@(y10:read-error)[54}'(ct),.1Ci=,.0?{.0}{'(cf),.2Ci=}_1?{${.4,:3^[01"
|
||||
"},.0,'(l2:y1:t;y4:true;),.1A1?{t]5}'(l2:y1:f;y5:false;),.1A1?{f]5}.4,'"
|
||||
"(y5:port:),.3,'(s23:unexpected name after #),@(y10:read-error)[54}'(cb"
|
||||
"),.1Ci=,.0?{.0}{'(co),.2Ci=,.0?{.0}{'(cd),.3Ci=,.0?{.0}{'(cx),.4Ci=,.0"
|
||||
"?{.0}{'(ci),.5Ci=,.0?{.0}{'(ce),.6Ci=}_1}_1}_1}_1}_1?{.2,'(c#),:(i11)^"
|
||||
"[32}'(c&),.1C=?{.2R0${.4,:3^[01}b]3}'(c;),.1C=?{.2R0${.4,:3^[01}.2,:(i"
|
||||
"10)^[31}'(c|),.1C=?{.2R0${,#0.5,.1,&2{%0:1R0,.0R8?{:1,'(y5:port:),'(s2"
|
||||
"5:end of file in #| comment),@(y10:read-error)[13}'(c|),.1C=?{:1R1,.0R"
|
||||
"8?{:1,'(y5:port:),'(s25:end of file in #| comment),@(y10:read-error)[2"
|
||||
"3}'(c#),.1C=?{:1R0]2}:0^[20}'(c#),.1C=?{:1R1,.0R8?{:1,'(y5:port:),'(s2"
|
||||
"5:end of file in #| comment),@(y10:read-error)[23}'(c|),.1C=?{:1R0${:0"
|
||||
"^[00}:0^[20}:0^[20}:0^[10}.!0.0^_1[00}.2,:(i10)^[31}'(c(),.1C=?{.2R0${"
|
||||
"f,:9^,.6,.5,:8^[04}X1]3}'(cu),.1C=?{.2R0'(c8),.3R0q?{'(c(),.3R0q}{f}?{"
|
||||
"${.4,:7^[01}E1]3}.2,'(y5:port:),'(s25:invalid bytevector syntax),@(y10"
|
||||
":read-error)[33}'(c%5c),.1C=?{.2R0.2R1,.0R8?{.3,'(y5:port:),'(s20:end "
|
||||
"of file after #%5c),@(y10:read-error)[43}.0,'(cx)C=?{.3R0${.5R1,:5^[01"
|
||||
"}?{.0]4}f,.4,:6^[42}.0C4?{${.5,:3^[01},'1,.1X4S3=?{.1]5}.0,'(y4:null),"
|
||||
".1v?{'0X9]6}'(y5:space),.1v?{'(c )]6}'(y5:alarm),.1v?{'(c%07)]6}'(y9:b"
|
||||
"ackspace),.1v?{'(c%08)]6}'(y6:delete),.1v?{'(i127)X9]6}'(y6:escape),.1"
|
||||
"v?{'(i27)X9]6}'(y3:tab),.1v?{'(c%09)]6}'(l2:y7:newline;y8:linefeed;),."
|
||||
"1A1?{'(c%0a)]6}'(y4:vtab),.1v?{'(c%0b)]6}'(y4:page),.1v?{'(c%0c)]6}'(y"
|
||||
"6:return),.1v?{'(c%0d)]6}.5,'(y5:port:),.3,'(s15:unknown #%5c name),@("
|
||||
"y10:read-error)[64}.3R0.0]4}.0C5?{:0?{${.4,'(y5:port:),'(s44:#N=/#N# n"
|
||||
"otation is not allowed in this mode),@(y10:read-error)[03}}n,,#0.4,.1,"
|
||||
":4,:3,:2,:1,&6{%1:5R0,.0R8?{:5,'(y5:port:),'(s32:end of file within a "
|
||||
"#N notation),@(y10:read-error)[23}.0C5?{.1,.1c,:4^[21}'(c#),.1C=?{.1A9"
|
||||
"X3,'(i10),.1E9,.0I0?{:0^,.1A3}{f},.0?{.0d]5}'(s22:unknown #n# referenc"
|
||||
"e:),'(y5:port:),.4,@(y10:read-error)[53}'(c=),.1C=?{.1A9X3,'(i10),.1E9"
|
||||
",.0I0~?{${'(s22:invalid #n= reference:),'(y5:port:),.5,@(y10:read-erro"
|
||||
"r)[03}}{:0^,.1A3?{${'(s18:duplicate #n= tag:),'(y5:port:),.4,@(y10:rea"
|
||||
"d-error)[03}}{f}}fb,:0^,${.3,:1^[01},.3cc:!0${:5,:2^[01},${.2,:3^[01}?"
|
||||
"{'(s31:#n= has another label as target),'(y5:port:),.5,@(y10:read-erro"
|
||||
"r)[63}.0,.2sz.0]6}:5,'(y5:port:),'(s34:invalid terminator for #N notat"
|
||||
"ion),@(y10:read-error)[23}.!0.0^_1[31}.2,'(y5:port:),.2,'(s16:unknown "
|
||||
"# syntax),@(y10:read-error)[34}.1,'(y5:port:),.2,'(s22:illegal charact"
|
||||
"er read),@(y10:read-error)[24}.!(i17).(i17),.(i12),.(i17),.(i13),&4{%4"
|
||||
"${.3,:3^[01},:0^,.1q?{.2,'(y5:port:),'(s42:missing car -- ( immediatel"
|
||||
"y followed by .),@(y10:read-error)[53}.0,,#0.0,.5,:3,:2,.(i10),:1,.(i1"
|
||||
"1),:0,&8{%1.0R8?{:6,'(y5:port:),'(s41:eof inside list -- unbalanced pa"
|
||||
"rentheses),@(y10:read-error)[13}:1,.1q?{n]1}:0^,.1q?{:3?{${:6,:2^[01},"
|
||||
"${:6,:5^[01},:1,.1q?{.1]3}:6,'(y5:port:),.2,'(s31:randomness after for"
|
||||
"m after dot),@(y10:read-error)[34}:6,'(y5:port:),'(s13:dot in #(...)),"
|
||||
"@(y10:read-error)[13}${.2,:4^[01}?{:6,'(y5:port:),.2d,'(s20:error insi"
|
||||
"de list --),@(y10:read-error)[14}${${:6,:5^[01},:7^[01},.1c]1}.!0.0^_1"
|
||||
"[51}.!(i18).(i17),.9,.(i13),&3{%1${.2,:2^[01},,#0.0,.3,:2,:0,:1,&5{%1."
|
||||
"0R8?{:3,'(y5:port:),'(s21:eof inside bytevector),@(y10:read-error)[13}"
|
||||
":0^,.1q?{n]1}${.2,:1^[01}?{:3,'(y5:port:),.2d,'(s26:error inside bytev"
|
||||
"ector --),@(y10:read-error)[14}.0I0~,.0?{.0}{'0,.2I<,.0?{.0}{'(i255),."
|
||||
"3I>}_1}_1?{:3,'(y5:port:),.2,'(s33:invalid byte inside bytevector --),"
|
||||
"@(y10:read-error)[14}${${:3,:2^[01},:4^[01},.1c]1}.!0.0^_1[11}.!(i19)."
|
||||
"(i21),&1{%2.0R0,.0R8?{${.3,'(y5:port:),.6,'(s20:end of file within a),"
|
||||
"@(y10:read-error)[04}}'(c%5c),.1C=,.0?{.0}{'(c%22),.2C=,.0?{.0}{'(c|),"
|
||||
".3C=}_1}_1?{.0]3}'(ca),.1C=?{'(c%07)]3}'(cb),.1C=?{'(c%08)]3}'(ct),.1C"
|
||||
"=?{'(c%09)]3}'(cn),.1C=?{'(c%0a)]3}'(cv),.1C=?{'(c%0b)]3}'(cf),.1C=?{'"
|
||||
"(c%0c)]3}'(cr),.1C=?{'(c%0d)]3}'(cx),.1C=?{t,.2,:0^[32}'(y6:string),.3"
|
||||
"q?{.0C1}{f}?{.1R1,'(c%0a),.2C=,,#0.0,.5,&2{%2.1R8,.0?{.0}{.2C1~}_1?{.0"
|
||||
"?{f]2}:0,'(y5:port:),'(s32:no newline in line ending escape),@(y10:rea"
|
||||
"d-error)[23}.0?{'(c%0a),.2C=}{f}?{f]2}:0R0:0R1,.1,.0?{.0}{'(c%0a),.4C="
|
||||
"}_1,:1^[22}.!0.0^_1[32}.1,'(y5:port:),.2,'(y1::),.6,'(s22:invalid char"
|
||||
" escape in),@(y10:read-error)[36}.!(i20).(i14),.(i14),&2{%2,#0.1,&1{%1"
|
||||
".0u?{:0,'(y5:port:),'(s31:%5cx escape sequence is too short),@(y10:rea"
|
||||
"d-error)[13}'(i16),.1A9X3X7X9]1}.!0'0,n,.3R1,,#0.0,.6,:0,.7,.(i10),:1,"
|
||||
"&6{%3.0R8?{:1?{:4,'(y5:port:),'(s27:end of file within a string),@(y10"
|
||||
":read-error)[33}.1,:2^[31}:1?{'(c;),.1C=}{f}?{:4R0.1,:2^[31}:1~?{${.2,"
|
||||
":0^[01}}{f}?{.1,:2^[31}${.2,:3^[01}~?{:4,'(y5:port:),.2,'(s37:unexpect"
|
||||
"ed char in %5cx escape sequence),@(y10:read-error)[34}'2,.3>?{:4,'(y5:"
|
||||
"port:),'(s30:%5cx escape sequence is too long),@(y10:read-error)[33}:4"
|
||||
"R0'1,.3+,.2,.2c,:4R1,:5^[33}.!0.0^_1[33}.!(i21)&0{%4.0,.0?{.0}{.2C5}_1"
|
||||
"?{f]4}'(s2:+i),.4Si=,.0?{.0}{'(s2:-i),.5Si=}_1?{f]4}'(s6:+nan.0),.4Si="
|
||||
",.0?{.0}{'(s6:-nan.0),.5Si=}_1?{f]4}'(s6:+inf.0),.4Si=,.0?{.0}{'(s6:-i"
|
||||
"nf.0),.5Si=}_1?{f]4}'(c+),.2C=,.0?{.0}{'(c-),.3C=}_1?{.2du?{t]4}'(c.),"
|
||||
".3daC=?{.2ddp?{.2ddaC5~]4}f]4}.2daC5~]4}'(c.),.2C=?{.2dp?{.2daC5~]4}f]"
|
||||
"4}f]4}.!(i22).(i14),.(i23),.(i12),.3,.(i16),&5{%2'(c#),.1C=,.1,l1,.3R1"
|
||||
",,#0.5,.1,:0,:1,:2,:3,:4,&7{%3.0R8,.0?{.0}{${.3,:0^[01}}_1?{.1A9,.0a,."
|
||||
"1X3,.5,.0?{.0}{.2C5,.0?{.0}{'(c+),.4C=,.0?{.0}{'(c-),.5C=,.0?{.0}{'(c."
|
||||
"),.6C=}_1}_1}_1}_1?{'(s1:.),.1S=?{:2^]6}${.2,.5,.5,.(i10),:1^[04}?{:3^"
|
||||
"?{.0SfX5]6}.0X5]6}'(i10),.1E9,.0?{.0]7}:6,'(y5:port:),.3,'(s54:unsuppo"
|
||||
"rted number syntax (implementation restriction)),@(y10:read-error)[74}"
|
||||
":3^?{.0SfX5]6}.0X5]6}'(c#),.1C=?{:6R0t,.2,.2c,:6R1,:5^[33}${.2,:4^[01}"
|
||||
"?{:6R0.2,.2,.2c,:6R1,:5^[33}:6,'(y5:port:),.2,'(s29:unexpected number/"
|
||||
"symbol char),@(y10:read-error)[34}.!0.0^_1[23}.!(i23)${.(i26),.(i20)^["
|
||||
"01},${.2,.(i15)^[01}~?{.2^u?{.0](i28)}.0,.8^[(i28)1}.(i25),'(y5:port:)"
|
||||
",.2d,'(s17:unexpected token:),@(y10:read-error)[(i28)4",
|
||||
"]1}.0z,:1^[11}f]1}.!3.3,&1{%1${.2,:0^[01}.0]1}.!4'(s17:right parenthes"
|
||||
"is),'1,'(y5:token)O2.!5'(s13:right bracket),'1,'(y5:token)O2.!6'(s5:%2"
|
||||
"2 . %22),'1,'(y5:token)O2.!7.5,.7,.2,.4,.(i11),.9,&6{%3,,,,,,#0#1#2#3#"
|
||||
"4#5.8,.0?{.0}{.7P78}_1.!0P51.!1n.!2.6,.2,:5,.8,:4,:1,.9,.7,.(i10),:3,."
|
||||
"(i14),:2,.(i19),&(i13){%0:(i11)^,:(i12)R7,t,.1q?{R9]1}f,.1q?{:(i12),'("
|
||||
"y5:port:),'(s13:invalid token),@(y10:read-error)[13}'(cf),.1C=?{f]1}'("
|
||||
"ct),.1C=?{t]1}'(cn),.1C=?{'(cn),:(i11)^P92,.0?{.0]2}:(i11)^P90,'(s54:u"
|
||||
"nsupported number syntax (implementation restriction)),@(y10:read-erro"
|
||||
"r)[22}'(cy),.1C=?{:5^?{:(i11)^P90,@(y17:string-ci->symbol)[11}'(cy),:("
|
||||
"i11)^P92]1}'(cc),.1C=,.0?{.0}{'(cs),.2C=,.0?{.0}{'(c!),.3C=}_1}_1?{.0,"
|
||||
":(i11)^P92]1}'(c;),.1C=?{${:2^[00}:6^[10}'(cl),.1C=?{f,t,:(i10)^,:9^[1"
|
||||
"3}'(cv),.1C=?{${f,f,:(i10)^,:9^[03}X1]1}'(cu),.1C=?{${t,f,:(i10)^,:9^["
|
||||
"03}E1]1}'(cr),.1C=?{:(i10)^]1}'(cb),.1C=?{f,t,:8^,:9^[13}'(ck),.1C=?{:"
|
||||
"8^]1}'(c.),.1C=?{:7^]1}'(c'),.1C=?{${:2^[00},'(y5:quote),l2]1}'(c`),.1"
|
||||
"C=?{${:2^[00},'(y10:quasiquote),l2]1}'(c,),.1C=?{${:2^[00},'(y7:unquot"
|
||||
"e),l2]1}'(c@),.1C=?{${:2^[00},'(y16:unquote-splicing),l2]1}'(c&),.1C=?"
|
||||
"{${:2^[00}b]1}'(cF),.1C=,.0?{.0}{'(cN),.2C=}_1?{'(cF),.1C=:!5:5^,:(i12"
|
||||
")P79:6^[10}'(c#),.1C=,.0?{.0}{'(c=),.2C=}_1?{:0?{${:(i12),'(y5:port:),"
|
||||
"'(s44:#N=/#N# notation is not allowed in this mode),@(y10:read-error)["
|
||||
"03}}'(cn),:(i11)^P92,'(c#),.2C=?{.0I0?{:4^,.1A3}{f},.0?{.0d]3}:(i12),'"
|
||||
"(y5:port:),.3,'(s21:unknown #n# reference),@(y10:read-error)[34}.0I0~?"
|
||||
"{:(i12),'(y5:port:),.2,'(s21:invalid #n= reference),@(y10:read-error)["
|
||||
"24}:4^,.1A3?{:(i12),'(y5:port:),.2,'(s18:duplicate #n= tag:),@(y10:rea"
|
||||
"d-error)[24}fb,:4^,${.3,:3^[01},.3cc:!4${:2^[00},${.2,:1^[01}?{:(i12),"
|
||||
"'(y5:port:),.4,'(s25:#n= has a label as target),@(y10:read-error)[44}."
|
||||
"0,.2sz.0]4}:(i12),'(y5:port:),:(i11)^P90,.3,'(s13:invalid token),@(y10"
|
||||
":read-error)[15}.!3.3,.7,&2{%0${:1^[00},.0R8?{:0,'(y5:port:),'(s22:une"
|
||||
"xpected end of file),@(y10:read-error)[13}Y9,.1O0?{:0,'(y5:port:),'0,."
|
||||
"3O4,'(s18:unexpected token: ),Sa2,@(y10:read-error)[13}.0]1}.!4.3,.5,:"
|
||||
"1,.9,&4{%3f,f,${:3^[00},,#0:3,.1,:0,.9,:1,.9,:2,.(i12),&8{%3.0R8?{:5,'"
|
||||
"(y5:port:),'(s41:eof inside list -- unbalanced parentheses),@(y10:read"
|
||||
"-error)[33}:2,.1q?{.2?{.1]3}n]3}:0?{:3^,.1q}{f}?{${:1^[00},${:7^[00},:"
|
||||
"2,.1q?{.4?{.1,.5sd.3]5}:5,'(y5:port:),'(s14:unexpected dot),@(y10:read"
|
||||
"-error)[53}:5,'(y5:port:),.2,'(s24:too many forms after dot),@(y10:rea"
|
||||
"d-error)[54}:3^,.1q?{:5,'(y5:port:),'(s23:unexpected dot notation),@(y"
|
||||
"10:read-error)[33}Y9,.1O0?{:5,'(y5:port:),'0,.3O4,'(s18:unexpected tok"
|
||||
"en: ),Sa2,@(y10:read-error)[33}:4?{.0I0~,.0?{.0}{'0,.2I<,.0?{.0}{'(i25"
|
||||
"5),.3I>}_1}_1}{f}?{:5,'(y5:port:),.2,'(s30:invalid byte inside bytevec"
|
||||
"tor),@(y10:read-error)[34}.2~?{.0,l1,.0,.1,${:7^[00},:6^[43}.0,l1,.0,."
|
||||
"4sd.0,.3,${:7^[00},:6^[43}.!0.0^_1[33}.!5${.5^[00},Y9,.1O0~?{.3^u?{.0]"
|
||||
"(i10)}.0,:0^[(i10)1}.7,'(y5:port:),'0,.3O4,'(s18:unexpected token: ),S"
|
||||
"a2,@(y10:read-error)[(i10)3}_8@!(y5:%25read)",
|
||||
|
||||
"C", 0,
|
||||
"&0{%1f,f,.2,@(y5:%25read)[13}%x,&0{%0f,f,Pi,@(y5:%25read)[03}%x,&2{|00"
|
||||
|
@ -1152,9 +1027,9 @@ char *s_code[] = {
|
|||
"?{.7d,${'2,.7,@(y11:string-copy)[02},.3^d,.(i12)[(i10)3}.1^?{.1^a?{'2,"
|
||||
".3=?{.7dp}{f}}{f}}{f}?{.7dd,.8da,.3^d,.(i12)[(i10)3}.1^?{.1^a}{f}?{.0^"
|
||||
",'(s23:missing option argument),.6^[(i10)2}.1^?{.1^a~?{'2,.3>}{f}}{f}?"
|
||||
"{.7d,${'2,.7,@(y11:string-copy)[02},'(s1:-)S6c,f,.3^d,.(i12)[(i10)3}.1"
|
||||
"^?{.1^a~}{f}?{.7d,f,.3^d,.(i12)[(i10)3}.0^,'(s14:unknown option),.6^[("
|
||||
"i10)2",
|
||||
"{.7d,${'2,.7,@(y11:string-copy)[02},'(s1:-),Sa2c,f,.3^d,.(i12)[(i10)3}"
|
||||
".1^?{.1^a~}{f}?{.7d,f,.3^d,.(i12)[(i10)3}.0^,'(s14:unknown option),.6^"
|
||||
"[(i10)2",
|
||||
|
||||
"P", "print-command-line-options",
|
||||
"%!1,,,,#0#1#2#3.4p?{.4a}{P11}.!0&0{%1.0ddda,.1dda,.2da,,,,#0#1#2.3?{.3"
|
||||
|
|
105
t.c
105
t.c
|
@ -62,8 +62,8 @@ char *t_code[] = {
|
|||
"sexp-case;y3:key;y6:clause;y7:clauses;y3:...;;;;",
|
||||
|
||||
"C", 0,
|
||||
"'0,#0.0,&1{%!0'1,:0^I+:!0.0u,.0?{.0}{.1aY0~}_1?{'(i10),:0^X6,'(s1:#)S6"
|
||||
"X5]1}'(i10),:0^X6,'(s1:#)S6,.1aX4S6X5]1}_1@!(y6:gensym)",
|
||||
"'0,#0.0,&1{%!0'1,:0^I+:!0.0u,.0?{.0}{.1aY0~}_1?{'(i10),:0^X6,'(s1:#),S"
|
||||
"a2X5]1}'(i10),:0^X6,'(s1:#),Sa2,.1aX4,Sa2X5]1}_1@!(y6:gensym)",
|
||||
|
||||
"P", "remove!",
|
||||
"%3.1,f,f,,#0.0,.7,.6,&3{%3.2p~?{.1?{.2,.2sd.0]3}.2]3}${.4a,:0,:1[02}?{"
|
||||
|
@ -77,7 +77,7 @@ char *t_code[] = {
|
|||
"%1.0u?{n]1}.0du?{.0a]1}${.2d,@(y7:append*)[01},.1aL6]1",
|
||||
|
||||
"P", "string-append*",
|
||||
"%1.0,@(y14:%25string-append),@(y13:apply-to-list)[12",
|
||||
"%1.0,@(y13:string-append),@(y13:apply-to-list)[12",
|
||||
|
||||
"P", "list1?",
|
||||
"%1.0p?{.0du]1}f]1",
|
||||
|
@ -108,7 +108,7 @@ char *t_code[] = {
|
|||
"%2${.3,.3,f,@(y12:error-object)[03},@(y5:raise)[21",
|
||||
|
||||
"P", "warning*",
|
||||
"%2Pe,.2,.2,'(s9:Warning: )S6,@(y19:print-error-message)[23",
|
||||
"%2Pe,.2,.2,'(s9:Warning: ),Sa2,@(y19:print-error-message)[23",
|
||||
|
||||
"P", "idslist?",
|
||||
"%1.0u?{t]1}.0p?{${.2a,@(y3:id?)[01}?{.0d,@(y8:idslist?)[11}f]1}.0,@(y3"
|
||||
|
@ -225,7 +225,7 @@ char *t_code[] = {
|
|||
"0^_1[11",
|
||||
|
||||
"P", "x-error",
|
||||
"%!1.0,.2,'(s13:transformer: )S6,@(y6:error*)[22",
|
||||
"%!1.0,.2,'(s13:transformer: ),Sa2,@(y6:error*)[22",
|
||||
|
||||
"P", "check-syntax",
|
||||
"%3${.2,.4,@(y11:sexp-match?)[02}~?{.0,.3,@(y7:x-error)[32}]3",
|
||||
|
@ -465,23 +465,23 @@ char *t_code[] = {
|
|||
"ake-list),.3,.5[02}?{&0{%1${'(s31:invalid make-list template args),'(l"
|
||||
"2:y8:<number>;y1:*;),.4,@(y12:check-syntax)[03}.0da,.1aL2]1}]2}${'(y13"
|
||||
":string-append),.3,.5[02}?{&0{%1${'(s35:invalid string-append template"
|
||||
" args),'(l2:y8:<string>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y14:%2"
|
||||
"5string-append),@(y13:apply-to-list)[12}]2}${'(y7:char<=?),.3,.5[02}?{"
|
||||
"&0{%1${'(s29:invalid char<=? template args),'(l2:y6:<char>;y3:...;),.4"
|
||||
",@(y12:check-syntax)[03}.0,@(y1:<),@(y13:apply-to-list)[12}]2}${'(y2:<"
|
||||
"=),.3,.5[02}?{&0{%1${'(s24:invalid <= template args),'(l2:y8:<number>;"
|
||||
"y3:...;),.4,@(y12:check-syntax)[03}.0,@(y1:<),@(y13:apply-to-list)[12}"
|
||||
"]2}${'(y1:+),.3,.5[02}?{&0{%1${'(s23:invalid + template args),'(l2:y8:"
|
||||
"<number>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y1:+),@(y13:apply-to-"
|
||||
"list)[12}]2}${'(y1:-),.3,.5[02}?{&0{%1${'(s23:invalid - template args)"
|
||||
",'(l2:y8:<number>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y1:-),@(y13:"
|
||||
"apply-to-list)[12}]2}${'(y10:id->string),.3,.5[02}?{&0{%1${'(s32:inval"
|
||||
"id id->string template args),'(l1:y4:<id>;),.4,@(y12:check-syntax)[03}"
|
||||
"${.2a,@(y7:id->sym)[01}X4]1}]2}${'(y10:string->id),.3,.5[02}?{.0,&1{%1"
|
||||
"${.2,'(l1:y8:<string>;),@(y11:sexp-match?)[02}?{.0aX5,:0,@(y12:id-rena"
|
||||
"me-as)[12}${.2,'(l2:y8:<string>;y4:<id>;),@(y11:sexp-match?)[02}?{.0aX"
|
||||
"5,.1da,@(y12:id-rename-as)[12}'(s32:invalid string->id template args),"
|
||||
"@(y7:x-error)[11}]2}f]2",
|
||||
" args),'(l2:y8:<string>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y13:st"
|
||||
"ring-append),@(y13:apply-to-list)[12}]2}${'(y7:char<=?),.3,.5[02}?{&0{"
|
||||
"%1${'(s29:invalid char<=? template args),'(l2:y6:<char>;y3:...;),.4,@("
|
||||
"y12:check-syntax)[03}.0,@(y1:<),@(y13:apply-to-list)[12}]2}${'(y2:<=),"
|
||||
".3,.5[02}?{&0{%1${'(s24:invalid <= template args),'(l2:y8:<number>;y3:"
|
||||
"...;),.4,@(y12:check-syntax)[03}.0,@(y1:<),@(y13:apply-to-list)[12}]2}"
|
||||
"${'(y1:+),.3,.5[02}?{&0{%1${'(s23:invalid + template args),'(l2:y8:<nu"
|
||||
"mber>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y1:+),@(y13:apply-to-lis"
|
||||
"t)[12}]2}${'(y1:-),.3,.5[02}?{&0{%1${'(s23:invalid - template args),'("
|
||||
"l2:y8:<number>;y3:...;),.4,@(y12:check-syntax)[03}.0,@(y1:-),@(y13:app"
|
||||
"ly-to-list)[12}]2}${'(y10:id->string),.3,.5[02}?{&0{%1${'(s32:invalid "
|
||||
"id->string template args),'(l1:y4:<id>;),.4,@(y12:check-syntax)[03}${."
|
||||
"2a,@(y7:id->sym)[01}X4]1}]2}${'(y10:string->id),.3,.5[02}?{.0,&1{%1${."
|
||||
"2,'(l1:y8:<string>;),@(y11:sexp-match?)[02}?{.0aX5,:0,@(y12:id-rename-"
|
||||
"as)[12}${.2,'(l2:y8:<string>;y4:<id>;),@(y11:sexp-match?)[02}?{.0aX5,."
|
||||
"1da,@(y12:id-rename-as)[12}'(s32:invalid string->id template args),@(y"
|
||||
"7:x-error)[11}]2}f]2",
|
||||
|
||||
"P", "syntax-rules*",
|
||||
"%4,,,,,,,,,,,,#0#1#2#3#4#5#6#7#8#9#(i10)#(i11).(i14),&1{%1:0,.1A0]1}.!"
|
||||
|
@ -760,10 +760,10 @@ char *t_code[] = {
|
|||
")S4W0]2}.1,'(c()W0${.3,.3,@(y21:write-serialized-sexp)[02}.1,'(c))W0]2",
|
||||
|
||||
"P", "c-error",
|
||||
"%!1.0,.2,'(s10:compiler: )S6,@(y6:error*)[22",
|
||||
"%!1.0,.2,'(s10:compiler: ),Sa2,@(y6:error*)[22",
|
||||
|
||||
"P", "c-warning",
|
||||
"%!1.0,.2,'(s10:compiler: )S6,@(y8:warning*)[22",
|
||||
"%!1.0,.2,'(s10:compiler: ),Sa2,@(y8:warning*)[22",
|
||||
|
||||
"P", "find-free*",
|
||||
"%2.0u?{n]2}${.3,.3d,@(y10:find-free*)[02},${.4,.4a,@(y9:find-free)[02}"
|
||||
|
@ -988,7 +988,7 @@ char *t_code[] = {
|
|||
|
||||
"P", "file-resolve-relative-to-base-path",
|
||||
"%2${.2,@(y14:path-relative?)[01}?{${.3,@(y19:base-path-separator)[01}?"
|
||||
"{.0,.2S6]2}.0,Zs,S11,.3,@(y14:%25string-append)[23}.0]2",
|
||||
"{.0,.2,Sa2]2}.0,Zs,S11,.3,Sa3]2}.0]2",
|
||||
|
||||
"C", 0,
|
||||
"n@!(y20:*current-file-stack*)",
|
||||
|
@ -1034,16 +1034,16 @@ char *t_code[] = {
|
|||
"P", "mangle-symbol->string",
|
||||
"%1,#0'(l5:c!;c$;c-;c_;c=;).!0n,.2X4X2,,#0.0,.4,&2{%2.0u?{.1A8X3]2}.0aC"
|
||||
"2,.0?{.0}{.1aC5}_1?{.1,.1ac,.1d,:1^[22}:0^,.1aA1?{.1,.1ac,.1d,:1^[22}'"
|
||||
"(i16),.1aX8E8,'2,.1S3<?{.0,'(s1:0)S6}{.0},.0SdX2,'(c%25)c,.4,.1A8L6,.4"
|
||||
"d,:1^[52}.!0.0^_1[22",
|
||||
"(i16),.1aX8E8,'2,.1S3<?{.0,'(s1:0),Sa2}{.0},.0SdX2,'(c%25)c,.4,.1A8L6,"
|
||||
".4d,:1^[52}.!0.0^_1[22",
|
||||
|
||||
"P", "listname->symbol",
|
||||
"%1,,,,#0#1#2#3'(s0:).!0'(s5:lib:/).!1'(s1:/).!2'(s1:/).!3.4L0~?{${.6,'"
|
||||
"(s20:invalid library name),@(y7:x-error)[02}}.1^,l1,.5,,#0.7,.1,.8,.8,"
|
||||
".7,&5{%2.0u?{${.3,:0^cA8,@(y14:%25string-append),@(y13:apply-to-list)["
|
||||
"02}X5]2}.0aY0?{.1,:1^c,${.3a,@(y21:mangle-symbol->string)[01}c,.1d,:3^"
|
||||
"[22}.0aI0?{.1,:2^c,'(i10),.2aE8c,.1d,:3^[22}:4,'(s20:invalid library n"
|
||||
"ame),@(y7:x-error)[22}.!0.0^_1[52",
|
||||
".7,&5{%2.0u?{${.3,:0^cA8,@(y13:string-append),@(y13:apply-to-list)[02}"
|
||||
"X5]2}.0aY0?{.1,:1^c,${.3a,@(y21:mangle-symbol->string)[01}c,.1d,:3^[22"
|
||||
"}.0aI0?{.1,:2^c,'(i10),.2aE8c,.1d,:3^[22}:4,'(s20:invalid library name"
|
||||
"),@(y7:x-error)[22}.!0.0^_1[52",
|
||||
|
||||
"P", "listname-segment->string",
|
||||
"%1.0Y0?{.0,@(y21:mangle-symbol->string)[11}.0I0?{'(i10),.1E8]1}.0,'(s3"
|
||||
|
@ -1060,12 +1060,12 @@ char *t_code[] = {
|
|||
"Zd,l1@!(y19:*library-path-list*)",
|
||||
|
||||
"P", "append-library-path!",
|
||||
"%1#0${.2^,@(y19:base-path-separator)[01}~?{Zs,S11,.1^S6.!0}.0^,l1,@(y1"
|
||||
"9:*library-path-list*)L6@!(y19:*library-path-list*)]1",
|
||||
"%1#0${.2^,@(y19:base-path-separator)[01}~?{Zs,S11,.1^,Sa2.!0}.0^,l1,@("
|
||||
"y19:*library-path-list*)L6@!(y19:*library-path-list*)]1",
|
||||
|
||||
"P", "prepend-library-path!",
|
||||
"%1#0${.2^,@(y19:base-path-separator)[01}~?{Zs,S11,.1^S6.!0}@(y19:*libr"
|
||||
"ary-path-list*),.1^,l1L6@!(y19:*library-path-list*)]1",
|
||||
"%1#0${.2^,@(y19:base-path-separator)[01}~?{Zs,S11,.1^,Sa2.!0}@(y19:*li"
|
||||
"brary-path-list*),.1^,l1L6@!(y19:*library-path-list*)]1",
|
||||
|
||||
"P", "find-library-path",
|
||||
"%1@(y19:*library-path-list*),,#0.0,.3,&2{%1.0p?{${'(s4:.sld),.3a,:0,@("
|
||||
|
@ -1573,12 +1573,12 @@ char *t_code[] = {
|
|||
"le),@(y5:error)[02}}_1}${.6R1,,#0.8,.1,&2{%1'(l2:c%0a;c%0d;),.1A1?{:1R"
|
||||
"0:1R1,:0^[11}]1}.!0.0^_1[01}'1,,#0.3,.7,.6,.3,.(i11),.7,.(i11),&7{%1:5"
|
||||
"R1R8~?{,,,,#0#1#2#3:5R0.!0:5R0.!1:5R0.!2.2^,.2^,.2^,l3.!3'(l3:cC;c%09;"
|
||||
"c%09;),.4^e?{${${:5,@(y9:read-line)[01},:6^[01}'1,.5+,:3^[51}'(cP),.1^"
|
||||
"v?{'(c%09),.2^v?{.2^R8~}{f}}{f}?{.2^,l1,:5R0,,#0:5,.1,:3,.(i10),:4,:0,"
|
||||
"&6{%2.0R8?{'(y3:eof),:2,:0^[22}'(c%09),.1v?{,#0.2A9X3X5.!0${${:5,@(y9:"
|
||||
"read-line)[01},.3^,:1^[02}'1,:2+,:3^[31}.1,.1c,:5R0,:4^[22}.!0.0^_1[52"
|
||||
"}'(l3:cM;c%09;c%09;),.4^e?{:2p?{:1^,n,n,:2c,'(y5:quote)cc,'(y4:main)c,"
|
||||
"@(y4:eval)[52}f]5}.3^,.5,:0^[52}]1}.!0.0^_1[61",
|
||||
"c%09;),.4^e?{${:5R6,:6^[01}'1,.5+,:3^[51}'(cP),.1^v?{'(c%09),.2^v?{.2^"
|
||||
"R8~}{f}}{f}?{.2^,l1,:5R0,,#0:5,.1,:3,.(i10),:4,:0,&6{%2.0R8?{'(y3:eof)"
|
||||
",:2,:0^[22}'(c%09),.1v?{,#0.2A9X3X5.!0${:5R6,.3^,:1^[02}'1,:2+,:3^[31}"
|
||||
".1,.1c,:5R0,:4^[22}.!0.0^_1[52}'(l3:cM;c%09;c%09;),.4^e?{:2p?{:1^,n,n,"
|
||||
":2c,'(y5:quote)cc,'(y4:main)c,@(y4:eval)[52}f]5}.3^,.5,:0^[52}]1}.!0.0"
|
||||
"^_1[61",
|
||||
|
||||
"P", "run-fasl",
|
||||
"%2,#0.2,.2c.!0.0,&1{%1:0^,.1,@(y18:run-fasl-from-port)[12},.2,@(y28:ca"
|
||||
|
@ -1691,17 +1691,16 @@ char *t_code[] = {
|
|||
"(i11),&5{%0:4,&1{%!0.0,&1{%0:0,@(y6:values),@(y13:apply-to-list)[02},:"
|
||||
"0[11},:0,:1,:2,:3,&4{%0${:1,:2,:3,@(y9:repl-read)[03},,#0:0,:3,:2,:1,."
|
||||
"4,&5{%1.0R8~?{:2?{${.2,'(l2:y7:unquote;y1:*;),@(y11:sexp-match?)[02}}{"
|
||||
"f}?{${:1,${:3,@(y9:read-line)[01},.4da,@(y17:repl-exec-command)[03}}{$"
|
||||
"{:1,:4,.4,@(y22:repl-evaluate-top-form)[03}}${:1,:2,:3,@(y9:repl-read)"
|
||||
"[03},:0^[11}]1}.!0.0^_1[01},@(y16:call-with-values)[02},.(i11),.(i11),"
|
||||
".(i11),.(i11),.(i11),.8,&6{%1${k0,.0,${.6,:1,:2,:3,:4,:5,&6{%0:5,${.2,"
|
||||
"@(y13:error-object?)[01}?{Pe,.0,${.4,@(y20:error-object-message)[01}W4"
|
||||
".0W6${${.5,@(y22:error-object-irritants)[01},.3,&1{%1:0,.1W5:0W6]1},@("
|
||||
"y10:%25for-each1)[02}_1${:4^,@(y23:set-current-file-stack!)[01}:1?{:0,"
|
||||
":1,:2,:3,@(y14:repl-from-port)[14}]1}Pe,.0,'(s14:Unknown error:)W4.0W6"
|
||||
".0,.2W5.0W6_1${:4^,@(y23:set-current-file-stack!)[01}:1?{:0,:1,:2,:3,@"
|
||||
"(y14:repl-from-port)[14}]1},:0[01}_1_3}[10},@(y22:with-exception-handl"
|
||||
"er)[02}_1_3}[50",
|
||||
"f}?{${:1,:3R6,.4da,@(y17:repl-exec-command)[03}}{${:1,:4,.4,@(y22:repl"
|
||||
"-evaluate-top-form)[03}}${:1,:2,:3,@(y9:repl-read)[03},:0^[11}]1}.!0.0"
|
||||
"^_1[01},@(y16:call-with-values)[02},.(i11),.(i11),.(i11),.(i11),.(i11)"
|
||||
",.8,&6{%1${k0,.0,${.6,:1,:2,:3,:4,:5,&6{%0:5,${.2,@(y13:error-object?)"
|
||||
"[01}?{Pe,.0,${.4,@(y20:error-object-message)[01}W4.0W6${${.5,@(y22:err"
|
||||
"or-object-irritants)[01},.3,&1{%1:0,.1W5:0W6]1},@(y10:%25for-each1)[02"
|
||||
"}_1${:4^,@(y23:set-current-file-stack!)[01}:1?{:0,:1,:2,:3,@(y14:repl-"
|
||||
"from-port)[14}]1}Pe,.0,'(s14:Unknown error:)W4.0W6.0,.2W5.0W6_1${:4^,@"
|
||||
"(y23:set-current-file-stack!)[01}:1?{:0,:1,:2,:3,@(y14:repl-from-port)"
|
||||
"[14}]1},:0[01}_1_3}[10},@(y22:with-exception-handler)[02}_1_3}[50",
|
||||
|
||||
"P", "run-benchmark",
|
||||
"%2,,#0#1${.4,@(y15:open-input-file)[01}.!0Po.!1${${.4^,@(y14:read-code"
|
||||
|
@ -1737,7 +1736,7 @@ char *t_code[] = {
|
|||
"kint-options*)",
|
||||
|
||||
"C", 0,
|
||||
"'(s5:0.4.9)@!(y15:*skint-version*)",
|
||||
"'(s5:0.6.2)@!(y15:*skint-version*)",
|
||||
|
||||
"P", "implementation-version",
|
||||
"%0@(y15:*skint-version*)]0",
|
||||
|
|
Loading…
Reference in a new issue