ref: d33305eb8ba0cd5cc806c36881d62514d88f890c
parent: 07b1360acf3d14f651113f9b7113f74fd56c21f5
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Wed Apr 9 14:55:23 EDT 2025
better error reporting, read-stage location for all errors; sl_ios → ios
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -320,10 +320,10 @@
list->vec #fn("n1700}2:" #(vec) list->vec) list-head
#fn("n2E1L2;3?040<700=1K~52P:" #(list-head) list-head) list-ref #fn("n2700152<:" #(list-tail) list-ref)
list-tail #fn("n2701E523400:710=1K~62:" #(<= list-tail) list-tail) list?
- #fn("n10S;J@040B;3904700=61:" #(list?) list?) load #fn("n120021522285>123850>2{:" #(#fn(file)
+ #fn("n10S;J@040B;3904700=61:" #(list?) list?) load #fn("n120021522285>12385>1{:" #(#fn(file)
:read #fn("n0Ib48420A84>2_484<^1III63:" #(#fn("n320A51JG0F<21A510721514735063:24A514737215161:" #(#fn(io-eof?)
- #fn(read) load-process void #fn(io-close))))) #fn("n120A5142122F0e361:" #(#fn(io-close)
- #fn(raise) load-error))) load)
+ #fn(read) load-process void #fn(io-close))))) #fn("n120A51421220e261:" #(#fn(io-close)
+ #fn(raise) load-error))) load)
load-process #fn("n170061:" #(eval) load-process) lookup-sym
#fn("n31J5020:1<2108752883808288P:7201=82KM63:" #(global #fn(assq) lookup-sym) lookup-sym)
lower-define #fn("n1I2021?55140H;J804720513400:0<23C<0747505161:0<26CK02726e10Te185051e17805164:2974062:" #(#1#
@@ -384,10 +384,13 @@
#fn("n02071A62:" #(#fn(for-each) write))
#fn("n1A50420061:" #(#fn(raise)))) princ)
print #fn("z02071062:" #(#fn(for-each) write) print) print-exception
- #fn("n10B3e00<20C^0710r3523T072230T2425760515127554787605151@\x0e00B3Z00<29CS0710r3523I0722:760512;534780T51@\xe100B3P00<2<CI0710r2523?0722=0T2>53@\xbe00B3I00<2?CB0722@514720=f2@\xa200B3N00<2ACG07B76051514722C0T52@\x8107D0513m0710r2523c0780<51472275140T2E8551;J60485R37072@40788551^1@>0722F514780514727G61:" #(type-error
- length= princ "type error: expected " ", got " #fn(typeof) caddr ": " print bounds-error "index "
- " out of bounds for " unbound-error "eval: variable " " has no value" error "error: " load-error
- print-exception "in file " list? #fn(str?) "*** Unhandled exception: " *linefeed*) print-exception)
+ #fn("n170051;3N04700<51;3C04217205151;35040<853700=@30086;3?0486<R;360486<87;360486=853O0732485<512585T257685512756@30q48728CQ0732988<2:2;88T51275547<88T51@61872=CH0732>88T2?5347<88<51@\x190872@C@0732A88<2B53@\x040872CCB0732D5147388f2@\xed0872EC?07F88<514I:@\xd90872GCB0732H5147388f2@\xc20872ICB0732J5147388f2@\xab0872KC>0732L88<52@\x980872MCR0732N88<513702O@402P5147<88<51@q0872QCB0732R5147388f2@Z0872SQ;J804872TQ3;07388f2@?0732U5147<865147V60:" #(list?
+ #fn(io?) caar princ #fn(io-filename) ":" caddr ": " type-error "type error: expected " ", got "
+ #fn(typeof) print bounds-error "index " " out of bounds for " unbound-error "eval: variable " " has no value"
+ error "error: " load-error print-exception parse-error "parsing error: " arg-error "arguments error: "
+ key-error "key not found: " const-error #fn(keyword?)
+ "keywords are read-only: " "tried to modify a constant: " io-error "I/O error: " divide-error
+ memory-error "*** Unhandled exception: " newline) print-exception)
print-stack-trace #fn("n1IIb5b620852185>1_51420862285>1_5147374252627505252Eb82829868788>37:05162:" #(#0#
#fn("n32005182P2105121151C?022232487e361:25051E76278851512888A187>4|:" #(#fn(fn-name)
#fn(fn-code)
--- a/src/cvalues.c
+++ b/src/cvalues.c
@@ -612,8 +612,8 @@
}
if(iscvalue(v)){
sl_cv *pcv = ptr(v);
- sl_ios *x;
- if(isio(v) && (x = value2c(sl_ios*, v))->bm == bm_mem){
+ ios *x;
+ if(isio(v) && (x = value2c(ios*, v))->bm == bm_mem){
*pdata = x->buf;
*psz = x->size;
return;
--- a/src/io.c
+++ b/src/io.c
@@ -11,13 +11,13 @@
sl_type *sl_iotype;
static void
-print_io(sl_v v, sl_ios *f)
+print_io(sl_v v, ios *f)
{
- sl_ios *s = value2c(sl_ios*, v);
+ ios *s = value2c(ios*, v);
sl_print_str(f, "#<io");
- if(*s->loc.filename){
+ if(*s->filename){
sl_print_chr(f, ' ');
- sl_print_str(f, s->loc.filename);
+ sl_print_str(f, s->filename);
}
sl_print_chr(f, '>');
}
@@ -25,7 +25,7 @@
static void
free_io(sl_v self)
{
- sl_ios *s = value2c(sl_ios*, self);
+ ios *s = value2c(ios*, self);
ios_close(s);
ios_free(s);
}
@@ -33,8 +33,8 @@
static void
relocate_io(sl_v oldv, sl_v newv)
{
- sl_ios *olds = value2c(sl_ios*, oldv);
- sl_ios *news = value2c(sl_ios*, newv);
+ ios *olds = value2c(ios*, oldv);
+ ios *news = value2c(ios*, newv);
if(news->buf == &olds->local[0])
news->buf = &news->local[0];
}
@@ -67,12 +67,12 @@
}
sl_purefn
-sl_ios *
+ios *
toio(sl_v v)
{
if(sl_unlikely(!isio(v)))
cthrow(type_error("io", v), v);
- return value2c(sl_ios*, v);
+ return value2c(ios*, v);
}
BUILTIN("file", file)
@@ -94,9 +94,9 @@
}
if(!r && !w && !c && !t && !a)
r = true; // default to reading
- sl_v f = cvalue(sl_iotype, sizeof(sl_ios));
+ sl_v f = cvalue(sl_iotype, sizeof(ios));
char *fname = tostr(args[0]);
- sl_ios *s = value2c(sl_ios*, f);
+ ios *s = value2c(ios*, f);
if(ios_file(s, fname, r, w, c, t) == nil)
bthrow(lerrorf(sl_errio, "could not open \"%s\"", fname));
if(a)
@@ -108,7 +108,7 @@
{
if(nargs < 1 || nargs > 2)
argcount(nargs, 1);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
if(nargs == 1){
switch(s->bm){
case bm_none: return sl_nonesym;
@@ -137,8 +137,8 @@
{
argcount(nargs, 0);
USED(args);
- sl_v f = cvalue(sl_iotype, sizeof(sl_ios));
- sl_ios *s = value2c(sl_ios*, f);
+ sl_v f = cvalue(sl_iotype, sizeof(ios));
+ ios *s = value2c(ios*, f);
if(ios_mem(s, 0) == nil)
bthrow(lerrorf(sl_errmem, "could not allocate in-memory io"));
return f;
@@ -167,7 +167,7 @@
BUILTIN("io-peekrune", io_peekrune)
{
argcount(nargs, 1);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
Rune r;
int res;
if((res = ios_peekrune(s, &r)) == IOS_EOF)
@@ -181,7 +181,7 @@
BUILTIN("io-getrune", io_getrune)
{
argcount(nargs, 1);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
Rune r;
int res;
if((res = ios_getrune(s, &r)) == IOS_EOF)
@@ -195,7 +195,7 @@
BUILTIN("io-putrune", io_putrune)
{
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
if(!isrune(args[1]))
bthrow(type_error("rune", args[1]));
return fixnum(ios_putrune(s, torune(args[1])));
@@ -204,7 +204,7 @@
BUILTIN("io-skip", io_skip)
{
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
soffset off = tooffset(args[1]);
soffset res = ios_skip(s, off);
if(res < 0)
@@ -228,7 +228,7 @@
BUILTIN("io-truncate", io_truncate)
{
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
if(ios_trunc(s, tooffset(args[1])) < 0)
bthrow(lerrorf(sl_errio, "truncation failed"));
return sl_void;
@@ -251,7 +251,7 @@
BUILTIN("io-seek", io_seek)
{
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
usize pos = tosize(args[1]);
soffset res = ios_seek(s, (soffset)pos);
if(res < 0)
@@ -262,7 +262,7 @@
BUILTIN("io-pos", io_pos)
{
argcount(nargs, 1);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
soffset res = ios_pos(s);
if(res < 0)
return sl_nil;
@@ -273,7 +273,7 @@
{
if(nargs < 1 || nargs > 2)
argcount(nargs, 1);
- sl_ios *s;
+ ios *s;
s = nargs == 2 ? toio(args[1]) : toio(sym_value(sl_iooutsym));
sl_print(s, args[0]);
return args[0];
@@ -283,7 +283,7 @@
{
if(nargs != 3)
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
usize n;
sl_type *ft;
if(nargs == 3){
@@ -321,7 +321,7 @@
{
if(nargs < 2 || nargs > 4)
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
sl_v v = args[1];
if(isrune(v)){
if(nargs > 2)
@@ -358,11 +358,11 @@
sl_v str = cvalue_str(80);
sl_cv *cv = ptr(str);
u8int *data = cv_data(cv);
- sl_ios dest;
+ ios dest;
ios_mem(&dest, 0);
ios_setbuf(&dest, data, 80, 0);
u8int delim = get_delim_arg(args[1]);
- sl_ios *src = toio(args[0]);
+ ios *src = toio(args[0]);
usize n = ios_copyuntil(&dest, src, delim);
cv->len = n;
if(dest.buf != data){
@@ -382,8 +382,8 @@
BUILTIN("io-copyuntil", io_copyuntil)
{
argcount(nargs, 3);
- sl_ios *dest = toio(args[0]);
- sl_ios *src = toio(args[1]);
+ ios *dest = toio(args[0]);
+ ios *src = toio(args[1]);
u8int delim = get_delim_arg(args[2]);
return size_wrap(ios_copyuntil(dest, src, delim));
}
@@ -392,8 +392,8 @@
{
if(nargs < 2 || nargs > 3)
argcount(nargs, 2);
- sl_ios *dest = toio(args[0]);
- sl_ios *src = toio(args[1]);
+ ios *dest = toio(args[0]);
+ ios *src = toio(args[1]);
if(nargs == 3)
return size_wrap(ios_copy(dest, src, tosize(args[2])));
return size_wrap(ios_copyall(dest, src));
@@ -402,16 +402,16 @@
BUILTIN("io-filename", io_filename)
{
argcount(nargs, 1);
- return str_from_cstr(toio(args[0])->loc.filename);
+ return str_from_cstr(toio(args[0])->filename);
}
BUILTIN("io-set-filename!", io_set_filename)
{
argcount(nargs, 2);
- sl_ios *s = toio(args[0]);
+ ios *s = toio(args[0]);
char *f = tostr(args[1]);
- MEM_FREE(s->loc.filename);
- s->loc.filename = MEM_STRDUP(f);
+ MEM_FREE(s->filename);
+ s->filename = MEM_STRDUP(f);
return args[1];
}
@@ -446,7 +446,7 @@
{
sl_v str;
usize n;
- sl_ios *st = value2c(sl_ios*, *ps);
+ ios *st = value2c(ios*, *ps);
if(st->buf == &st->local[0]){
n = st->size;
str = cvalue_str(n);
@@ -466,7 +466,7 @@
BUILTIN("io->str", io_tostr)
{
argcount(nargs, 1);
- sl_ios *src = toio(args[0]);
+ ios *src = toio(args[0]);
if(src->bm != bm_mem)
bthrow(lerrorf(sl_errarg, "requires in-memory io"));
bool eof = ios_eof(src);
@@ -479,7 +479,7 @@
void
io_init(void)
{
- sl_iosym = mk_csym("io");
+ iosym = mk_csym("io");
sl_rdsym = mk_csym(":read");
sl_wrsym = mk_csym(":write");
sl_apsym = mk_csym(":append");
@@ -492,8 +492,8 @@
sl_whitespace = mk_csym(":whitespace");
sl_ioinsym = mk_csym("*io-in*");
sl_iooutsym = mk_csym("*io-out*");
- sl_iotype = define_opaque_type(sl_iosym, sizeof(sl_ios), &io_vtable, nil);
- set(mk_csym("*stdout*"), cvalue_from_ref(sl_iotype, ios_stdout, sizeof(sl_ios)));
- set(mk_csym("*stderr*"), cvalue_from_ref(sl_iotype, ios_stderr, sizeof(sl_ios)));
- set(mk_csym("*stdin*"), cvalue_from_ref(sl_iotype, ios_stdin, sizeof(sl_ios)));
+ sl_iotype = define_opaque_type(iosym, sizeof(ios), &io_vtable, nil);
+ set(mk_csym("*stdout*"), cvalue_from_ref(sl_iotype, ios_stdout, sizeof(ios)));
+ set(mk_csym("*stderr*"), cvalue_from_ref(sl_iotype, ios_stderr, sizeof(ios)));
+ set(mk_csym("*stdin*"), cvalue_from_ref(sl_iotype, ios_stdin, sizeof(ios)));
}
--- a/src/io.h
+++ b/src/io.h
@@ -1,4 +1,4 @@
-sl_ios *toio(sl_v v);
+ios *toio(sl_v v);
bool isio(sl_v v) sl_purefn;
sl_v io_to_str(sl_v *ps);
void io_init(void);
--- a/src/ios.c
+++ b/src/ios.c
@@ -3,9 +3,9 @@
#define MOST_OF(x) ((x) - ((x)>>4))
-sl_ios *ios_stdin = nil;
-sl_ios *ios_stdout = nil;
-sl_ios *ios_stderr = nil;
+ios *ios_stdin = nil;
+ios *ios_stdout = nil;
+ios *ios_stderr = nil;
/* OS-level primitive wrappers */
@@ -125,7 +125,7 @@
/* internal utility functions */
static u8int *
-_buf_realloc(sl_ios *s, usize sz)
+_buf_realloc(ios *s, usize sz)
{
u8int *temp;
@@ -165,7 +165,7 @@
// write a block of data into the buffer at the current position, resizing
// if necessary. returns # written.
static usize
-_write_grow(sl_ios *s, const void *data, usize n)
+_write_grow(ios *s, const void *data, usize n)
{
usize amt;
usize newsize;
@@ -202,7 +202,7 @@
/* interface functions, low level */
static usize
-_ios_read(sl_ios *s, u8int *dest, usize n, bool all)
+_ios_read(ios *s, u8int *dest, usize n, bool all)
{
usize tot = 0;
usize got, avail;
@@ -268,7 +268,7 @@
}
usize
-ios_read(sl_ios *s, void *dest, usize n)
+ios_read(ios *s, void *dest, usize n)
{
return _ios_read(s, dest, n, 0);
}
@@ -275,7 +275,7 @@
// ensure at least n bytes are buffered if possible. returns # available.
static usize
-ios_readprep(sl_ios *s, usize n)
+ios_readprep(ios *s, usize n)
{
if(s->state == bst_wr && s->bm != bm_mem){
ios_flush(s);
@@ -307,7 +307,7 @@
}
static void
-_write_update_pos(sl_ios *s)
+_write_update_pos(ios *s)
{
if(s->bpos > s->ndirty)
s->ndirty = s->bpos;
@@ -316,7 +316,7 @@
}
usize
-ios_write(sl_ios *s, const void *data, usize n)
+ios_write(ios *s, const void *data, usize n)
{
if(s->readonly || s->state == bst_closed || n == 0)
return 0;
@@ -371,7 +371,7 @@
}
soffset
-ios_seek(sl_ios *s, soffset pos)
+ios_seek(ios *s, soffset pos)
{
if(s->state == bst_closed)
return 0;
@@ -391,7 +391,7 @@
}
soffset
-ios_seek_end(sl_ios *s)
+ios_seek_end(ios *s)
{
if(s->state == bst_closed)
return 0;
@@ -409,7 +409,7 @@
}
soffset
-ios_skip(sl_ios *s, soffset offs)
+ios_skip(ios *s, soffset offs)
{
if(s->state == bst_closed)
return 0;
@@ -446,7 +446,7 @@
}
soffset
-ios_pos(sl_ios *s)
+ios_pos(ios *s)
{
if(s->state == bst_closed)
return 0;
@@ -469,7 +469,7 @@
}
int
-ios_trunc(sl_ios *s, soffset size)
+ios_trunc(ios *s, soffset size)
{
if(s->state == bst_closed || s->readonly || size < 0)
return -1;
@@ -488,7 +488,7 @@
}
bool
-ios_eof(sl_ios *s)
+ios_eof(ios *s)
{
if(s->state == bst_closed)
return true;
@@ -498,7 +498,7 @@
}
int
-ios_flush(sl_ios *s)
+ios_flush(ios *s)
{
if(s->ndirty == 0 || s->bm == bm_mem || s->buf == nil)
return 0;
@@ -545,7 +545,7 @@
}
void
-ios_close(sl_ios *s)
+ios_close(ios *s)
{
if(s->state == bst_closed)
return;
@@ -561,14 +561,14 @@
}
void
-ios_free(sl_ios *s)
+ios_free(ios *s)
{
- MEM_FREE(s->loc.filename);
- s->loc.filename = nil;
+ MEM_FREE(s->filename);
+ s->filename = nil;
}
static void
-_buf_init(sl_ios *s, ios_bm bm)
+_buf_init(ios *s, ios_bm bm)
{
s->bm = bm;
if(s->bm == bm_mem || s->bm == bm_none){
@@ -582,7 +582,7 @@
}
u8int *
-ios_takebuf(sl_ios *s, usize *psize)
+ios_takebuf(ios *s, usize *psize)
{
u8int *buf;
@@ -611,7 +611,7 @@
}
int
-ios_setbuf(sl_ios *s, u8int *buf, usize size, bool own)
+ios_setbuf(ios *s, u8int *buf, usize size, bool own)
{
ios_flush(s);
usize nvalid = size < s->size ? size : s->size;
@@ -632,7 +632,7 @@
}
int
-ios_bufmode(sl_ios *s, ios_bm mode)
+ios_bufmode(ios *s, ios_bm mode)
{
// no fd; can only do mem-only buffering
if(s->fd == -1 && mode != bm_mem)
@@ -642,7 +642,7 @@
}
void
-ios_set_readonly(sl_ios *s)
+ios_set_readonly(ios *s)
{
if(s->readonly)
return;
@@ -652,7 +652,7 @@
}
static usize
-ios_copy_(sl_ios *to, sl_ios *from, usize nbytes, bool all)
+ios_copy_(ios *to, ios *from, usize nbytes, bool all)
{
// FIXME(sigrid): ios doesn't really care about errors
// this needs a big fix everywhere
@@ -686,13 +686,13 @@
}
usize
-ios_copy(sl_ios *to, sl_ios *from, usize nbytes)
+ios_copy(ios *to, ios *from, usize nbytes)
{
return ios_copy_(to, from, nbytes, 0);
}
usize
-ios_copyall(sl_ios *to, sl_ios *from)
+ios_copyall(ios *to, ios *from)
{
return ios_copy_(to, from, 0, true);
}
@@ -700,7 +700,7 @@
#define LINE_CHUNK_SIZE 160
usize
-ios_copyuntil(sl_ios *to, sl_ios *from, u8int delim)
+ios_copyuntil(ios *to, ios *from, u8int delim)
{
usize total = 0, avail = from->size - from->bpos;
bool first = true;
@@ -731,7 +731,7 @@
}
static void
-_ios_init(sl_ios *s)
+_ios_init(ios *s)
{
// put all fields in a sane initial state
memset(s, 0, sizeof(*s));
@@ -745,8 +745,8 @@
/* io object initializers. we do no allocation. */
-sl_ios *
-ios_file(sl_ios *s, char *fname, bool rd, bool wr, bool creat, bool trunc)
+ios *
+ios_file(ios *s, char *fname, bool rd, bool wr, bool creat, bool trunc)
{
int fd;
if(!(rd || wr)) // must specify read and/or write
@@ -774,18 +774,18 @@
return nil;
}
-sl_ios *
-ios_mem(sl_ios *s, usize initsize)
+ios *
+ios_mem(ios *s, usize initsize)
{
_ios_init(s);
s->bm = bm_mem;
- s->loc.filename = MEM_STRDUP("");
+ s->filename = MEM_STRDUP("");
_buf_realloc(s, initsize);
return s;
}
-sl_ios *
-ios_static_buffer(sl_ios *s, const u8int *buf, usize sz)
+ios *
+ios_static_buffer(ios *s, const u8int *buf, usize sz)
{
ios_mem(s, 0);
ios_setbuf(s, (u8int*)buf, sz, 0);
@@ -794,8 +794,8 @@
return s;
}
-sl_ios *
-ios_fd(sl_ios *s, int fd, const char *name, bool isfile, bool own)
+ios *
+ios_fd(ios *s, int fd, const char *name, bool isfile, bool own)
{
_ios_init(s);
s->fd = fd;
@@ -803,7 +803,7 @@
s->rereadable = true;
_buf_init(s, bm_block);
s->ownfd = own;
- s->loc.filename = MEM_STRDUP(name);
+ s->filename = MEM_STRDUP(name);
return s;
}
@@ -810,14 +810,14 @@
void
ios_init_std(void)
{
- ios_stdin = MEM_ALLOC(sizeof(sl_ios));
+ ios_stdin = MEM_ALLOC(sizeof(ios));
ios_fd(ios_stdin, STDIN_FILENO, "*stdin*", false, false);
- ios_stdout = MEM_ALLOC(sizeof(sl_ios));
+ ios_stdout = MEM_ALLOC(sizeof(ios));
ios_fd(ios_stdout, STDOUT_FILENO, "*stdout*", false, false);
ios_stdout->bm = bm_line;
- ios_stderr = MEM_ALLOC(sizeof(sl_ios));
+ ios_stderr = MEM_ALLOC(sizeof(ios));
ios_fd(ios_stderr, STDERR_FILENO, "*stderr*", false, false);
ios_stderr->bm = bm_none;
}
@@ -825,7 +825,7 @@
/* higher level interface */
int
-ios_putc(sl_ios *s, int c)
+ios_putc(ios *s, int c)
{
char ch = c;
@@ -840,7 +840,7 @@
}
static void
-ios_loc(sl_ios *s, u8int ch)
+ios_move(ios *s, u8int ch)
{
if(ch == '\n'){
s->loc.lineno++;
@@ -862,7 +862,7 @@
}
int
-ios_getc(sl_ios *s)
+ios_getc(ios *s)
{
u8int ch;
if(s->state == bst_rd && s->bpos < s->size)
@@ -869,12 +869,12 @@
ch = s->buf[s->bpos++];
else if(s->_eof || ios_read(s, &ch, 1) < 1)
return IOS_EOF;
- ios_loc(s, ch);
+ ios_move(s, ch);
return ch;
}
int
-ios_peekc(sl_ios *s)
+ios_peekc(ios *s)
{
if(s->bpos < s->size)
return (u8int)s->buf[s->bpos];
@@ -887,7 +887,7 @@
}
int
-ios_peekrune(sl_ios *s, Rune *r)
+ios_peekrune(ios *s, Rune *r)
{
int n = s->bpos+UTFmax <= s->size ? UTFmax : ios_readprep(s, UTFmax);
if(n < UTFmax && !fullrune((char*)s->buf + s->bpos, n))
@@ -903,7 +903,7 @@
}
int
-ios_getrune(sl_ios *s, Rune *r)
+ios_getrune(ios *s, Rune *r)
{
int c;
usize i;
@@ -929,7 +929,7 @@
}
int
-ios_putrune(sl_ios *s, Rune r)
+ios_putrune(ios *s, Rune r)
{
char buf[UTFmax];
return ios_write(s, buf, runetochar(buf, &r));
@@ -936,16 +936,16 @@
}
void
-ios_purge(sl_ios *s)
+ios_purge(ios *s)
{
if(s->state == bst_rd){
for(; s->bpos < s->size; s->bpos++)
- ios_loc(s, s->buf[s->bpos]);
+ ios_move(s, s->buf[s->bpos]);
}
}
int
-ios_vprintf(sl_ios *s, const char *format, va_list args)
+ios_vprintf(ios *s, const char *format, va_list args)
{
char buf[256];
char *str;
@@ -976,7 +976,7 @@
}
int
-ios_printf(sl_ios *s, const char *format, ...)
+ios_printf(ios *s, const char *format, ...)
{
va_list args;
int c;
--- a/src/ios.h
+++ b/src/ios.h
@@ -19,10 +19,9 @@
#define IOS_BUFSIZE 32768
typedef struct {
- char *filename;
- u32int lineno;
- u32int colno;
-}sl_loc;
+ int lineno;
+ int colno;
+}ios_loc;
typedef struct {
u8int *buf; // start of buffer
@@ -31,7 +30,8 @@
usize bpos; // current position in buffer
usize ndirty; // # bytes at &buf[0] that need to be written
soffset fpos; // cached file pos
- sl_loc loc;
+ char *filename;
+ ios_loc loc;
ios_bm bm;
int colnowait;
@@ -53,60 +53,60 @@
bool rereadable;
u8int local[IOS_INLSIZE];
-}sl_ios;
+}ios;
void *llt_memrchr(const void *s, int c, usize n) sl_purefn;
/* low-level interface functions */
-usize ios_read(sl_ios *s, void *dest, usize n);
-usize ios_write(sl_ios *s, const void *data, usize n);
-soffset ios_seek(sl_ios *s, soffset pos); // absolute seek
-soffset ios_seek_end(sl_ios *s);
-soffset ios_skip(sl_ios *s, soffset offs); // relative seek
-soffset ios_pos(sl_ios *s); // get current position
-int ios_trunc(sl_ios *s, soffset size);
-bool ios_eof(sl_ios *s) sl_purefn;
-int ios_flush(sl_ios *s);
-void ios_close(sl_ios *s);
-void ios_free(sl_ios *s);
-u8int *ios_takebuf(sl_ios *s, usize *psize); // null-terminate and release buffer to caller
+usize ios_read(ios *s, void *dest, usize n);
+usize ios_write(ios *s, const void *data, usize n);
+soffset ios_seek(ios *s, soffset pos); // absolute seek
+soffset ios_seek_end(ios *s);
+soffset ios_skip(ios *s, soffset offs); // relative seek
+soffset ios_pos(ios *s); // get current position
+int ios_trunc(ios *s, soffset size);
+bool ios_eof(ios *s) sl_purefn;
+int ios_flush(ios *s);
+void ios_close(ios *s);
+void ios_free(ios *s);
+u8int *ios_takebuf(ios *s, usize *psize); // null-terminate and release buffer to caller
// set buffer space to use
-int ios_setbuf(sl_ios *s, u8int *buf, usize size, bool own);
-int ios_bufmode(sl_ios *s, ios_bm mode);
-void ios_set_readonly(sl_ios *s);
-usize ios_copy(sl_ios *to, sl_ios *from, usize nbytes);
-usize ios_copyall(sl_ios *to, sl_ios *from);
-usize ios_copyuntil(sl_ios *to, sl_ios *from, u8int delim);
+int ios_setbuf(ios *s, u8int *buf, usize size, bool own);
+int ios_bufmode(ios *s, ios_bm mode);
+void ios_set_readonly(ios *s);
+usize ios_copy(ios *to, ios *from, usize nbytes);
+usize ios_copyall(ios *to, ios *from);
+usize ios_copyuntil(ios *to, ios *from, u8int delim);
/* io creation */
-sl_ios *ios_file(sl_ios *s, char *fname, bool rd, bool wr, bool create, bool trunc);
-sl_ios *ios_mem(sl_ios *s, usize initsize);
-sl_ios *ios_static_buffer(sl_ios *s, const u8int *buf, usize sz);
-sl_ios *ios_fd(sl_ios *s, int fd, const char *name, bool isfile, bool own);
+ios *ios_file(ios *s, char *fname, bool rd, bool wr, bool create, bool trunc);
+ios *ios_mem(ios *s, usize initsize);
+ios *ios_static_buffer(ios *s, const u8int *buf, usize sz);
+ios *ios_fd(ios *s, int fd, const char *name, bool isfile, bool own);
-extern sl_ios *ios_stdin;
-extern sl_ios *ios_stdout;
-extern sl_ios *ios_stderr;
+extern ios *ios_stdin;
+extern ios *ios_stdout;
+extern ios *ios_stderr;
void ios_init_std(void);
/* high-level functions - output */
-int ios_putrune(sl_ios *s, Rune r);
-int ios_printf(sl_ios *s, const char *format, ...) sl_printfmt(2, 3);
-int ios_vprintf(sl_ios *s, const char *format, va_list args) sl_printfmt(2, 0);
+int ios_putrune(ios *s, Rune r);
+int ios_printf(ios *s, const char *format, ...) sl_printfmt(2, 3);
+int ios_vprintf(ios *s, const char *format, va_list args) sl_printfmt(2, 0);
/* high-level io functions - input */
-int ios_peekrune(sl_ios *s, Rune *r);
-int ios_getrune(sl_ios *s, Rune *r);
+int ios_peekrune(ios *s, Rune *r);
+int ios_getrune(ios *s, Rune *r);
// discard data buffered for reading
-void ios_purge(sl_ios *s);
+void ios_purge(ios *s);
/* stdio-style functions */
#define IOS_EOF (-1)
-int ios_putc(sl_ios *s, int c);
-int ios_getc(sl_ios *s);
-int ios_peekc(sl_ios *s);
+int ios_putc(ios *s, int c);
+int ios_getc(ios *s);
+int ios_peekc(ios *s);
#define ios_puts(s, str) ios_write(s, str, strlen(str))
/*
--- a/src/plan9/lsd.c
+++ b/src/plan9/lsd.c
@@ -9,7 +9,7 @@
static sl_v lsd_gpregsym, lsd_fpregsym, lsd_regsym, lsd_symsym, lsd_framesym;
static Map* coremap;
static Fhdr fhdr;
-static sl_ios *proc_stdin;
+static ios *proc_stdin;
void
lsd_init(void)
@@ -161,7 +161,7 @@
for(i = 0; i < coremap->nsegs; i++)
if(coremap->seg[i].inuse && coremap->seg[i].fd >= 0)
close(coremap->seg[i].fd);
- free(coremap);
+ MEM_FREE(coremap);
coremap = nil;
}
@@ -343,8 +343,8 @@
pid = newproc(argv, &p);
if(proc_stdin != nil){
- free(proc_stdin->loc.filename);
- free(proc_stdin);
+ MEM_FREE(proc_stdin->filename);
+ MEM_FREE(proc_stdin);
}
proc_stdin = MEM_ALLOC(sizeof(*proc_stdin));
ios_fd(proc_stdin, p, "proc-stdin", false, false);
--- a/src/print.c
+++ b/src/print.c
@@ -8,7 +8,7 @@
#define LOG2_10 3.321928094887362347870319429489
static inline void
-outc(sl_ios *f, char c)
+outc(ios *f, char c)
{
if(ios_putc(f, c) != 1)
lerrorf(sl_errio, "write failed");
@@ -19,7 +19,7 @@
}
static inline void
-outsn(sl_ios *f, const char *s, usize n)
+outsn(ios *f, const char *s, usize n)
{
if(ios_write(f, s, n) != n)
lerrorf(sl_errio, "write failed");
@@ -33,7 +33,7 @@
}
static inline void
-outs(sl_ios *f, const char *s)
+outs(ios *f, const char *s)
{
outsn(f, s, strlen(s));
}
@@ -44,7 +44,7 @@
}while(0)
static int
-outindent(sl_ios *f, int n)
+outindent(ios *f, int n)
{
// move back to left margin if we get too indented
if(n > sl.scr_width-12)
@@ -65,13 +65,13 @@
}
void
-sl_print_chr(sl_ios *f, char c)
+sl_print_chr(ios *f, char c)
{
outc(f, c);
}
void
-sl_print_str(sl_ios *f, const char *s)
+sl_print_str(ios *f, const char *s)
{
outs(f, s);
}
@@ -123,7 +123,7 @@
}
static void
-print_sym_name(sl_ios *f, const char *name)
+print_sym_name(ios *f, const char *name)
{
int i;
bool escape = false, charescape = false;
@@ -289,7 +289,7 @@
}
static void
-print_cons(sl_ios *f, sl_v v)
+print_cons(ios *f, sl_v v)
{
sl_v cd;
const char *op;
@@ -383,12 +383,12 @@
}
}
-static void unboxed_print(sl_ios *f, sl_v v);
-static void cvalue_print(sl_ios *f, sl_v v);
-static void rune_print(sl_ios *f, Rune r);
+static void unboxed_print(ios *f, sl_v v);
+static void cvalue_print(ios *f, sl_v v);
+static void rune_print(ios *f, Rune r);
static bool
-print_circle_prefix(sl_ios *f, sl_v v)
+print_circle_prefix(ios *f, sl_v v)
{
sl_v label;
if((label = (sl_v)ptrhash_get(&sl.printconses, (void*)v)) != (sl_v)HT_NOTFOUND){
@@ -410,7 +410,7 @@
}
void
-sl_print_child(sl_ios *f, sl_v v)
+sl_print_child(ios *f, sl_v v)
{
const char *name;
if(sl.print_level >= 0 && sl.p_level >= sl.print_level && (iscons(v) || isvec(v) || isfn(v))){
@@ -527,7 +527,7 @@
}
static void
-print_str(sl_ios *f, const char *str, usize sz)
+print_str(ios *f, const char *str, usize sz)
{
char buf[64];
u8int c;
@@ -655,7 +655,7 @@
}
static void
-rune_print(sl_ios *f, Rune r)
+rune_print(ios *f, Rune r)
{
char seq[UTFmax+1];
int n, nb = runetochar(seq, &r);
@@ -698,7 +698,7 @@
// printing in a context where a type is already implied, e.g. inside
// an array.
static void
-cvalue_printdata(sl_ios *f, void *data, usize len, sl_v type, bool weak)
+cvalue_printdata(ios *f, void *data, usize len, sl_v type, bool weak)
{
int n;
if(type == sl_utf8sym){
@@ -855,7 +855,7 @@
}
static void
-unboxed_print(sl_ios *f, sl_v v)
+unboxed_print(ios *f, sl_v v)
{
if(isrune(v)){
rune_print(f, torune(v));
@@ -870,7 +870,7 @@
}
static void
-cvalue_print(sl_ios *f, sl_v v)
+cvalue_print(ios *f, sl_v v)
{
sl_cv *cv = ptr(v);
void *data = cvalue_data(v);
@@ -906,7 +906,7 @@
}
void
-sl_print(sl_ios *f, sl_v v)
+sl_print(ios *f, sl_v v)
{
sl.print_pretty = sym_value(sl_printprettysym) != sl_nil;
if(sl.print_pretty)
--- a/src/print.h
+++ b/src/print.h
@@ -1,7 +1,7 @@
#pragma once
-void sl_print(sl_ios *f, sl_v v);
+void sl_print(ios *f, sl_v v);
void print_traverse(sl_v v);
-void sl_print_chr(sl_ios *f, char c);
-void sl_print_str(sl_ios *f, const char *s);
-void sl_print_child(sl_ios *f, sl_v v);
+void sl_print_chr(ios *f, char c);
+void sl_print_str(ios *f, const char *s);
+void sl_print_child(ios *f, sl_v v);
--- a/src/read.c
+++ b/src/read.c
@@ -17,7 +17,9 @@
struct Rctx {
sl_v tokval;
- sl_loc loc;
+ sl_v *source;
+ ios_loc loc0;
+ ios_loc loc;
u32int toktype;
bool ws;
char buf[1024];
@@ -25,7 +27,7 @@
static sl_v do_read_sexpr(Rctx *ctx, sl_v label);
-#define RS value2c(sl_ios*, sl.readstate->source)
+#define RS value2c(ios*, sl.readstate->source)
bool
sl_read_numtok(const char *tok, sl_v *pval, int base)
@@ -95,7 +97,7 @@
nextchar(Rctx *ctx)
{
int c;
- sl_ios *f = RS;
+ ios *f = RS;
do{
c = ios_getc(RS);
@@ -122,21 +124,16 @@
}
static _Noreturn void sl_printfmt(2, 3)
-parse_error(sl_loc *loc, const char *format, ...)
+parse_error(Rctx *ctx, const char *format, ...)
{
- char msgbuf[512];
+ char msgbuf[1024];
va_list args;
- int n;
- n = snprintf(msgbuf, sizeof(msgbuf), "%s:%"PRIu64":%"PRIu64": ",
- loc->filename, (u64int)loc->lineno, (u64int)loc->colno);
- if(n >= (int)sizeof(msgbuf))
- n = 0;
va_start(args, format);
- vsnprintf(msgbuf+n, sizeof(msgbuf)-n, format, args);
+ vsnprintf(msgbuf, sizeof(msgbuf), format, args);
sl_v msg = str_from_cstr(msgbuf);
va_end(args);
-
+ sl.readstate->errloc = ctx->loc;
sl_raise(mk_list2(sl_errparse, msg));
}
@@ -144,8 +141,10 @@
accumchar(Rctx *ctx, char c, int *pi)
{
ctx->buf[(*pi)++] = c;
- if(*pi >= (int)(sizeof(ctx->buf)-1))
- parse_error(&ctx->loc, "token too long");
+ if(*pi >= (int)(sizeof(ctx->buf)-1)){
+ ctx->buf[sizeof(ctx->buf)-64] = 0; // cut down to fit the whole message
+ parse_error(ctx, "token too long: %s…", ctx->buf);
+ }
}
// return: 1 if escaped (forced to be symbol)
@@ -182,7 +181,7 @@
nc++;
}
if(nc == 0)
- parse_error(&ctx->loc, "unexpected char: 0x%x", c);
+ parse_error(ctx, "unexpected char: 0x%x", c);
terminate:
ctx->buf[i++] = '\0';
return issym;
@@ -214,6 +213,7 @@
ctx->ws = false;
return TOK_NONE;
}
+ ctx->loc0 = RS->loc;
if(c == '(')
ctx->toktype = TOK_OPEN;
else if(c == ')')
@@ -238,7 +238,7 @@
}else if(c == '#'){
c = ch = ios_getc(RS);
if(ch == IOS_EOF)
- parse_error(&ctx->loc, "invalid read macro");
+ parse_error(ctx, "invalid read macro");
if(c == '.')
ctx->toktype = TOK_SHARPDOT;
else if(c == '\'')
@@ -246,12 +246,12 @@
else if(c == '\\'){
Rune cval;
if(ios_getrune(RS, &cval) == IOS_EOF)
- parse_error(&ctx->loc, "end of input in character constant");
+ parse_error(ctx, "EOI in character constant");
if(cval == 'u' || cval == 'U' || cval == 'x'){
read_token(ctx, 'u', 0);
if(ctx->buf[1] != '\0'){ // not a solitary 'u','U','x'
if(!sl_read_numtok(&ctx->buf[1], &ctx->tokval, 16))
- parse_error(&ctx->loc, "invalid hex character constant");
+ parse_error(ctx, "invalid hex character constant: %s", &ctx->buf[1]);
cval = numval(ctx->tokval);
}
}else if(cval >= 'a' && cval <= 'z'){
@@ -271,7 +271,7 @@
else if(ctx->tokval == sl_spacesym) cval = 0x20;
else if(ctx->tokval == sl_deletesym) cval = 0x7F;
else
- parse_error(&ctx->loc, "unknown character #\\%s", ctx->buf);
+ parse_error(ctx, "unknown character #\\%s", ctx->buf);
}
ctx->toktype = TOK_NUM;
ctx->tokval = mk_rune(cval);
@@ -278,7 +278,7 @@
}else if(c == '('){
ctx->toktype = TOK_SHARPOPEN;
}else if(c == '<'){
- parse_error(&ctx->loc, "unreadable object");
+ parse_error(ctx, "unreadable object");
}else if(isdigit(c)){
read_token(ctx, c, 1);
c = ios_getc(RS);
@@ -287,10 +287,10 @@
else if(c == '=')
ctx->toktype = TOK_LABEL;
else
- parse_error(&ctx->loc, "invalid label");
+ parse_error(ctx, "invalid label: #%s%c", ctx->buf, c);
x = strtoll(ctx->buf, &end, 10);
if(*end != '\0')
- parse_error(&ctx->loc, "invalid label");
+ parse_error(ctx, "invalid label: #%s%c", ctx->buf, c);
ctx->tokval = fixnum(x);
}else if(c == '!'){
// #! single line comment for shbang script support
@@ -305,7 +305,7 @@
ch = ios_getc(RS);
hashpipe_gotc:
if(ch == IOS_EOF)
- parse_error(&ctx->loc, "eof within comment");
+ parse_error(ctx, "eof within comment");
if(ch == '|'){
ch = ios_getc(RS);
if(ch == '#'){
@@ -337,7 +337,7 @@
read_token(ctx, ch, 0);
x = strtol(ctx->buf, &end, 10);
if(*end != '\0' || ctx->buf[0] == '\0')
- parse_error(&ctx->loc, "invalid gensym label");
+ parse_error(ctx, "invalid gensym label: #%s", ctx->buf);
ctx->toktype = TOK_GENSYM;
ctx->tokval = fixnum(x);
}else if(symchar(c)){
@@ -348,7 +348,7 @@
(c == 'd' && (base = 10)) ||
(c == 'x' && (base = 16))) && (isdigit_base(ctx->buf[1], base) || ctx->buf[1] == '-')){
if(!sl_read_numtok(&ctx->buf[1], &ctx->tokval, base))
- parse_error(&ctx->loc, "invalid base %d constant", base);
+ parse_error(ctx, "invalid base %d constant: %s", base, &ctx->buf[1]);
ctx->ws = false;
return (ctx->toktype = TOK_NUM);
}
@@ -356,7 +356,7 @@
ctx->toktype = TOK_SHARPSYM;
ctx->tokval = mk_sym(ctx->buf, true);
}else{
- parse_error(&ctx->loc, "unknown read macro");
+ parse_error(ctx, "unknown read macro");
}
}else if(c == ','){
ctx->toktype = TOK_COMMA;
@@ -433,7 +433,7 @@
ptrhash_put(&sl.readstate->backrefs, (void*)label, (void*)v);
while(peek(ctx) != closer){
if(ios_eof(RS))
- parse_error(&ctx->loc, "unexpected end of input");
+ parse_error(ctx, "unexpected EOI");
v = sl.sp[-1]; // reload after possible alloc in peek()
if(i >= vec_size(v)){
v = sl.sp[-1] = vec_grow(v, label != UNBOUND);
@@ -470,7 +470,7 @@
if(temp == nil){
if(buf == ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "out of memory reading verbatim string");
+ parse_error(ctx, "out of memory reading verbatim string");
}
buf = temp;
}
@@ -478,7 +478,7 @@
if(c == IOS_EOF){
if(buf != ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "unexpected end of input in verbatim string");
+ parse_error(ctx, "unexpected EOI in verbatim string");
}
if(c == 0xc2 && ios_peekc(RS) == 0xbb){ // »
ios_getc(RS);
@@ -515,7 +515,7 @@
if(temp == nil){
if(buf == ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "out of memory reading string");
+ parse_error(ctx, "out of memory reading string");
}
buf = temp;
}
@@ -523,7 +523,7 @@
if(c == IOS_EOF){
if(buf != ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "unexpected end of input in string");
+ parse_error(ctx, "unexpected EOI in string");
}
if(c == '"')
break;
@@ -532,7 +532,7 @@
if(c == IOS_EOF){
if(buf != ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "end of input in escape sequence");
+ parse_error(ctx, "EOI in escape sequence");
}
j = 0;
if(octal_digit(c)){
@@ -561,7 +561,7 @@
if(!j || r > Runemax){
if(buf != ctx->buf)
MEM_FREE(buf);
- parse_error(&ctx->loc, "invalid escape sequence");
+ parse_error(ctx, "invalid escape sequence");
}
if(ndig == 2)
buf[i++] = r;
@@ -574,14 +574,7 @@
if(esc == c && !strchr("\\'\"`", esc)){
if(buf != ctx->buf)
MEM_FREE(buf);
- sl_loc *l = &RS->loc;
- parse_error(
- &ctx->loc,
- "invalid escape sequence \\%c "PAtLoc,
- c,
- l->lineno,
- l->colno
- );
+ parse_error(ctx, "invalid escape sequence: \\%c", c);
}
buf[i++] = esc;
}
@@ -604,7 +597,7 @@
{
sl_v c, *pc, *pval, *ipval, *ipc;
u32int t;
- sl_loc loc0;
+ ios_loc loc0;
loc0 = RS->loc;
loc0.colno--;
@@ -613,8 +606,15 @@
ipc = sl.sp-1; // to keep track of current cons cell
t = peek(ctx);
while(t != closer){
- if(ios_eof(RS))
- parse_error(&loc0, "not closed: unexpected EOI "PAtLoc, ctx->loc.lineno, ctx->loc.colno);
+ if(ios_eof(RS)){
+ parse_error(
+ ctx,
+ "not closed: unexpected EOI: opened with '%c' "PAtLoc,
+ closer == TOK_CLOSE ? '(' : (closer == TOK_CLOSEB ? '[' : '{'),
+ loc0.lineno,
+ loc0.colno
+ );
+ }
c = alloc_cons(); car_(c) = cdr_(c) = sl_nil;
pc = ipc;
if(iscons(*pc))
@@ -638,13 +638,15 @@
cdr_(*pc) = c;
t = peek(ctx);
if(ios_eof(RS))
- parse_error(&ctx->loc, "unexpected end of input");
+ parse_error(ctx, "unexpected EOI");
if(t != closer){
take(ctx);
parse_error(
- &ctx->loc,
- "expected '%c'",
- closer == TOK_CLOSEB ? ']' : (closer == TOK_CLOSEC ? '}' : ')')
+ ctx,
+ "expected '%c': opened "PAtLoc,
+ closer == TOK_CLOSEB ? ']' : (closer == TOK_CLOSEC ? '}' : ')'),
+ loc0.lineno,
+ loc0.colno
);
}
}
@@ -658,8 +660,8 @@
static sl_v
do_read_sexpr(Rctx *ctx, sl_v label)
{
- sl_v v, sym, oldtokval, *head;
- sl_v *pv;
+ sl_v v, sym, oldtokval, *head, *pv;
+ ios_loc loc0;
u32int t;
char c;
@@ -706,6 +708,7 @@
// StreetLISP doesn't need symbol-function, so #' does nothing
return do_read_sexpr(ctx, label);
case TOK_SHARPSYM:
+ loc0 = ctx->loc0;
sym = ctx->tokval;
// constructor notation
c = nextchar(ctx);
@@ -712,7 +715,7 @@
ctx->loc = RS->loc;
if(c != '(' && c != '[' && c != '{'){
take(ctx);
- parse_error(&ctx->loc, "expected argument list for %s", sym_name(ctx->tokval));
+ parse_error(ctx, "expected argument list for %s", sym_name(ctx->tokval));
}
PUSH(sl_nil);
read_list(ctx, UNBOUND, c == '(' ? TOK_CLOSE : (c == '[' ? TOK_CLOSEB : TOK_CLOSEC));
@@ -721,6 +724,7 @@
sl.sp[-1] = mk_cons(sl_u8sym, sl.sp[-1]);
}
v = sym_value(sym);
+ sl.readstate->errloc = loc0;
if(v == UNBOUND)
unbound_error(sym);
return sl_apply(v, POP());
@@ -732,11 +736,14 @@
// cannot see pending labels. in other words:
// (... #2=#.#0# ... ) OK
// (... #2=#.(#2#) ... ) DO NOT WANT
+ loc0 = ctx->loc;
sym = do_read_sexpr(ctx, UNBOUND);
if(issym(sym)){
v = sym_value(sym);
- if(v == UNBOUND)
+ if(v == UNBOUND){
+ sl.readstate->errloc = loc0;
unbound_error(sym);
+ }
return v;
}
return sl_toplevel_eval(sym);
@@ -743,7 +750,7 @@
case TOK_LABEL:
// create backreference label
if(ptrhash_has(&sl.readstate->backrefs, (void*)ctx->tokval))
- parse_error(&ctx->loc, "label %"PRIdPTR" redefined", (intptr)numval(ctx->tokval));
+ parse_error(ctx, "label %"PRIdPTR" redefined", (intptr)numval(ctx->tokval));
oldtokval = ctx->tokval;
v = do_read_sexpr(ctx, ctx->tokval);
ptrhash_put(&sl.readstate->backrefs, (void*)oldtokval, (void*)v);
@@ -752,7 +759,7 @@
// look up backreference
v = (sl_v)ptrhash_get(&sl.readstate->backrefs, (void*)ctx->tokval);
if(v == (sl_v)HT_NOTFOUND)
- parse_error(&ctx->loc, "undefined label %"PRIdPTR, (intptr)numval(ctx->tokval));
+ parse_error(ctx, "undefined label %"PRIdPTR, (intptr)numval(ctx->tokval));
return v;
case TOK_GENSYM:
pv = (sl_v*)ptrhash_bp(&sl.readstate->gensyms, (void*)ctx->tokval);
@@ -764,13 +771,13 @@
case TOK_VERBATIM:
return read_verbatim(ctx);
case TOK_CLOSE:
- parse_error(&ctx->loc, "unexpected ')'");
+ parse_error(ctx, "unexpected ')'");
case TOK_CLOSEB:
- parse_error(&ctx->loc, "unexpected ']'");
+ parse_error(ctx, "unexpected ']'");
case TOK_CLOSEC:
- parse_error(&ctx->loc, "unexpected '}'");
+ parse_error(ctx, "unexpected '}'");
case TOK_DOT:
- parse_error(&ctx->loc, "unexpected '.'");
+ parse_error(ctx, "unexpected '.'");
}
return sl_void;
}
@@ -785,6 +792,7 @@
state.source = f;
sl.readstate = &state;
Rctx ctx;
+ ctx.source = &state.source;
ctx.toktype = TOK_NONE;
ctx.ws = ws;
sl_gc_handle(&ctx.tokval);
--- a/src/sl.c
+++ b/src/sl.c
@@ -25,7 +25,7 @@
sl_v sl_printwidthsym, sl_printreadablysym, sl_printprettysym, sl_printlengthsym;
sl_v sl_printlevelsym;
sl_v sl_tablesym, sl_arrsym;
-sl_v sl_iosym, sl_rdsym, sl_wrsym, sl_apsym, sl_crsym, sl_truncsym;
+sl_v iosym, sl_rdsym, sl_wrsym, sl_apsym, sl_crsym, sl_truncsym;
sl_v sl_s8sym, sl_u8sym, sl_s16sym, sl_u16sym, sl_s32sym, sl_u32sym;
sl_v sl_s64sym, sl_u64sym, sl_ptrsym, sl_bignumsym;
sl_v sl_utf8sym, sl_runesym, sl_floatsym, sl_doublesym;
@@ -117,6 +117,12 @@
sl.curr_frame = _ctx->frame;
}
+static sl_v
+mk_loc(sl_v io, ios_loc *l)
+{
+ return mk_listn(3, io, fixnum(l->lineno), fixnum(l->colno));
+}
+
_Noreturn void
sl_raise(sl_v e)
{
@@ -123,6 +129,12 @@
ios_flush(ios_stdout);
ios_flush(ios_stderr);
+ if(sl.readstate != sl.exctx->rdst){
+ sl_gc_handle(&e);
+ e = mk_cons(mk_loc(sl.readstate->source, &sl.readstate->errloc), e);
+ sl_free_gc_handles(1);
+ }
+
sl.lasterror = e;
// unwind read state
while(sl.readstate != sl.exctx->rdst){
@@ -902,19 +914,20 @@
static sl_v
_stacktrace(sl_v *top)
{
- sl_v lst = sl_nil;
+ sl_v lst = sl_nil, v = sl_nil;
sl_v *stack = sl.stack;
sl_gc_handle(&lst);
+ sl_gc_handle(&v);
while(top > stack){
const u8int *ip1 = (void*)top[-1];
int sz = top[-2]+1;
sl_v *bp = top-4-sz;
sl_v fn = bp[0];
- sl_v v = alloc_vec(sz+1, 0);
- if(iscbuiltin(fn)){
- vec_elt(v, 0) = lst == sl_nil ? mk_ptr(sl.cpc) : fn; mk_ptr((uintptr)ip1);
- }else{
+ v = alloc_vec(sz+1, 0);
+ if(iscbuiltin(fn))
+ vec_elt(v, 0) = lst == sl_nil ? mk_ptr(sl.cpc) : fn;
+ else{
/* -1: ip1 is *after* the one that was being executed */
intptr ip = ip1 - (const u8int*)cvalue_data(fn_bcode(fn)) - 1;
vec_elt(v, 0) = fixnum(ip);
@@ -929,7 +942,7 @@
lst = mk_cons(v, lst);
top = (sl_v*)top[-3];
}
- sl_free_gc_handles(1);
+ sl_free_gc_handles(2);
return lst;
}
@@ -1199,7 +1212,7 @@
{
USED(args);
argcount(nargs, 0);
- sl_ios *io = toio(sym_value(sl_iooutsym));
+ ios *io = toio(sym_value(sl_iooutsym));
ios_printf(io, "heap total %10"PRIuPTR" bytes\n", slg.heapsize);
ios_printf(io, "heap free %10"PRIuPTR" bytes\n", (uintptr)(slg.lim-slg.curheap));
ios_printf(io, "heap used %10"PRIuPTR" bytes\n", (uintptr)(slg.curheap-slg.fromspace));
@@ -1363,7 +1376,7 @@
while(1){
sl.sp = saveSP;
sl_v e = sl_read_sexpr(sl.sp[-1], false);
- if(ios_eof(value2c(sl_ios*, sl.sp[-1])))
+ if(ios_eof(value2c(ios*, sl.sp[-1])))
break;
if(isfn(e)){
// stage 0 format: series of thunks
--- a/src/sl.h
+++ b/src/sl.h
@@ -250,6 +250,7 @@
sl_htable backrefs;
sl_htable gensyms;
sl_v source;
+ ios_loc errloc;
struct _sl_readstate *prev;
}sl_readstate;
@@ -300,7 +301,7 @@
}while(0)
typedef struct {
- void (*print)(sl_v self, sl_ios *f);
+ void (*print)(sl_v self, ios *f);
void (*relocate)(sl_v oldv, sl_v newv);
void (*finalize)(sl_v self);
void (*print_traverse)(sl_v self);
@@ -444,7 +445,7 @@
extern sl_v sl_printwidthsym, sl_printreadablysym, sl_printprettysym, sl_printlengthsym;
extern sl_v sl_printlevelsym;
extern sl_v sl_arrsym;
-extern sl_v sl_iosym, sl_rdsym, sl_wrsym, sl_apsym, sl_crsym, sl_truncsym;
+extern sl_v iosym, sl_rdsym, sl_wrsym, sl_apsym, sl_crsym, sl_truncsym;
extern sl_v sl_s8sym, sl_u8sym, sl_s16sym, sl_u16sym, sl_s32sym, sl_u32sym;
extern sl_v sl_s64sym, sl_u64sym, sl_ptrsym, sl_bignumsym;
extern sl_v sl_utf8sym, sl_runesym, sl_floatsym, sl_doublesym;
--- a/src/slmain.c
+++ b/src/slmain.c
@@ -116,7 +116,7 @@
boot = unpacked;
bootsz = n;
}
- static sl_ios s;
+ static ios s;
ios_static_buffer(&s, boot, bootsz);
const char *status = nil;
@@ -123,7 +123,7 @@
sl_v args = argv_list(argc, argv);
sl_gc_handle(&args);
SL_TRY_EXTERN{
- sl_v f = cvalue_from_ref(sl_iotype, &s, sizeof(sl_ios));
+ sl_v f = cvalue_from_ref(sl_iotype, &s, sizeof(ios));
if(sl_load_system_image(f) == 0){
MEM_FREE(unpacked);
ios_close(&s);
--- a/src/str.c
+++ b/src/str.c
@@ -73,7 +73,7 @@
return args[0];
sl_v arg, buf = fn_builtin_buffer(nil, 0);
sl_gc_handle(&buf);
- sl_ios *s = value2c(sl_ios*, buf);
+ ios *s = value2c(ios*, buf);
sl_v oldpr = sym_value(sl_printreadablysym);
sl_v oldpp = sym_value(sl_printprettysym);
set(sl_printreadablysym, sl_nil);
--- a/src/system.sl
+++ b/src/system.sl
@@ -1360,7 +1360,7 @@
(void (load-process E)))))
(λ (e)
(io-close F)
- (raise `(load-error ,filename ,e))))))
+ (raise `(load-error ,e))))))
(def (repl)
(*prompt*)
@@ -1428,47 +1428,62 @@
(reverse! st))))
(def (print-exception e)
- (cond ((and (cons? e)
- (eq? (car e) 'type-error)
- (length= e 3))
- (princ "type error: expected " (cadr e) ", got " (typeof (caddr e)) ": ")
- (print (caddr e)))
+ (let* {[loc (and (list? e)
+ (list? (car e))
+ (io? (caar e))
+ (car e))]
+ [e (if loc (cdr e) e)]
+ [k (and e (sym? (car e)) (car e))]
+ [a (and k (cdr e))]}
+ (when loc
+ (princ (io-filename (car loc)) ":" (cadr loc) ":" (caddr loc) ": "))
+ (cond ((eq? k 'type-error)
+ (princ "type error: expected " (car a) ", got " (typeof (cadr a)) ": ")
+ (print (cadr a)))
- ((and (cons? e)
- (eq? (car e) 'bounds-error)
- (length= e 3))
- (princ "index " (caddr e) " out of bounds for ")
- (print (cadr e)))
+ ((eq? k 'bounds-error)
+ (princ "index " (cadr a) " out of bounds for ")
+ (print (car a)))
- ((and (cons? e)
- (eq? (car e) 'unbound-error)
- (length= e 2))
- (princ "eval: variable " (cadr e) " has no value"))
+ ((eq? k 'unbound-error)
+ (princ "eval: variable " (car a) " has no value"))
- ((and (cons? e)
- (eq? (car e) 'error))
- (princ "error: ")
- (apply princ (cdr e)))
+ ((eq? k 'error)
+ (princ "error: ")
+ (apply princ a))
- ((and (cons? e)
- (eq? (car e) 'load-error))
- (print-exception (caddr e))
- (princ "in file " (cadr e)))
+ ((eq? k 'load-error)
+ (print-exception (car a))
+ (return))
- ((and (list? e)
- (length= e 2))
- (print (car e))
- (princ ": ")
- (let ((msg (cadr e)))
- ((if (or (str? msg) (sym? msg))
- princ
- print)
- msg)))
+ ((eq? k 'parse-error)
+ (princ "parsing error: ")
+ (apply princ a))
- (else (princ "*** Unhandled exception: ")
- (print e)))
+ ((eq? k 'arg-error)
+ (princ "arguments error: ")
+ (apply princ a))
- (princ *linefeed*))
+ ((eq? k 'key-error)
+ (princ "key not found: " (car a)))
+
+ ((eq? k 'const-error)
+ (princ (if (keyword? (car a))
+ "keywords are read-only: "
+ "tried to modify a constant: "))
+ (print (car a)))
+
+ ((eq? k 'io-error)
+ (princ "I/O error: ")
+ (apply princ a))
+
+ ((or (eq? k 'divide-error)
+ (eq? k 'memory-error))
+ (apply princ a))
+
+ (else (princ "*** Unhandled exception: ")
+ (print e)))
+ (newline)))
(def (sort l cmp (:key identity))
(if (not (cdr l))
--- a/src/table.c
+++ b/src/table.c
@@ -10,7 +10,7 @@
static sl_type *sl_tabletype;
static void
-print_htable(sl_v v, sl_ios *f)
+print_htable(sl_v v, ios *f)
{
sl_htable *h = cvalue_data(v);
int first = 1;
@@ -134,7 +134,7 @@
static void
key_error(sl_v key)
{
- lerrorf(mk_list2(sl_errkey, key), "key not found");
+ sl_raise(mk_list2(sl_errkey, key));
}
// (get table key [default])