ref: a837405f1b0bb374a490bbd9fb458aa050a7074a
parent: 9971c959f1a2e3849b508a7b91f257a256b1ea73
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Mar 25 05:42:51 EDT 2025
improve interactive repl Print the prompt when it makes sense only. References: https://todo.sr.ht/~ft/sl/1
--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -424,12 +424,12 @@
#fn(ash)) ref-s32-LE)
remprop #fn("n220711q5386;3F042286052;3:042386062:" #(#fn(get) *properties* #fn(has?)
#fn(del!)) remprop)
- repl #fn("n0IIb4b5208421_5142085228485>2_51485<5047360:" #(#0#
- #fn("n07050421725142324{257651S;3Z04778451788551360q@=079855147:5047;85w<61:" #(*prompt*
- #fn(io-flush) *io-out* #fn("n02060:" #(#fn(read)))
- #fn("n1207151422061:" #(#fn(io-discardbuffer) *io-in* #fn(raise)))
- #fn(io-eof?) *io-in* load-process void? print newline void that) prompt)
- #fn("n020A>121{370F<60:q:" #(#fn("n0A<60:")
+ repl #fn("n0IIb4b5705042172514238424_5142385258485>2_51485<5047660:" #(*prompt* #fn(io-flush)
+ *io-out* #0#
+ #fn("n02021{227351S;3q047484517585513M07584513@076504277851@30q@=079855147:5047;85w<61:" #(#fn("n02071D62:" #(#fn(read)
+ *io-in*)) #fn("n1207151422061:" #(#fn(io-discardbuffer) *io-in* #fn(raise)))
+ #fn(io-eof?) *io-in* load-process void? *prompt* #fn(io-flush) *io-out* print newline void that) prompt)
+ #fn("n020A>121{370F<60:q:" #(#fn("n0A<60:")
#fn("n1700514D:" #(top-level-exception-handler))) reploop) newline) repl)
revappend #fn("n2701062:" #(reverse-) revappend) reverse
#fn("n170q062:" #(reverse-) reverse) reverse! #fn("n170q062:" #(reverse!-) reverse!)
--- a/src/io.c
+++ b/src/io.c
@@ -147,10 +147,10 @@
BUILTIN("read", read)
{
if(nargs > 1)
- argcount(nargs, 1);
+ argcount(nargs, 2);
sl_v a = nargs == 0 ? sym_value(sl_ioinsym) : args[0];
sl_gc_handle(&a);
- sl_v v = sl_read_sexpr(a);
+ sl_v v = sl_read_sexpr(a, nargs > 1 && args[1] == sl_t);
sl_free_gc_handles(1);
return ios_eof(toio(a)) ? sl_eof : v;
}
--- a/src/read.c
+++ b/src/read.c
@@ -16,9 +16,10 @@
typedef struct Rctx Rctx;
struct Rctx {
- u32int toktype;
sl_v tokval;
sl_loc loc;
+ u32int toktype;
+ bool ws;
char buf[1024];
};
@@ -91,26 +92,25 @@
}
static char
-nextchar(void)
+nextchar(Rctx *ctx)
{
- int ch;
- char c;
+ int c;
sl_ios *f = RS;
do{
- ch = ios_getc(RS);
- if(ch == IOS_EOF)
+ c = ios_getc(RS);
+ if(c == IOS_EOF)
return 0;
- c = ch;
if(c == ';'){
// single-line comment
do{
- ch = ios_getc(f);
- if(ch == IOS_EOF)
+ c = ios_getc(f);
+ if(c == IOS_EOF)
return 0;
- }while(ch != '\n');
- c = ch;
+ }while(c != '\n');
}
+ if(c == '\n' && ctx->ws)
+ return '\n';
}while(c == ' ' || isspace(c));
return c;
}
@@ -206,9 +206,10 @@
if(ctx->toktype != TOK_NONE)
return ctx->toktype;
- c = nextchar();
+ c = nextchar(ctx);
ctx->loc = RS->loc;
- if(ios_eof(RS))
+ ctx->ws = false;
+ if(ios_eof(RS) || isspace(c))
return TOK_NONE;
if(c == '(')
ctx->toktype = TOK_OPEN;
@@ -320,7 +321,6 @@
goto hashpipe_gotc;
}
}
- // this was whitespace, so keep peeking
return peek(ctx);
}else if(c == ';'){
// datum comment
@@ -699,7 +699,7 @@
case TOK_SHARPSYM:
sym = ctx->tokval;
// constructor notation
- c = nextchar();
+ c = nextchar(ctx);
ctx->loc = RS->loc;
if(c != '('){
take(ctx);
@@ -767,7 +767,7 @@
}
sl_v
-sl_read_sexpr(sl_v f)
+sl_read_sexpr(sl_v f, bool ws)
{
sl_readstate state;
state.prev = sl.readstate;
@@ -777,6 +777,7 @@
sl.readstate = &state;
Rctx ctx;
ctx.toktype = TOK_NONE;
+ ctx.ws = ws;
sl_gc_handle(&ctx.tokval);
sl_v v = do_read_sexpr(&ctx, UNBOUND);
--- a/src/read.h
+++ b/src/read.h
@@ -1,6 +1,6 @@
#pragma once
-sl_v sl_read_sexpr(sl_v f);
+sl_v sl_read_sexpr(sl_v f, bool ws);
bool sl_read_numtok(const char *tok, sl_v *pval, int base);
// defines which characters are ordinary symbol characters.
--- a/src/sl.c
+++ b/src/sl.c
@@ -1355,7 +1355,7 @@
SL_TRY{
while(1){
sl.sp = saveSP;
- sl_v e = sl_read_sexpr(sl.sp[-1]);
+ sl_v e = sl_read_sexpr(sl.sp[-1], false);
if(ios_eof(value2c(sl_ios*, sl.sp[-1])))
break;
if(isfn(e)){
--- a/src/system.sl
+++ b/src/system.sl
@@ -1,3 +1,4 @@
+
; StreetLISP standard library
; by Jeff Bezanson (C) 2009
; Distributed under the BSD License
@@ -1342,15 +1343,20 @@
(raise `(load-error ,filename ,e))))))
(def (repl)
+ (*prompt*)
+ (io-flush *io-out*)
(def (prompt)
- (*prompt*)
- (io-flush *io-out*)
- (let ((v (trycatch (read)
+ (let ((v (trycatch (read *io-in* T)
(λ (e) (io-discardbuffer *io-in*)
(raise e)))))
(and (not (io-eof? *io-in*))
(let ((V (load-process v)))
- (unless (void? V) (print V) (newline))
+ (if (void? V)
+ (when (void? v)
+ (*prompt*)
+ (io-flush *io-out*))
+ (begin (print V)
+ (newline)))
(void (set! that V))))))
(def (reploop)
(when (trycatch (prompt)