aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/expr.zc
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 17:50:10 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 17:50:10 +0330
commit251b0212f626d0f92eda51906d353712ef4a63b8 (patch)
tree4f0e0b0ee6b0f6d0671261a46bb2bcd15ef0f59c /src/compiler/expr.zc
parentmerge work/actors: wasm seed bootstrap (seed/MANIFEST), shared copy-on-write ... (diff)
parentprescan: guess an owned return only from a local declared from new/heap, not ... (diff)
merge work/demo-fixes: analyzer ownership fixes (back links, loop-built lists, .u inference), Io.print any args, block-end borrow messages
Diffstat (limited to 'src/compiler/expr.zc')
-rw-r--r--src/compiler/expr.zc33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc
index 141ca16..2935a9b 100644
--- a/src/compiler/expr.zc
+++ b/src/compiler/expr.zc
@@ -409,9 +409,42 @@ int shifthint(int p, int v) {
// function isn't defined yet)
// 6. the result's type and class are set: .u functions return C_FRESH, which
// is how the analyzer knows the caller now owns a new object
+// std.Io.print(a, b, ...) and println: any mix of strings, byte strings,
+// numbers and floats. each argument goes to the writer for its type; a fresh
+// owned string is written and then freed. println ends with a line break.
+int printcall(int line) {
+ int c; char* w;
+ expect(s_lp);
+ if (!is_op(s_rp)) {
+ while (1) {
+ c = expr(); rval();
+ if (xty == tbstr || xstr) w = "std.Io.put_bs";
+ else if (xfloat) w = "std.Io.put_f";
+ else if (xty[0] == TY_PTR && xty[4] == tchar) w = "std.Io.put_s";
+ else if (xty[0] == TY_ARR && xty[4] == tchar) w = "std.Io.put_s";
+ else w = "std.Io.put_n";
+ if (c == C_FRESH && fchk) {
+ if (!rt.eq_w(w, "std.Io.put_s") && !rt.eq_w(w, "std.Io.put_bs")) cerr("a new object can't be printed; bind it to a name first");
+ lit(0); op(O_PICK); callname(intern(w)); op(O_DROP); callname(s_free); op(O_DROP);
+ } else {
+ if (c >= C_VAR && tracked(c - C_VAR)) touch(c - C_VAR);
+ callname(intern(w)); op(O_DROP);
+ }
+ if (!accept(s_comma)) break;
+ }
+ }
+ expect(s_rp);
+ if (line) { lit(10); callname(intern("rt.put_c")); op(O_DROP); }
+ lit(0);
+ lv = 0; lvk = LV_NONE; xty = tint; xzero = 0; xbor = -1; xconst = 0;
+ xfloat = 0; xstr = 0; xlenloc = -1; xstamp = 0; xaf = 0;
+ return C_PLAIN;
+}
int call(int s) {
int np, tags = 0, ret = 0; word ft = stype[s]; word[8] bs; int rs, rhs_type = 0, kop, cp = callpos, original = s; word storage; int origin, temporary, owner; word origins, owner_fact;
word requirements = effect_requirements, edges = effect_edges;
+ if (rt.eq_w(sname[s], "std.Io.print")) return printcall(0);
+ if (rt.eq_w(sname[s], "std.Io.println")) return printcall(1);
borrow_depth++;
if (sname[s] == s_new && skind[s] == K_FN) {
peek();