shithub: sl

Download patch

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)