aboutsummaryrefslogtreecommitdiff
path: root/src/lib/std.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 09:42:25 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 09:42:25 +0330
commitde4da84ca3159ad0ebcf13729716be5f4d7bbc2a (patch)
tree216f00007206fdc15dccd3327884b4c0dad94446 /src/lib/std.zc
parentxref: baseline records the prover's writers of ft_ln (bin, kw_for), xub and x... (diff)
std: add std.Io (print, println, nl, put_*, put_f, get_c, eof, read, getline) with test, learn example and docs
Diffstat (limited to 'src/lib/std.zc')
-rw-r--r--src/lib/std.zc78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/lib/std.zc b/src/lib/std.zc
index 745a921..b206888 100644
--- a/src/lib/std.zc
+++ b/src/lib/std.zc
@@ -415,6 +415,84 @@ struct Host {
}
}
+// ---- standard input and output ----
+
+// the terminal: printing to the standard output and reading the standard input.
+// called as std.Io.name(args). the writers go through rt.put_c, so a capture
+// (std.capture) sees their text too. the rt names (rt.put_n, rt.put_s and the
+// rest) stay; these are the same operations, grouped with the library.
+// zc has no varargs or overloading, so print takes a string, and numbers have
+// their own writers: std.Io.print("n = "); std.Io.put_n(n); std.Io.nl();
+struct Io {
+ // writes a string.
+ // s: the text
+ // returns: 0
+ static int print(char* s) { return rt.put_s(s); }
+ // writes a string and a line break.
+ // s: the text
+ // returns: 0
+ static int println(char* s) { rt.put_s(s); return rt.put_c(10); }
+ // writes a line break.
+ // returns: 0
+ static int nl() { return rt.put_c(10); }
+ // writes one character.
+ // c: the character
+ // returns: 0
+ static int put_c(int c) { return rt.put_c(c); }
+ // writes a string, the same as print.
+ // s: the text
+ // returns: 0
+ static int put_s(char* s) { return rt.put_s(s); }
+ // writes a number in decimal, with a minus sign when it is negative.
+ // n: the number
+ // returns: 0
+ static int put_n(int n) { return rt.put_n(n); }
+ // writes a number in hexadecimal.
+ // n: the number
+ // returns: 0
+ static int put_hex(int n) { return rt.put_hex(n); }
+ // writes a packed byte string.
+ // s: the byte string
+ // returns: 0
+ static int put_bs(bstr s) { return rt.put_bs(s); }
+ // writes a float with the vm's float printer (six decimals, inf, nan).
+ // x: the value
+ // returns: 0
+ static int put_f(float x) { asm { x @ #1220 } return 0; }
+ // reads one character.
+ // returns: its byte value, -1 at the end of the input
+ static int get_c() { return rt.get_c(); }
+ // true when the input has no more characters.
+ // returns: 1 at the end of the input, 0 otherwise
+ static int eof() { return rt.eof(); }
+ // reads up to n characters, one to a word, stopping early at the end of the input.
+ // buf: where they go, room for n words
+ // n: the most to read
+ // returns: how many were read, 0 at the end of the input
+ static int read(char* buf, int n) {
+ int i = 0, c;
+ while (i < n) { c = rt.get_c(); if (c < 0 && rt.eof()) break; buf[i] = c; i++; }
+ return i;
+ }
+ // reads one line into buf as a string, without its line break. a line longer
+ // than n - 1 characters is cut short and the rest is left for the next call.
+ // buf: where the line goes, room for n words, the 0 included
+ // n: the size of buf in words
+ // returns: the line's length, or -1 at the end of the input with nothing read
+ static int getline(char* buf, int n) {
+ int i = 0, c;
+ if (n < 1) return -1;
+ while (i < n - 1) {
+ c = rt.get_c();
+ if (c < 0 && rt.eof()) { if (!i) { buf[0] = 0; return -1; } break; }
+ if (c == 10) break;
+ buf[i] = c; i++;
+ }
+ buf[i] = 0;
+ return i;
+ }
+}
+
// ---- byte strings ----
// the same helpers as Text, for packed byte strings of type bstr (b"..."