shithub: sl

Download patch

ref: b0d0d82887dd95ffa9a6157d0c1446e8249eca32
parent: 03caa766eca727daba0c3c149ff6b27675e09b1c
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Mar 25 22:20:29 EDT 2025

add io-peekrune; io-{get,put}c → io-{get,put}rune

References: https://todo.sr.ht/~ft/sl/52

--- a/boot/sl.boot
+++ b/boot/sl.boot
@@ -457,7 +457,7 @@
                                                                          #fn(io->str)) str-join)
             str-lpad #fn("n3207182122051~52062:" #(#fn(str) str-rep #fn(str-length)) str-lpad)
             str-map #fn("n2205021151EI8887L23O0422860231885251524748851?8@\f/^14258661:" #(#fn(buffer)
-  #fn(str-length) #fn(io-putc) #fn(str-rune) 1+ #fn(io->str)) str-map)
+  #fn(str-length) #fn(io-putrune) #fn(str-rune) 1+ #fn(io->str)) str-map)
             str-rep #fn("n21r4L23b0701E5235021:1Kl238022061:1r2l2390220062:2200063:731513@02207401K~5262:742200521r2j262:" #(<=
   "" #fn(str) odd? str-rep) str-rep)
             str-rpad #fn("n32007182122051~5262:" #(#fn(str) str-rep #fn(str-length)) str-rpad)
--- a/src/io.c
+++ b/src/io.c
@@ -164,12 +164,26 @@
 	return ios_eof(toio(a)) ? sl_eof : v;
 }
 
-BUILTIN("io-getc", io_getc)
+BUILTIN("io-peekrune", io_peekrune)
 {
 	argcount(nargs, 1);
 	sl_ios *s = toio(args[0]);
 	Rune r;
 	int res;
+	if((res = ios_peekrune(s, &r)) == IOS_EOF)
+		//lerrorf(sl_errio, "end of file reached");
+		return sl_eof;
+	if(res == 0)
+		lerrorf(sl_errio, "invalid UTF-8 sequence");
+	return mk_rune(r);
+}
+
+BUILTIN("io-getrune", io_getrune)
+{
+	argcount(nargs, 1);
+	sl_ios *s = toio(args[0]);
+	Rune r;
+	int res;
 	if((res = ios_getrune(s, &r)) == IOS_EOF)
 		//lerrorf(sl_errio, "end of file reached");
 		return sl_eof;
@@ -178,7 +192,7 @@
 	return mk_rune(r);
 }
 
-BUILTIN("io-putc", io_putc)
+BUILTIN("io-putrune", io_putrune)
 {
 	argcount(nargs, 2);
 	sl_ios *s = toio(args[0]);
--- a/src/ios.c
+++ b/src/ios.c
@@ -887,6 +887,22 @@
 }
 
 int
+ios_peekrune(sl_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))
+		return n == 0 ? IOS_EOF : 0;
+	chartorune(r, (char*)s->buf + s->bpos);
+	if(*r == Runeerror)
+		return 0;
+	if(*r == '\n')
+		s->loc.colno = 0;
+	else
+		s->loc.colno++;
+	return 1;
+}
+
+int
 ios_getrune(sl_ios *s, Rune *r)
 {
 	int c;
--- a/src/ios.h
+++ b/src/ios.h
@@ -83,10 +83,11 @@
 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);
-// todo: ios_socket
+
 extern sl_ios *ios_stdin;
 extern sl_ios *ios_stdout;
 extern sl_ios *ios_stderr;
+
 void ios_init_std(void);
 
 /* high-level functions - output */
@@ -95,6 +96,7 @@
 int ios_vprintf(sl_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);
 
 // discard data buffered for reading
--- a/src/system.sl
+++ b/src/system.sl
@@ -1001,7 +1001,7 @@
         (n (str-length s)))
     (let ((i 0))
       (while (< i n)
-         (io-putc b (f (str-rune s i)))
+         (io-putrune b (f (str-rune s i)))
          (set! i (1+ i))))
     (io->str b)))