aboutsummaryrefslogtreecommitdiff
path: root/tests/programs
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-14 08:29:46 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-14 08:29:46 +0330
commit1c53304d03414890af0da7432d1aea87e754a14a (patch)
tree97190d86cf548c9bc63f68c86a4d2a4f09809713 /tests/programs
parenta (diff)
feat: grow memory limits, add icon/actor libraries, overhaul LSP diagnostics
Compiler and VM - make every memory map limit dynamic and adjustable at both build time and runtime, including compiler tables, stacks, and every execution region - reserve and grow tables, operand and return stacks, frame segments, and image-building output without relocating live code or globals - rename i/o and string helpers consistently (puts -> put_s, putn -> put_n, scat -> cat_s) across compiler, runtime, examples, tests, and docs - recast and consume values assigned to globals from inside functions - allow fixed and const together, add typed closure returns (fn:t(...)), multi-include syntax (include rt, run, core;), and recurse type inference - never infer string literals as word, anywhere, as argument, variable, or return type - draft docs/BORROW.md: a borrow checker less intrusive than Rust's but more intelligent LSP and editor integration - require explicit includes and give every toolchain area its own namespace (rt, lsp, run, core) - hover for built-in types, inferred types, values known at hover time, array and pointer lifetime/size, library names in include statements, and inferred lifetimes with explanations - honor /* */ comments as documentation for variables and arguments, and stop misattributing section headers or trailing comments as variable hints - stream diagnostics and cancel stale requests on change - jump to definition and references, including cross-file - quick fixes with automatic library import, and namespace completion Hints and diagnostics - render hints as blue squigglies by default, with hints on/small/off per file - suppress magic-number hints via a preceding /* */ comment, and say so - warn on unused arguments; allow multiple _ discards in parameters, pattern matching, and tagged enums, warning if a _ is actually used - rewrite hint and comment prose in professional compiler-doc register Libraries - add icon.zc: run-time self-modification, find/replace syntax, type and block edits, and step-through inspection of locals and globals - add actor.zc: async actors with Actor<I,O>, implicit this, spawn/recv/send, injected into the compiler machinery at include time rather than built in Tooling and docs - reorganize sources, tests, and designs into subdirectories - unify windows entry points in tinyvm.bat and add a matching tinyvm.sh - add --help across the toolchain - polish the learning guide, stdlib docs, and design notes Tests - add accept, reject, and regression coverage across the compiler, LSP, - runtime, icon, actors, threads, formatting, and the toolchain contracts, plus fuzzers and property tests
Diffstat (limited to 'tests/programs')
-rw-r--r--tests/programs/actor.zc12
-rw-r--r--tests/programs/alias.zc21
-rw-r--r--tests/programs/allocfast.zc21
-rw-r--r--tests/programs/annotate.expected24
-rw-r--r--tests/programs/annotate.zc22
-rw-r--r--tests/programs/arena.zc25
-rw-r--r--tests/programs/args.zc15
-rw-r--r--tests/programs/array_values.expected1
-rw-r--r--tests/programs/array_values.zc30
-rw-r--r--tests/programs/arrays.zc33
-rw-r--r--tests/programs/backtick.zc7
-rw-r--r--tests/programs/bareexit.zc9
-rw-r--r--tests/programs/bareio.zc41
-rw-r--r--tests/programs/basics.zc15
-rw-r--r--tests/programs/bench.zc17
-rw-r--r--tests/programs/bench_bytes.zc15
-rw-r--r--tests/programs/bench_share.zc21
-rw-r--r--tests/programs/bench_strings.zc21
-rw-r--r--tests/programs/bitops.zc27
-rw-r--r--tests/programs/borrow_rules.expected1
-rw-r--r--tests/programs/borrow_rules.zc39
-rw-r--r--tests/programs/borrowmove.zc7
-rw-r--r--tests/programs/bounds.zc17
-rw-r--r--tests/programs/bounds_hi.zc7
-rw-r--r--tests/programs/bounds_lo.zc7
-rw-r--r--tests/programs/bstr_io.zc35
-rw-r--r--tests/programs/buddy.zc23
-rw-r--r--tests/programs/bytes.zc57
-rw-r--r--tests/programs/cabi.zc33
-rw-r--r--tests/programs/cabi_o3.zc15
-rw-r--r--tests/programs/cabi_sized.zc17
-rw-r--r--tests/programs/capture.zc41
-rw-r--r--tests/programs/closure.zc31
-rw-r--r--tests/programs/closure_result.zc12
-rw-r--r--tests/programs/csyn.zc11
-rw-r--r--tests/programs/decl_undefined.zc2
-rw-r--r--tests/programs/discard_m.zc7
-rw-r--r--tests/programs/doublefree.zc11
-rw-r--r--tests/programs/enhance.zc17
-rw-r--r--tests/programs/enumscope.zc9
-rw-r--r--tests/programs/enumtype.zc7
-rw-r--r--tests/programs/f32.zc31
-rw-r--r--tests/programs/f32o3.zc9
-rw-r--r--tests/programs/fbench.zc11
-rw-r--r--tests/programs/float.zc23
-rw-r--r--tests/programs/fo3.zc19
-rw-r--r--tests/programs/ftext.zc17
-rw-r--r--tests/programs/ftruth.zc35
-rw-r--r--tests/programs/ftype.zc15
-rw-r--r--tests/programs/gc.zc19
-rw-r--r--tests/programs/generics.zc38
-rw-r--r--tests/programs/genmeth.zc17
-rw-r--r--tests/programs/global_transfer.zc16
-rw-r--r--tests/programs/growheap.zc21
-rw-r--r--tests/programs/growone.zc9
-rw-r--r--tests/programs/infer_return.zc7
-rw-r--r--tests/programs/interior.zc17
-rw-r--r--tests/programs/joins.zc23
-rw-r--r--tests/programs/manyerrors.zc5
-rw-r--r--tests/programs/memleak.zc9
-rw-r--r--tests/programs/memory_bounds.zc13
-rw-r--r--tests/programs/meta.zc53
-rw-r--r--tests/programs/methodown.zc15
-rw-r--r--tests/programs/misc.zc21
-rw-r--r--tests/programs/names.zc9
-rw-r--r--tests/programs/o3.zc33
-rw-r--r--tests/programs/o3_bounds.zc7
-rw-r--r--tests/programs/o3bytes.zc51
-rw-r--r--tests/programs/o3call.zc17
-rw-r--r--tests/programs/o3copy.zc5
-rw-r--r--tests/programs/o3deep.zc5
-rw-r--r--tests/programs/o3deep_over.zc5
-rw-r--r--tests/programs/o3direct.zc25
-rw-r--r--tests/programs/o3fat.zc19
-rw-r--r--tests/programs/o3licm.zc17
-rw-r--r--tests/programs/o3push.zc33
-rw-r--r--tests/programs/o3scopes.zc11
-rw-r--r--tests/programs/o3zero.zc7
-rw-r--r--tests/programs/overflow_data.zc5
-rw-r--r--tests/programs/overflow_frame.zc5
-rw-r--r--tests/programs/overflow_return.zc5
-rw-r--r--tests/programs/packedfields.zc37
-rw-r--r--tests/programs/quarantine.zc25
-rw-r--r--tests/programs/rawpid.zc7
-rw-r--r--tests/programs/rawsys.zc7
-rw-r--r--tests/programs/recycle.zc25
-rw-r--r--tests/programs/replace_owner.expected1
-rw-r--r--tests/programs/replace_owner.zc27
-rw-r--r--tests/programs/roots.zc19
-rw-r--r--tests/programs/scrub.zc13
-rw-r--r--tests/programs/share.zc71
-rw-r--r--tests/programs/share_dbg.zc11
-rw-r--r--tests/programs/sized.zc67
-rw-r--r--tests/programs/sizedvec.zc39
-rw-r--r--tests/programs/static.zc5
-rw-r--r--tests/programs/stdbuf.zc31
-rw-r--r--tests/programs/stdmore.zc68
-rw-r--r--tests/programs/strings.zc59
-rw-r--r--tests/programs/structret.zc15
-rw-r--r--tests/programs/structval.zc17
-rw-r--r--tests/programs/sys.zc17
-rw-r--r--tests/programs/tagenum.zc17
-rw-r--r--tests/programs/tagenum_two.zc7
-rw-r--r--tests/programs/tagenum_warn.zc7
-rw-r--r--tests/programs/temporary_borrows.expected1
-rw-r--r--tests/programs/temporary_borrows.zc29
-rw-r--r--tests/programs/typedmethods.zc11
-rw-r--r--tests/programs/typeoff.zc5
-rw-r--r--tests/programs/typeok.zc11
-rw-r--r--tests/programs/types.zc51
-rw-r--r--tests/programs/uaf.zc7
-rw-r--r--tests/programs/uaf_in.zc7
-rw-r--r--tests/programs/umd.zc27
-rw-r--r--tests/programs/undefined_call.zc2
-rw-r--r--tests/programs/use_std.zc13
-rw-r--r--tests/programs/wide.zc13
-rw-r--r--tests/programs/zc0plain.zc2
-rw-r--r--tests/programs/zc0typed.zc10
118 files changed, 1385 insertions, 881 deletions
diff --git a/tests/programs/actor.zc b/tests/programs/actor.zc
new file mode 100644
index 0000000..5256aca
--- /dev/null
+++ b/tests/programs/actor.zc
@@ -0,0 +1,12 @@
+namespace;
+include rt, actor;
+typecheck on;
+int add_two(int n) { return n + 2; }
+fn main() {
+ actor.Actor<int,int>* a = rt.new(actor.Actor<int,int>);
+ let total = 0;
+ a.spawn(add_two); a.recv(fn(int value) { total += value; return 0; });
+ a.send(2); a.send(3); a.await(); rt.put_n(total); rt.put_c(' ');
+ a.send(1); a.await(); rt.put_n(total); rt.put_c(' ');
+ a.close(); rt.put_n(a.send(4)); rt.put_c(10); return 0;
+}
diff --git a/tests/programs/alias.zc b/tests/programs/alias.zc
index 2ebc3e5..7d394c5 100644
--- a/tests/programs/alias.zc
+++ b/tests/programs/alias.zc
@@ -1,21 +1,24 @@
+namespace;
+include rt, run;
+
// a pointer computed from a live object is a borrow of it: fine while the owner lives
struct node { int v; node* next; };
fn main() {
- let p = new(4);
+ let p = rt.new(4);
p[0] = 11; p[1] = 22;
let q = p + 1;
- put_n(q[-1]); put_c(' ');
- put_n(q[0]); put_c(' ');
- node* a = new(node), b = new(node);
+ rt.put_n(q[-1]); rt.put_c(' ');
+ rt.put_n(q[0]); rt.put_c(' ');
+ node* a = rt.new(node), b = rt.new(node);
a.v = 3; b.v = 4; a.next = b;
node* c = a.next;
- put_n(c.v); put_c(' ');
- int** list = new(int*, 2);
- int* item = new(int);
+ rt.put_n(c.v); rt.put_c(' ');
+ int** list = rt.new(int*, 2);
+ int* item = rt.new(int);
*item = 8;
list[1] = item;
int* e = list[1];
- put_n(*e); put_c(10);
- free(d*p); free(d*a); free(d*list);
+ rt.put_n(*e); rt.put_c(10);
+ rt.free(d*p); rt.free(d*a); rt.free(d*list);
return 0;
}
diff --git a/tests/programs/allocfast.zc b/tests/programs/allocfast.zc
index 5ef2df2..d7b1d93 100644
--- a/tests/programs/allocfast.zc
+++ b/tests/programs/allocfast.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// repeated allocations of a size known at compile time: new(T) of a struct of
// numbers, and new(n) with a constant n. each pass of the loop makes an object
// and frees it at the end of the block, so the allocator should hand back the
@@ -8,7 +11,7 @@ struct line { point* a; int len; };
fn loop_leaf(int n) {
let total = 0;
for (int i = 0; i < n; i++) {
- point* p = new(point);
+ point* p = rt.new(point);
total += p.x + p.y; // zero from the allocator, every pass
p.x = i; p.y = 2;
}
@@ -17,7 +20,7 @@ fn loop_leaf(int n) {
fn loop_words(int n) {
let total = 0, i = 0;
while (i < n) {
- let w = new(6);
+ let w = rt.new(6);
total += w[0] + w[5];
w[0] = 7; w[5] = 9;
i++;
@@ -27,8 +30,8 @@ fn loop_words(int n) {
fn loop_owner(int n) {
let i = 0, total = 0;
while (i < n) {
- line* l = new(line);
- l.a = new(point);
+ line* l = rt.new(line);
+ l.a = rt.new(point);
l.a.x = i;
total += l.a.x + l.len;
i++;
@@ -36,10 +39,10 @@ fn loop_owner(int n) {
return total;
}
fn main() {
- let before = live_objects();
- put_n(loop_leaf(50000)); put_c(' ');
- put_n(loop_words(50000)); put_c(' ');
- put_n(loop_owner(1000)); put_c(' ');
- put_n(live_objects() - before); put_c(10);
+ let before = rt.live_objects();
+ rt.put_n(loop_leaf(50000)); rt.put_c(' ');
+ rt.put_n(loop_words(50000)); rt.put_c(' ');
+ rt.put_n(loop_owner(1000)); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - before); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/annotate.expected b/tests/programs/annotate.expected
index 553353e..c22eb66 100644
--- a/tests/programs/annotate.expected
+++ b/tests/programs/annotate.expected
@@ -1,10 +1,10 @@
-// zclsp --annotate writes the types the compiler can see into a program that
-// has none. this one has none: locals take the type of what they start as, a
-// parameter takes the type every call gives it, and a function the type of
-// what it returns. what it can't tell it leaves alone (twice is called with
-// a plain word, so its parameter stays), and the program still means the
-// same thing: tests/test.sh runs both and compares.
-include "src/lib/std.zc";
+namespace;
+include rt;
+
+// --annotate adds type annotations inferred from declarations and calls.
+// unresolved types remain unchanged, and annotations do not add conversions.
+// tests/test.sh compares this program's output before and after annotation.
+include std;
struct point { int x, y; };
int calls = 0;
char* name = "annotate";
@@ -12,12 +12,12 @@ int table[4];
int add(int a, int b) { calls = calls + 1; return a + b; }
point* scale(point* p, int k) { p.x = p.x * k; p.y = p.y * k; return p; }
point*.u fresh(int x, int y) {
- point* p = new(point);
+ point* p = rt.new(point);
p.x = x; p.y = y;
return u*p;
}
-int twice(int v) { return v + v; }
-fn len3(char* s) { return len_w(s) + 3; }
+fn twice(v) { return v + v; }
+fn len3(char* s) { return rt.len_w(s) + 3; }
fn half(f) { return f / 2.0; }
int main() {
int i = 0, sum = 0, buf[6];
@@ -27,7 +27,7 @@ int main() {
while (i < 4) { table[i] = add(i, 10); sum = sum + table[i]; i++; }
scale(pt, 3);
buf[0] = twice(sum);
- put_n(sum); put_c(32); put_n(pt.x + pt.y); put_c(32); put_n(buf[0]); put_c(32);
- put_n(len3(text)); put_c(32); put_n(calls); put_c(32); put_n(half(r) * 4); put_c(10);
+ rt.put_n(sum); rt.put_c(32); rt.put_n(pt.x + pt.y); rt.put_c(32); rt.put_n(buf[0]); rt.put_c(32);
+ rt.put_n(len3(text)); rt.put_c(32); rt.put_n(calls); rt.put_c(32); rt.put_n(half(r) * 4); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/annotate.zc b/tests/programs/annotate.zc
index 75dad97..3a39f5f 100644
--- a/tests/programs/annotate.zc
+++ b/tests/programs/annotate.zc
@@ -1,10 +1,10 @@
-// zclsp --annotate writes the types the compiler can see into a program that
-// has none. this one has none: locals take the type of what they start as, a
-// parameter takes the type every call gives it, and a function the type of
-// what it returns. what it can't tell it leaves alone (twice is called with
-// a plain word, so its parameter stays), and the program still means the
-// same thing: tests/test.sh runs both and compares.
-include "src/lib/std.zc";
+namespace;
+include rt;
+
+// --annotate adds type annotations inferred from declarations and calls.
+// unresolved types remain unchanged, and annotations do not add conversions.
+// tests/test.sh compares this program's output before and after annotation.
+include std;
struct point { int x, y; };
let calls = 0;
let name = "annotate";
@@ -12,12 +12,12 @@ let table[4];
fn add(a, b) { calls = calls + 1; return a + b; }
fn scale(p, k) { p.x = p.x * k; p.y = p.y * k; return p; }
.u fresh(x, y) {
- let p = new(point);
+ let p = rt.new(point);
p.x = x; p.y = y;
return u*p;
}
fn twice(v) { return v + v; }
-fn len3(s) { return len_w(s) + 3; }
+fn len3(s) { return rt.len_w(s) + 3; }
fn half(f) { return f / 2.0; }
fn main() {
let i = 0, sum = 0, buf[6];
@@ -27,7 +27,7 @@ fn main() {
while (i < 4) { table[i] = add(i, 10); sum = sum + table[i]; i++; }
scale(pt, 3);
buf[0] = twice(sum);
- put_n(sum); put_c(32); put_n(pt.x + pt.y); put_c(32); put_n(buf[0]); put_c(32);
- put_n(len3(text)); put_c(32); put_n(calls); put_c(32); put_n(half(r) * 4); put_c(10);
+ rt.put_n(sum); rt.put_c(32); rt.put_n(pt.x + pt.y); rt.put_c(32); rt.put_n(buf[0]); rt.put_c(32);
+ rt.put_n(len3(text)); rt.put_c(32); rt.put_n(calls); rt.put_c(32); rt.put_n(half(r) * 4); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/arena.zc b/tests/programs/arena.zc
index 5156b80..4ca7e7c 100644
--- a/tests/programs/arena.zc
+++ b/tests/programs/arena.zc
@@ -1,16 +1,19 @@
+namespace;
+include rt;
+
// the bump arena: interior pointers, a rewind, and a full bump.
fn main() {
- let a = arena_new(32), p, q, r;
- p = arena_alloc(a, 4);
+ let a = rt.arena_new(32), p, q, r;
+ p = rt.arena_alloc(a, 4);
p[0] = 7;
- q = arena_alloc(a, 4);
- put_n(q - p); put_c(' ');
- put_n(p[0]); put_c(' ');
- put_n(q[0]); put_c(' ');
- arena_reset(a);
- r = arena_alloc(a, 4);
- put_n(r == p); put_c(' ');
- put_n(arena_alloc(a, 100) == 0); put_c(10);
- free(d*a);
+ q = rt.arena_alloc(a, 4);
+ rt.put_n(q - p); rt.put_c(' ');
+ rt.put_n(p[0]); rt.put_c(' ');
+ rt.put_n(q[0]); rt.put_c(' ');
+ rt.arena_reset(a);
+ r = rt.arena_alloc(a, 4);
+ rt.put_n(r == p); rt.put_c(' ');
+ rt.put_n(rt.arena_alloc(a, 100) == 0); rt.put_c(10);
+ rt.free(d*a);
return 0;
}
diff --git a/tests/programs/args.zc b/tests/programs/args.zc
index aac72ec..4e0947e 100644
--- a/tests/programs/args.zc
+++ b/tests/programs/args.zc
@@ -1,16 +1,19 @@
+namespace;
+include rt, std;
+
// the command line and the environment, as the host hands them over. argv[0]
// is the program path, and <eval> when the source came from stdin, so argc is
// 1 even with nothing on the command line. run through a shell with no extra
// arguments, which is how test.sh calls it, so the line is fixed.
-include "src/lib/std.zc";
+include std;
fn main() {
- put_n(argc); put_c(32); put_s(argv[0]);
- put_c(32); put_c(32); put_s(argv[argc - 1]);
+ rt.put_n(std.argc); rt.put_c(32); rt.put_s(std.argv[0]);
+ rt.put_c(32); rt.put_c(32); rt.put_s(std.argv[std.argc - 1]);
// envc counts every entry, envp holds NAME=value strings
- put_c(32); put_n(envc > 0);
+ rt.put_c(32); rt.put_n(std.envc > 0);
let hit = 0;
- for (int i = 0; i < envc; i++) if (eq_w(envp[i], "ZC_ARG_TEST=ok")) hit = 1;
- put_c(32); put_n(hit);
+ for (int i = 0; i < std.envc; i++) if (rt.eq_w(std.envp[i], "ZC_ARG_TEST=ok")) hit = 1;
+ rt.put_c(32); rt.put_n(hit);
return 0;
} \ No newline at end of file
diff --git a/tests/programs/array_values.expected b/tests/programs/array_values.expected
new file mode 100644
index 0000000..792708f
--- /dev/null
+++ b/tests/programs/array_values.expected
@@ -0,0 +1 @@
+7 0 8 9 0 3 9 7 1 255 6 6 5 4 7 9 5 9 ok 66 6 7 2 3 3 9
diff --git a/tests/programs/array_values.zc b/tests/programs/array_values.zc
new file mode 100644
index 0000000..01dd3aa
--- /dev/null
+++ b/tests/programs/array_values.zc
@@ -0,0 +1,30 @@
+namespace;
+include rt;
+
+int[] global = { 1, [5] = 9, 7 };
+int* static_values = (int[]){6, [3] = 9};
+int calls;
+int next_value() { calls++; return calls; }
+u8[4] packed = { 257, [3] = 255 };
+int sum(int[] a, int n) { int out = 0; for (int i = 0; i < n; i++) out += a[i]; return out; }
+fn main() {
+ int[] effects = {next_value(), [0] = next_value(), next_value()};
+ int[] a = { 1, 2, [5] = 8, 9, };
+ int[3] b = { 7 };
+ int[2][2] matrix = { { 1, 2 }, { 3, 4 } };
+ char[] text = "ok";
+ u8[] bytes = b"AB";
+ int[2][3] asymmetric = {1,2,3,4,5,6};
+ int[2][2] flat = {1, 2, 3, 4};
+ int[2][2] designated = { [1][0] = 8, 9, [0][1] = 7 };
+ int[2][2][2] cube = { [1][1] = {5,6} };
+ int[?] grow = { 6 }; push(grow, 7);
+ rt.put_n(sizeof(a)); rt.put_c(' '); rt.put_n(a[2]); rt.put_c(' '); rt.put_n(a[5]); rt.put_c(' '); rt.put_n(a[6]); rt.put_c(' ');
+ rt.put_n(b[1]); rt.put_c(' '); rt.put_n(matrix[1][0]); rt.put_c(' '); rt.put_n(global[5]); rt.put_c(' '); rt.put_n(global[6]); rt.put_c(' ');
+ rt.put_n(packed[0]); rt.put_c(' '); rt.put_n(packed[3]); rt.put_c(' '); rt.put_n(grow[0]); rt.put_c(' ');
+ rt.put_n(sum((int[]){1, 2, 3}, 3)); rt.put_c(' ');
+ let literal = { 4, 5 }; rt.put_n(literal[1]); rt.put_c(' ');
+ rt.put_n(flat[1][1]); rt.put_c(' '); rt.put_n(designated[0][1]); rt.put_c(' '); rt.put_n(designated[1][1]); rt.put_c(' '); rt.put_n(cube[1][1][0]); rt.put_c(' ');
+ rt.put_n((int[]){8,9}[1]); rt.put_c(' '); rt.put_s(text); rt.put_c(' '); rt.put_n(bytes[1]); rt.put_c(' '); rt.put_n(asymmetric[1][2]); rt.put_c(' '); rt.put_n(grow[1]); rt.put_c(' '); rt.put_n(effects[0]); rt.put_c(' '); rt.put_n(effects[1]); rt.put_c(' '); rt.put_n(calls); rt.put_c(' '); rt.put_n(static_values[3]); rt.put_c(10);
+ return 0;
+}
diff --git a/tests/programs/arrays.zc b/tests/programs/arrays.zc
index a8a12bf..b1fa43b 100644
--- a/tests/programs/arrays.zc
+++ b/tests/programs/arrays.zc
@@ -1,23 +1,26 @@
+namespace;
+include rt;
+
// growable arrays and fixed ones
struct point { int x, y; };
fn main() {
- let before = live_objects();
+ let before = rt.live_objects();
{
- []int a = new([]int);
+ int[?] a = rt.new(int[?]);
for (int i = 0; i < 100; i++) push(a, i * i);
- put_n(len(a)); put_c(' '); put_n(cap(a)); put_c(' '); put_n(a[99]); put_c(' ');
- put_n(pop(a)); put_c(' '); put_n(len(a)); put_c(' ');
- resize(a, 3); put_n(len(a)); put_c(' '); put_n(a[2]); put_c(' ');
- fixed []int f = new(fixed []int, 5);
- f[4] = 7; put_n(f[4] + len(f)); put_c(' ');
- []point ps = new([]point, 2);
- ps[1].y = 9; resize(ps, 10); put_n(ps[1].y + len(ps)); put_c(' ');
- [8]int st; put_n(len(st)); put_c(' ');
- []point* owned = new([]point*);
- for (int i = 0; i < 20; i++) { point* p = new(point); p.x = i; push(owned, d*p); }
- put_n(owned[19].x); put_c(' ');
- put_n(live_objects() - before); put_c(10);
+ rt.put_n(len(a)); rt.put_c(' '); rt.put_n(cap(a)); rt.put_c(' '); rt.put_n(a[99]); rt.put_c(' ');
+ rt.put_n(pop(a)); rt.put_c(' '); rt.put_n(len(a)); rt.put_c(' ');
+ resize(a, 3); rt.put_n(len(a)); rt.put_c(' '); rt.put_n(a[2]); rt.put_c(' ');
+ fixed int[?] f = rt.new(fixed int[?], 5);
+ f[4] = 7; rt.put_n(f[4] + len(f)); rt.put_c(' ');
+ point[?] ps = rt.new(point[?], 2);
+ ps[1].y = 9; resize(ps, 10); rt.put_n(ps[1].y + len(ps)); rt.put_c(' ');
+ int[8] st; rt.put_n(len(st)); rt.put_c(' ');
+ point*[?] owned = rt.new(point*[?]);
+ for (int i = 0; i < 20; i++) { point* p = rt.new(point); p.x = i; push(owned, d*p); }
+ rt.put_n(owned[19].x); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - before); rt.put_c(10);
}
- put_n(live_objects() - before); put_c(10);
+ rt.put_n(rt.live_objects() - before); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/backtick.zc b/tests/programs/backtick.zc
index 3610f70..548eac8 100644
--- a/tests/programs/backtick.zc
+++ b/tests/programs/backtick.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// a backtick ends the source only where the lexer would read it as a token.
// this one, in a line comment: ` does not end anything.
/* nor does this, in a block comment ` with a star / and a slash */
fn main() {
let s = "a`b", t = "q\"`", c = '`', d = '\'';
- put_n(len_w(s)); put_c(' '); put_n(len_w(t)); put_c(' '); put_n(c); put_c(' '); put_n(d); put_c(' ');
- while (!eof()) put_c(get_c());
+ rt.put_n(rt.len_w(s)); rt.put_c(' '); rt.put_n(rt.len_w(t)); rt.put_c(' '); rt.put_n(c); rt.put_c(' '); rt.put_n(d); rt.put_c(' ');
+ while (!rt.eof()) rt.put_c(rt.get_c());
return 0;
}
diff --git a/tests/programs/bareexit.zc b/tests/programs/bareexit.zc
index 905710e..1cede83 100644
--- a/tests/programs/bareexit.zc
+++ b/tests/programs/bareexit.zc
@@ -1,7 +1,10 @@
+namespace;
+include rt;
+
// exit(3) must stop the machine before the next print.
fn main() {
- put_s("bye\n");
- syscall(7, 3, 0, 0);
- put_s("still\n");
+ rt.put_s("bye\n");
+ rt.syscall(7, 3, 0, 0);
+ rt.put_s("still\n");
return 0;
}
diff --git a/tests/programs/bareio.zc b/tests/programs/bareio.zc
index 6da50b1..a06ef38 100644
--- a/tests/programs/bareio.zc
+++ b/tests/programs/bareio.zc
@@ -1,28 +1,31 @@
+namespace;
+include rt;
+
// bare-metal syscalls: clock, a RAM file, random, and the machine size.
// zc0 subset, so a run-only image can carry it. names stay off u/m/d.
fn main() {
let buf[16], n, t0, t1, i, fd, r, board[8];
- t0 = syscall(6, 0, 0, 0);
+ t0 = rt.syscall(6, 0, 0, 0);
i = 0;
while (i < 20000) i = i + 1;
- t1 = syscall(6, 0, 0, 0);
- if (t0 >= 0 && t1 >= t0) put_s("tick ");
- else put_s("notick ");
- fd = syscall(1, "note", 1, 0);
- n = syscall(4, fd, "zy", 2);
- syscall(2, fd, 0, 0);
- fd = syscall(1, "note", 0, 0);
- n = syscall(3, fd, buf, 8);
- syscall(2, fd, 0, 0);
+ t1 = rt.syscall(6, 0, 0, 0);
+ if (t0 >= 0 && t1 >= t0) rt.put_s("tick ");
+ else rt.put_s("notick ");
+ fd = rt.syscall(1, "note", 1, 0);
+ n = rt.syscall(4, fd, "zy", 2);
+ rt.syscall(2, fd, 0, 0);
+ fd = rt.syscall(1, "note", 0, 0);
+ n = rt.syscall(3, fd, buf, 8);
+ rt.syscall(2, fd, 0, 0);
buf[n] = 0;
- put_n(n); put_c(' '); put_s(buf); put_c(' ');
- r = syscall(8, 0, 0, 0);
- if (r != -1) put_s("rand ");
- else put_s("norand ");
- n = syscall(5, "BOARD", board, 8);
- if (n > 0) put_s("board ");
- else put_s("noboard ");
- put_n(syscall(9, 0, 0, 0));
- put_c(10);
+ rt.put_n(n); rt.put_c(' '); rt.put_s(buf); rt.put_c(' ');
+ r = rt.syscall(8, 0, 0, 0);
+ if (r != -1) rt.put_s("rand ");
+ else rt.put_s("norand ");
+ n = rt.syscall(5, "BOARD", board, 8);
+ if (n > 0) rt.put_s("board ");
+ else rt.put_s("noboard ");
+ rt.put_n(rt.syscall(9, 0, 0, 0));
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/basics.zc b/tests/programs/basics.zc
index 9865527..89ea882 100644
--- a/tests/programs/basics.zc
+++ b/tests/programs/basics.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
let table[10];
let greeting = "hey";
const N = 10, BIG = 0x100 * 2;
@@ -8,14 +11,14 @@ fn main() {
let i, s = 0, a[5];
for (i = 0; i < N; i++) table[i] = i * i;
for (let j = 0; j < N; j++) s += table[j];
- put_n(s); put_c(' '); put_n(fib(15)); put_c(' '); put_n(twice(inc, 40)); put_c(' '); put_n(BIG); put_c(10);
- put_s(greeting); put_c(' '); put_n('A'); put_c(' '); put_n(-17 / 5); put_c(' '); put_n(-17 % 5); put_c(' '); put_n(1 << 10); put_c(' '); put_n(-64 >> 3); put_c(10);
- i = 0; while (1) { i++; if (i == 3) continue; if (i > 6) break; put_n(i); } put_c(10);
- a[0] = 5; a[1] = a[0]++; a[2] = ++a[0]; put_n(a[0]); put_n(a[1]); put_n(a[2]); put_c(10);
+ rt.put_n(s); rt.put_c(' '); rt.put_n(fib(15)); rt.put_c(' '); rt.put_n(twice(inc, 40)); rt.put_c(' '); rt.put_n(BIG); rt.put_c(10);
+ rt.put_s(greeting); rt.put_c(' '); rt.put_n('A'); rt.put_c(' '); rt.put_n(-17 / 5); rt.put_c(' '); rt.put_n(-17 % 5); rt.put_c(' '); rt.put_n(1 << 10); rt.put_c(' '); rt.put_n(-64 >> 3); rt.put_c(10);
+ i = 0; while (1) { i++; if (i == 3) continue; if (i > 6) break; rt.put_n(i); } rt.put_c(10);
+ a[0] = 5; a[1] = a[0]++; a[2] = ++a[0]; rt.put_n(a[0]); rt.put_n(a[1]); rt.put_n(a[2]); rt.put_c(10);
let b = { let t = 3; t * t };
- put_n(b); put_c(' '); put_n(3 > 2 && 2 > 1); put_n(0 || 0); put_n(!5); put_n(~0); put_n(5 != 5); put_n(4 >= 4); put_c(10);
+ rt.put_n(b); rt.put_c(' '); rt.put_n(3 > 2 && 2 > 1); rt.put_n(0 || 0); rt.put_n(!5); rt.put_n(~0); rt.put_n(5 != 5); rt.put_n(4 >= 4); rt.put_c(10);
let x = asm { 2 3 + };
- put_n(x); put_c(10);
+ rt.put_n(x); rt.put_c(10);
asm { 'o' . 'k' . 10 . }
return 0;
}
diff --git a/tests/programs/bench.zc b/tests/programs/bench.zc
index 7d34ead..06d0782 100644
--- a/tests/programs/bench.zc
+++ b/tests/programs/bench.zc
@@ -1,17 +1,20 @@
+namespace;
+include rt;
+
// four kernels with and without o3; bench.sh runs each one on each backend
int csum(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; }
o3 int csum3(int lim) { int s = 0; for (int n = 1; n < lim; n++) { int x = n; while (x != 1) { if (x & 1) x = 3 * x + 1; else x = x / 2; s++; } } return s; }
-int sieve(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; }
-o3 int sieve3(fixed []int f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; }
+int sieve(fixed int[?] f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; }
+o3 int sieve3(fixed int[?] f) { int c = 0, n = len(f); for (int i = 0; i < n; i++) f[i] = 1; for (int i = 2; i < n; i++) if (f[i]) { c++; for (int j = i + i; j < n; j += i) f[j] = 0; } return c; }
int digits(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; }
o3 int digits3(int n) { int s = 0; for (int i = 0; i < n; i++) { int x = i; while (x) { s = s + x % 10; x = x / 10; } } return s; }
int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); }
o3 int fib3(int n) { if (n < 2) return n; return fib3(n - 1) + fib3(n - 2); }
// input: a letter (the kernel; z runs none) and how many times to run it
fn main() {
- fixed []int f = new(fixed []int, 50000);
- let which = get_c(), reps = 0, ch = get_c(), r = 0;
- while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = get_c(); }
+ fixed int[?] f = rt.new(fixed int[?], 50000);
+ let which = rt.get_c(), reps = 0, ch = rt.get_c(), r = 0;
+ while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = rt.get_c(); }
while (reps > 0) {
if (which == 'a') r = csum(30000);
if (which == 'b') r = csum3(30000);
@@ -23,7 +26,7 @@ fn main() {
if (which == 'h') r = fib3(22);
reps--;
}
- put_n(r); put_c(10);
- free(d*f);
+ rt.put_n(r); rt.put_c(10);
+ rt.free(d*f);
return 0;
}
diff --git a/tests/programs/bench_bytes.zc b/tests/programs/bench_bytes.zc
index cb878f6..086d752 100644
--- a/tests/programs/bench_bytes.zc
+++ b/tests/programs/bench_bytes.zc
@@ -1,19 +1,22 @@
+namespace;
+include rt;
+
fn sumbytes(n) {
let buf[64], i = 0, s = 0, b, reps, ch;
while (i < 64) { buf[i] = i * 0x0101010101010101; i++; }
- b = addr_b(buf);
- ch = get_c();
+ b = rt.addr_b(buf);
+ ch = rt.get_c();
reps = 0;
- while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = get_c(); }
+ while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = rt.get_c(); }
while (reps > 0) {
i = 0; s = 0;
- while (i < n) { s = s + ld8(b + (i & 511)); i++; }
+ while (i < n) { s = s + rt.ld8(b + (i & 511)); i++; }
reps--;
}
return s;
}
fn main() {
- put_n(sumbytes(4000));
- put_c(10);
+ rt.put_n(sumbytes(4000));
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/bench_share.zc b/tests/programs/bench_share.zc
index 6fa478f..04306fe 100644
--- a/tests/programs/bench_share.zc
+++ b/tests/programs/bench_share.zc
@@ -1,30 +1,33 @@
+namespace;
+include rt;
+
// walk one shared spine from two parents. the checksum is one repetition.
fn build() {
let i = 0, spine = 0;
- while (i < 40) { spine = cons(i, spine); i++; }
- return cons(cons(spine, 1), cons(spine, 2));
+ while (i < 40) { spine = rt.cons(i, spine); i++; }
+ return rt.cons(rt.cons(spine, 1), rt.cons(spine, 2));
}
fn sum(t) {
let a = 0;
- while (t) { a = a + car(t); t = cdr(t); }
+ while (t) { a = a + rt.car(t); t = rt.cdr(t); }
return a;
}
fn work() {
- let ch = get_c(), reps = 0, acc = 0, root, spine, k;
- while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = get_c(); }
+ let ch = rt.get_c(), reps = 0, acc = 0, root, spine, k;
+ while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = rt.get_c(); }
root = build();
- spine = car(car(root));
+ spine = rt.car(rt.car(root));
while (reps > 0) {
k = 0;
acc = 0;
while (k < 200) { acc = acc + sum(spine); k++; }
- acc = acc + cdr(car(root)) + cdr(cdr(root));
+ acc = acc + rt.cdr(rt.car(root)) + rt.cdr(rt.cdr(root));
reps--;
}
return acc;
}
fn main() {
- put_n(work());
- put_c(10);
+ rt.put_n(work());
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/bench_strings.zc b/tests/programs/bench_strings.zc
index 455cff9..6f224db 100644
--- a/tests/programs/bench_strings.zc
+++ b/tests/programs/bench_strings.zc
@@ -1,27 +1,30 @@
+namespace;
+include rt;
+
fn work() {
let s = b"abcdefghijklmnopqrstuvwxyz0123456789";
let i, acc, n, t, part, k, reps, ch;
- ch = get_c();
+ ch = rt.get_c();
reps = 0;
- while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = get_c(); }
+ while (ch >= '0' && ch <= '9') { reps = reps * 10 + ch - '0'; ch = rt.get_c(); }
while (reps > 0) {
- k = 0; acc = 0; n = len_s(s);
+ k = 0; acc = 0; n = rt.len_s(s);
while (k < 200) {
i = 0;
- while (i < n) { acc = acc + at_s(s, i); i++; }
+ while (i < n) { acc = acc + rt.at_s(s, i); i++; }
k++;
}
t = s + b"!";
part = t[1:8];
- acc = acc + len_s(t) + len_s(part) + at_s(part, 0);
- free(part);
- free(t);
+ acc = acc + rt.len_s(t) + rt.len_s(part) + rt.at_s(part, 0);
+ rt.free(part);
+ rt.free(t);
reps--;
}
return acc;
}
fn main() {
- put_n(work());
- put_c(10);
+ rt.put_n(work());
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/bitops.zc b/tests/programs/bitops.zc
index 97817b9..3b6b113 100644
--- a/tests/programs/bitops.zc
+++ b/tests/programs/bitops.zc
@@ -1,26 +1,29 @@
+namespace;
+include rt;
+
// bit tricks and float32 conversion as micro-ops
-fn show(v) { put_n(v); put_c(' '); }
+fn show(v) { rt.put_n(v); rt.put_c(' '); }
fn once() {
- show(clz(1)); show(clz(0)); show(ctz(8)); show(ctz(0));
- show(popcnt(255)); show(popcnt(-1)); show(popcnt(0));
- show(bswap(1) == 72057594037927936);
- show(rotl(1, 65)); show(rotr(1, 1) < 0); show(rotl(rotr(12345, 7), 7));
- show(mulhi(-1, 5)); show(umulhi(-1, 5));
- show(f2s(0x3ff8000000000000)); show(s2f(0x3fc00000) == 0x3ff8000000000000);
- show(f2s(0x3ff0000000000000)); show(f2s(0x3810000000000000));
- put_c(10);
+ show(rt.clz(1)); show(rt.clz(0)); show(rt.ctz(8)); show(rt.ctz(0));
+ show(rt.popcnt(255)); show(rt.popcnt(-1)); show(rt.popcnt(0));
+ show(rt.bswap(1) == 72057594037927936);
+ show(rt.rotl(1, 65)); show(rt.rotr(1, 1) < 0); show(rt.rotl(rt.rotr(12345, 7), 7));
+ show(rt.mulhi(-1, 5)); show(rt.umulhi(-1, 5));
+ show(rt.f2s(0x3ff8000000000000)); show(rt.s2f(0x3fc00000) == 0x3ff8000000000000);
+ show(rt.f2s(0x3ff0000000000000)); show(rt.f2s(0x3810000000000000));
+ rt.put_c(10);
}
// the same in a loop, so o3 lifts and fuses them
o3 int sums(int n) {
int a = 0;
for (int i = 0; i < n; i++) {
- a += popcnt(i) + ctz(i + 1) + clz(i + 1);
- a ^= rotl(a, 3) + bswap(i) + f2s(s2f(i));
+ a += rt.popcnt(i) + rt.ctz(i + 1) + rt.clz(i + 1);
+ a ^= rt.rotl(a, 3) + rt.bswap(i) + rt.f2s(rt.s2f(i));
}
return a;
}
int main() {
once();
- put_n(sums(1000)); put_c(10);
+ rt.put_n(sums(1000)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/borrow_rules.expected b/tests/programs/borrow_rules.expected
new file mode 100644
index 0000000..71bce3a
--- /dev/null
+++ b/tests/programs/borrow_rules.expected
@@ -0,0 +1 @@
+7 14 7 7 11 8 3 10 11 11 1 2 1 2 6 11 ok
diff --git a/tests/programs/borrow_rules.zc b/tests/programs/borrow_rules.zc
new file mode 100644
index 0000000..ed2b199
--- /dev/null
+++ b/tests/programs/borrow_rules.zc
@@ -0,0 +1,39 @@
+namespace;
+include rt;
+
+// last-use borrows do not block an owner's later move; disjoint projections remain independently usable.
+struct pair { int left, right; };
+int*.u make(int n) { int* p = rt.new(int); *p = n; return p; }
+int take(int*.d p) { return p[0]; }
+int twice(int*.m p, int*.m q) { return p[0] + q[0]; }
+char* alias(char*.m p) { return p; }
+word.u counter() {
+ int n = 0;
+ let next = fn() { n++; return n; };
+ return next;
+}
+word.u object_counter() {
+ int* value = rt.new(int);
+ let next = fn() { value[0]++; return value[0]; };
+ return next;
+}
+fn main() {
+ let p = make(7); int* borrowed = p + 0;
+ rt.put_n(borrowed[0]); rt.put_c(32); rt.put_n(twice(p,p)); rt.put_c(32);
+ rt.put_n(take(p)); rt.put_c(32);
+ let disposable = rt.new(2); rt.free(disposable);
+ pair* item = rt.new(pair); int* left = &item.left; int* right = &item.right;
+ *left = 3; *right = 4; rt.put_n(*left + *right); rt.put_c(32);
+ int[3] a = {1,2,3}; int* middle = &a[1]; middle[-1] = 5; a[2] = 6;
+ rt.put_n(middle[-1] + middle[1]); rt.put_c(32);
+ int[?] values = {8,9}; int* first = &values[0]; rt.put_n(first[0]); rt.put_c(32); resize(values,3);
+ rt.put_n(len(values)); rt.put_c(32);
+ int n = 0; let next = fn() { return ++n; }; let current = fn() { return n; };
+ next(); n = 10; rt.put_n(current()); rt.put_c(32); rt.put_n(next()); rt.put_c(32); rt.put_n(n); rt.put_c(32);
+ let escaping = counter(); rt.gc(); rt.put_n(escaping()); rt.put_c(32); rt.put_n(escaping()); rt.put_c(32);
+ let heap = object_counter(); rt.gc(); rt.put_n(heap()); rt.put_c(32); rt.put_n(heap()); rt.put_c(32);
+ int sum = 0, i = 0; while (i < 3) { sum += i; let f = fn() { return ++sum; }; f(); i++; }
+ rt.put_n(sum); rt.put_c(32);
+ let raw = fn() { return asm { n @ }; }; rt.put_n(raw()); rt.put_c(32);
+ rt.put_s(alias("ok")); rt.put_c(10);
+}
diff --git a/tests/programs/borrowmove.zc b/tests/programs/borrowmove.zc
index b0f0e42..e229fab 100644
--- a/tests/programs/borrowmove.zc
+++ b/tests/programs/borrowmove.zc
@@ -1,2 +1,5 @@
-fn put(.m box, int v) { int* c = new(int); *c = v; box[0] = c; return 0; }
-fn main() { let b = new(1); put(b, 6); put_n(*(b[0] as int*)); put_c(10); return 0; }
+namespace;
+include rt;
+
+fn put(.m box, int v) { int* c = rt.new(int); *c = v; box[0] = c; return 0; }
+fn main() { let b = rt.new(1); put(b, 6); rt.put_n(*(b[0] as int*)); rt.put_c(10); return 0; }
diff --git a/tests/programs/bounds.zc b/tests/programs/bounds.zc
index 42c3997..6908683 100644
--- a/tests/programs/bounds.zc
+++ b/tests/programs/bounds.zc
@@ -1,17 +1,20 @@
+namespace;
+include rt;
+
// a +1 loop whose bound is len of the fixed array: the check is gone, the sum is not
-fn acc(fixed []int f) {
+fn acc(fixed int[?] f) {
int n = len(f), i = 0, s = 0;
for (; i < n; i += 1) f[i] = i + 1;
for (i = 0; i < n; i++) s = s + f[i];
return s;
}
-o3 fn acc3(fixed []int f) {
+o3 fn acc3(fixed int[?] f) {
int n = len(f), i = 0, s = 0;
for (; i < n; i++) f[i] = i + 1;
for (i = 0; i < n; i++) s += f[i];
return s;
}
-o3 fn small(fixed []int f) {
+o3 fn small(fixed int[?] f) {
int n = len(f), c = 0, i, j;
for (i = 2; i < n; i++) f[i] = 1;
for (i = 2; i * i < n; i++)
@@ -20,9 +23,9 @@ o3 fn small(fixed []int f) {
return c;
}
fn main() {
- fixed []int f = new(fixed []int, 10);
- fixed []int g = new(fixed []int, 20);
- put_n(acc(f)); put_c(32); put_n(acc3(f)); put_c(32); put_n(small(g)); put_c(10);
- free(d*f); free(d*g);
+ fixed int[?] f = rt.new(fixed int[?], 10);
+ fixed int[?] g = rt.new(fixed int[?], 20);
+ rt.put_n(acc(f)); rt.put_c(32); rt.put_n(acc3(f)); rt.put_c(32); rt.put_n(small(g)); rt.put_c(10);
+ rt.free(d*f); rt.free(d*g);
return 0;
}
diff --git a/tests/programs/bounds_hi.zc b/tests/programs/bounds_hi.zc
index d61179d..49639c5 100644
--- a/tests/programs/bounds_hi.zc
+++ b/tests/programs/bounds_hi.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt;
+
// the index is not the induction variable. i + 1 walks off the end.
o3 fn main() {
- fixed []int f = new(fixed []int, 4);
+ fixed int[?] f = rt.new(fixed int[?], 4);
int n = len(f), i;
for (i = 0; i < n; i++) f[i + 1] = 1;
- free(d*f);
+ rt.free(d*f);
return 0;
}
diff --git a/tests/programs/bounds_lo.zc b/tests/programs/bounds_lo.zc
index 896d864..b6a82f4 100644
--- a/tests/programs/bounds_lo.zc
+++ b/tests/programs/bounds_lo.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt;
+
// i starts negative. i < len is true for the first pass, and the index is still illegal.
fn main() {
- fixed []int f = new(fixed []int, 4);
+ fixed int[?] f = rt.new(fixed int[?], 4);
int n = len(f), i;
for (i = -1; i < n; i++) f[i] = 1;
- free(d*f);
+ rt.free(d*f);
return 0;
}
diff --git a/tests/programs/bstr_io.zc b/tests/programs/bstr_io.zc
index 9cf7ca9..8b1f2af 100644
--- a/tests/programs/bstr_io.zc
+++ b/tests/programs/bstr_io.zc
@@ -1,22 +1,25 @@
+namespace;
+include rt;
+
fn main() {
let path = b"/tmp/zc-bstr.txt";
let msg = b"byte-io";
- let fd = bopen(path, 1);
- let n = bwrite(fd, msg, len_s(msg));
- syscall(SYS_CLOSE, fd, 0, 0);
- fd = bopen(path, 0);
- let buf = new_s(7);
- let g = bread(fd, buf, 7);
- syscall(SYS_CLOSE, fd, 0, 0);
+ let fd = rt.bopen(path, 1);
+ let n = rt.bwrite(fd, msg, rt.len_s(msg));
+ rt.syscall(rt.SYS_CLOSE, fd, 0, 0);
+ fd = rt.bopen(path, 0);
+ let buf = rt.new_s(7);
+ let g = rt.bread(fd, buf, 7);
+ rt.syscall(rt.SYS_CLOSE, fd, 0, 0);
let name = b"ZC_BSTR";
- let envb = new_s(16);
- let k = bgetenv(name, envb, 16);
- put_s(buf); put_c(32);
- put_n(n); put_c(32);
- put_n(g); put_c(32);
- put_n(buf == msg); put_c(32);
- put_n(k); put_c(32);
- put_n(at_s(envb, 0)); put_c(32);
- put_n(at_s(envb, 5)); put_c(10);
+ let envb = rt.new_s(16);
+ let k = rt.bgetenv(name, envb, 16);
+ rt.put_s(buf); rt.put_c(32);
+ rt.put_n(n); rt.put_c(32);
+ rt.put_n(g); rt.put_c(32);
+ rt.put_n(buf == msg); rt.put_c(32);
+ rt.put_n(k); rt.put_c(32);
+ rt.put_n(rt.at_s(envb, 0)); rt.put_c(32);
+ rt.put_n(rt.at_s(envb, 5)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/buddy.zc b/tests/programs/buddy.zc
index ab351d2..c92a790 100644
--- a/tests/programs/buddy.zc
+++ b/tests/programs/buddy.zc
@@ -1,16 +1,19 @@
+namespace;
+include rt;
+
// the buddy allocator: 20000 small blocks, freed, merge back into one big one
let keep[20000];
fn main() {
let i = 0, p;
- while (i < 20000) { keep[i] = new(2); i++; } // 20000 8-word blocks
- put_n(largest_free()); put_c(' ');
- i = 0; while (i < 20000) { free(keep[i]); keep[i] = 0; i++; }
- scrub(); // stale stack words would keep the quarantined blocks
- gc();
- put_n(largest_free()); put_c(' ');
- p = new(200000); // only possible if the small blocks merged back
- put_n(osize(p) >= 200000); put_c(' ');
- free(d*p);
- put_n(live_objects()); put_c(10);
+ while (i < 20000) { keep[i] = rt.new(2); i++; } // 20000 8-word blocks
+ rt.put_n(rt.largest_free()); rt.put_c(' ');
+ i = 0; while (i < 20000) { rt.free(keep[i]); keep[i] = 0; i++; }
+ rt.scrub(); // stale stack words would keep the quarantined blocks
+ rt.gc();
+ rt.put_n(rt.largest_free()); rt.put_c(' ');
+ p = rt.new(200000); // only possible if the small blocks merged back
+ rt.put_n(rt.osize(p) >= 200000); rt.put_c(' ');
+ rt.free(d*p);
+ rt.put_n(rt.live_objects()); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/bytes.zc b/tests/programs/bytes.zc
index b4e1079..1332c26 100644
--- a/tests/programs/bytes.zc
+++ b/tests/programs/bytes.zc
@@ -1,44 +1,47 @@
-fn sp() { put_c(32); return 0; }
+namespace;
+include rt;
+
+fn sp() { rt.put_c(32); return 0; }
fn litw(v) { return v + v + 1; }
-fn f() { put_c('A'); return 0; }
+fn f() { rt.put_c('A'); return 0; }
fn sumbytes(n) {
let buf[64], i = 0, s = 0, b;
while (i < 64) { buf[i] = i * 0x0101010101010101; i++; }
- b = addr_b(buf);
+ b = rt.addr_b(buf);
i = 0;
- while (i < n) { s = s + ld8(b + (i & 511)); i++; }
+ while (i < n) { s = s + rt.ld8(b + (i & 511)); i++; }
return s;
}
fn main() {
let buf[3], b;
buf[0] = 0; buf[1] = 0; buf[2] = 0;
- b = addr_b(buf);
- st8(b, 0x11);
- st8(b + 1, 0x22);
- st8(b + 7, 0x7f);
- st16(b + 7, 0xabcd);
- st32(b + 10, 0x01020304);
- put_n(ld8(b)); sp();
- put_n(ld8(b + 1)); sp();
- put_n(ld16(b + 7)); sp();
- put_n(ld32(b + 10)); sp();
- put_n(addr_w(b) == buf); sp();
- put_n(ld8(b + 7)); sp();
- put_n(ld8(b + 8)); sp();
- put_n(buf[0]); sp();
- put_n(buf[1]); sp();
- st8(0 - 1, 99);
- put_n(ld8(0 - 1)); sp();
- put_n(ld16(addr_b(MW) - 1)); sp();
- put_n(sumbytes(1000));
- put_c(10);
+ b = rt.addr_b(buf);
+ rt.st8(b, 0x11);
+ rt.st8(b + 1, 0x22);
+ rt.st8(b + 7, 0x7f);
+ rt.st16(b + 7, 0xabcd);
+ rt.st32(b + 10, 0x01020304);
+ rt.put_n(rt.ld8(b)); sp();
+ rt.put_n(rt.ld8(b + 1)); sp();
+ rt.put_n(rt.ld16(b + 7)); sp();
+ rt.put_n(rt.ld32(b + 10)); sp();
+ rt.put_n(rt.addr_w(b) == buf); sp();
+ rt.put_n(rt.ld8(b + 7)); sp();
+ rt.put_n(rt.ld8(b + 8)); sp();
+ rt.put_n(buf[0]); sp();
+ rt.put_n(buf[1]); sp();
+ rt.st8(0 - 1, 99);
+ rt.put_n(rt.ld8(0 - 1)); sp();
+ rt.put_n(rt.ld16(rt.addr_b(rt.MW) - 1)); sp();
+ rt.put_n(sumbytes(1000));
+ rt.put_c(10);
let p = f;
f();
while (*p != litw('A')) p++;
- st8(addr_b(p), litw('B') & 255);
+ rt.st8(rt.addr_b(p), litw('B') & 255);
f();
- st8(addr_b(p), litw('C') & 255);
+ rt.st8(rt.addr_b(p), litw('C') & 255);
f();
- put_c(10);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/cabi.zc b/tests/programs/cabi.zc
index 6a608ab..da9518b 100644
--- a/tests/programs/cabi.zc
+++ b/tests/programs/cabi.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// native calls: extern declares a c function, cfunc hands a zc function to c
extern double sqrt(double);
extern double pow(double x, double y);
@@ -10,7 +13,7 @@ extern int snprintf2(word *buf, long cap, str fmt, long a, double b) = "snprintf
extern double hypot(double, double);
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
int cmp(int* a, int* b) { return *a - *b; }
// a callback that makes a native call of its own, and an o3 one
@@ -23,24 +26,24 @@ fn main() {
put_f(sqrt(2.0)); sp();
put_f(pow(2.0, 10.0)); sp();
put_f(sqrtf(16.0)); sp();
- put_n(c_strlen(b"hello, world")); sp();
- put_n(c_abs(0 - 42)); sp();
- put_n(c_atoi(b"1234xyz")); sp();
+ rt.put_n(c_strlen(b"hello, world")); sp();
+ rt.put_n(c_abs(0 - 42)); sp();
+ rt.put_n(c_atoi(b"1234xyz")); sp();
a[0] = 5; a[1] = 3; a[2] = 9; a[3] = 1; a[4] = 7; a[5] = 2;
qsort(a, 6, 8, cfunc(cmp));
- while (i < 6) { put_n(a[i]); sp(); i++; }
- put_c(10);
+ while (i < 6) { rt.put_n(a[i]); sp(); i++; }
+ rt.put_c(10);
qsort(a, 6, 8, cfunc(cmpdesc));
- i = 0; while (i < 6) { put_n(a[i]); sp(); i++; }
- put_c(10);
+ i = 0; while (i < 6) { rt.put_n(a[i]); sp(); i++; }
+ rt.put_c(10);
qsort(a, 6, 8, cfunc(cmp));
- i = 0; while (i < 6) { put_n(a[i]); sp(); i++; }
+ i = 0; while (i < 6) { rt.put_n(a[i]); sp(); i++; }
qsort(a, 6, 8, cfunc(cmpo3));
- i = 0; while (i < 6) { put_n(a[i]); sp(); i++; }
- put_c(10);
- put_n(snprintf2(a, 48, b"%ld:%.2f", 7, 2.5)); sp();
- i = 0; while (i < 6) { put_c(ld8(addr_b(a) + i)); i++; }
- put_c(10);
- put_f(hypot(3.0, 4.0)); put_c(10);
+ i = 0; while (i < 6) { rt.put_n(a[i]); sp(); i++; }
+ rt.put_c(10);
+ rt.put_n(snprintf2(a, 48, b"%ld:%.2f", 7, 2.5)); sp();
+ i = 0; while (i < 6) { rt.put_c(rt.ld8(rt.addr_b(a) + i)); i++; }
+ rt.put_c(10);
+ put_f(hypot(3.0, 4.0)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/cabi_o3.zc b/tests/programs/cabi_o3.zc
index 5c9a55a..6020dd8 100644
--- a/tests/programs/cabi_o3.zc
+++ b/tests/programs/cabi_o3.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// native calls from o3 code: lifted into the region as micro-ops, called directly by llvm
extern double sqrt(double);
extern double pow(double, double);
@@ -20,11 +23,11 @@ o3 int absum(int n) {
fn main() {
let buf[16];
let i = 0;
- put_f(norm(100)); put_c(32);
- put_f(pow(2.0, 0.5)); put_c(32);
- put_n(absum(100)); put_c(10);
- put_n(snprintf9(buf, 100, b"%ld-%ld-%ld-%ld-%ld-%ld", 1, 2, 3, 4, 5, 6)); put_c(32);
- while (i < 11) { put_c(ld8(addr_b(buf) + i)); i++; }
- put_c(10);
+ put_f(norm(100)); rt.put_c(32);
+ put_f(pow(2.0, 0.5)); rt.put_c(32);
+ rt.put_n(absum(100)); rt.put_c(10);
+ rt.put_n(snprintf9(buf, 100, b"%ld-%ld-%ld-%ld-%ld-%ld", 1, 2, 3, 4, 5, 6)); rt.put_c(32);
+ while (i < 11) { rt.put_c(rt.ld8(rt.addr_b(buf) + i)); i++; }
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/cabi_sized.zc b/tests/programs/cabi_sized.zc
index d1dc2ba..8460107 100644
--- a/tests/programs/cabi_sized.zc
+++ b/tests/programs/cabi_sized.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// extern and cfunc with f32 and the sized integers
extern f32 sqrtf(f32);
extern f64 hypot(f64, f64);
@@ -5,24 +8,24 @@ extern i32 abs(i32);
extern u8 toupper(u8);
extern long labs(long);
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
extern void qsort(word *base, long n, long size, void *cmp);
i32 cmpi(int* a, int* b) { return *a - *b; }
f32 half(f32 v) { return v / 2; }
fn main() {
f32 r = sqrtf(2.0);
put_f(r); sp();
- put_n(r == sqrtf(2.0)); sp();
+ rt.put_n(r == sqrtf(2.0)); sp();
put_f(hypot(3.0, 4.0)); sp();
- put_n(abs(0 - 77)); sp();
- put_n(toupper(97)); sp();
+ rt.put_n(abs(0 - 77)); sp();
+ rt.put_n(toupper(97)); sp();
i32 big = 0 - 5;
- put_n(abs(big)); sp();
+ rt.put_n(abs(big)); sp();
int v[4];
v[0] = 4; v[1] = 1; v[2] = 3; v[3] = 2;
qsort(v, 4, 8, cfunc(cmpi));
- put_n(v[0]); put_n(v[1]); put_n(v[2]); put_n(v[3]); sp();
+ rt.put_n(v[0]); rt.put_n(v[1]); rt.put_n(v[2]); rt.put_n(v[3]); sp();
put_f(half(5.0));
- put_c(10);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/capture.zc b/tests/programs/capture.zc
index c178791..34d03a6 100644
--- a/tests/programs/capture.zc
+++ b/tests/programs/capture.zc
@@ -1,31 +1,34 @@
+namespace;
+include rt, std;
+
// capture.start() sends everything the program writes into a string instead of
-// the terminal, and buf.end() stops it and terminates the string. nothing may
+// the terminal, and capture.end(buf) stops it and terminates the string. nothing may
// be printed during a capture, or it lands in the buffer too.
-include "src/lib/std.zc";
+include std;
fn main() {
- let buf = capture.start();
- put_s("hello world!");
- put_n(42);
- put_c(10);
- buf.end(); // stops the capture and terminates the string
+ let buf = std.capture.start();
+ rt.put_s("hello world!");
+ rt.put_n(42);
+ rt.put_c(10);
+ std.capture.end(buf); // stops the capture and terminates the string
// the capture is off again, so these go to the terminal
- put_n(outmode); put_c(10); // 0
- put_n(outbuf == 0); put_c(10); // 1, the buffer is handed over
- put_n(len_w(buf)); put_c(10); // 15
- put_s(buf); // hello world!42
+ rt.put_n(rt.outmode); rt.put_c(10); // 0
+ rt.put_n(rt.outbuf == 0); rt.put_c(10); // 1, the buffer is handed over
+ rt.put_n(rt.len_w(buf)); rt.put_c(10); // 15
+ rt.put_s(buf); // hello world!42
// a second capture does not disturb the first, and both read back
- let two = capture.start();
- put_s("second");
- two.end();
- put_n(eq_w(buf, "hello world!42\n")); put_c(10); // 1
- put_n(eq_w(two, "second")); put_c(10); // 1
+ let two = std.capture.start();
+ rt.put_s("second");
+ std.capture.end(two);
+ rt.put_n(rt.eq_w(buf, "hello world!42\n")); rt.put_c(10); // 1
+ rt.put_n(rt.eq_w(two, "second")); rt.put_c(10); // 1
// capture_stdin returns an empty string, so an unused capture is empty
- let three = capture.start();
- three.end();
- put_n(len_w(three)); put_c(10); // 0
+ let three = std.capture.start();
+ std.capture.end(three);
+ rt.put_n(rt.len_w(three)); rt.put_c(10); // 0
return 0;
} \ No newline at end of file
diff --git a/tests/programs/closure.zc b/tests/programs/closure.zc
index 660c32a..eee6226 100644
--- a/tests/programs/closure.zc
+++ b/tests/programs/closure.zc
@@ -1,4 +1,7 @@
-// closures: calls through values, captures by value, state in a capture,
+namespace;
+include rt;
+
+// closures: calls through values, shared captures, state in a capture,
// nested captures, closures passed as arguments and returned from functions
fn apply(f, x) { return f(x); }
fn twice(g, x) { return g(g(x)); }
@@ -10,30 +13,30 @@ word.u make(n) {
fn main() {
let k = 10, m = 3;
let add = fn(x) { return x + k * m; };
- put_n(add(1)); put_c(10);
- put_n(apply(add, 5)); put_c(10);
+ rt.put_n(add(1)); rt.put_c(10);
+ rt.put_n(apply(add, 5)); rt.put_c(10);
let none = fn() { return 42; };
- put_n(none()); put_c(10);
+ rt.put_n(none()); rt.put_c(10);
let n = 0;
let bump = fn(d) { n = n + d; return n; };
- put_n(bump(2)); put_c(10);
- put_n(bump(5)); put_c(10);
- put_n(n); put_c(10);
+ rt.put_n(bump(2)); rt.put_c(10);
+ rt.put_n(bump(5)); rt.put_c(10);
+ rt.put_n(n); rt.put_c(10);
let a = 2;
let outer = fn(x) {
let inner = fn(y) { return y + a + x; };
return inner(100);
};
- put_n(outer(7)); put_c(10);
+ rt.put_n(outer(7)); rt.put_c(10);
let base = 5;
let scale = fn(i) { return i * base; };
let s = 0, i = 0;
while (i < 4) { s = s + scale(i); i++; }
- put_n(s); put_c(10);
+ rt.put_n(s); rt.put_c(10);
let c = 3;
let plus = fn(v) { return v + c; };
- put_n(twice(plus, 1)); put_c(10);
- put_n(sq(4)); put_c(10);
+ rt.put_n(twice(plus, 1)); rt.put_c(10);
+ rt.put_n(sq(4)); rt.put_c(10);
let total = 0, j = 0;
while (j < 3) {
let kk = j;
@@ -41,12 +44,12 @@ fn main() {
total = total + g(10);
j++;
}
- put_n(total); put_c(10);
+ rt.put_n(total); rt.put_c(10);
let f = make(4);
- put_n(f(5)); put_c(10);
+ rt.put_n(f(5)); rt.put_c(10);
let h = 1;
let frozen = fn(x) { return x + h; };
h = 100;
- put_n(frozen(1)); put_c(10);
+ rt.put_n(frozen(1)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/closure_result.zc b/tests/programs/closure_result.zc
new file mode 100644
index 0000000..57b666e
--- /dev/null
+++ b/tests/programs/closure_result.zc
@@ -0,0 +1,12 @@
+namespace;
+include rt;
+
+// fn:type(args) declares a closure's result; returns are coerced to it
+fn put_f(x) { asm { x @ #1220 } return 0; }
+fn main() {
+ let half = fn:float(int x) { return x; };
+ let twice = fn:int(int x) { return x * 2; };
+ rt.put_n(twice(4)); rt.put_c(32);
+ put_f(half(3) / 2.0); rt.put_c(10);
+ return 0;
+}
diff --git a/tests/programs/csyn.zc b/tests/programs/csyn.zc
index 0099d1c..1bf8949 100644
--- a/tests/programs/csyn.zc
+++ b/tests/programs/csyn.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// do/while, enum constants, and a C cast
typecheck on;
enum color { RED, GREEN = 5, BLUE };
@@ -10,9 +13,9 @@ fn main() {
} while (i < 5);
int* p = (int*)0;
int z = (int)p;
- put_n(n); put_c(' ');
- put_n(RED); put_c(' '); put_n(GREEN); put_c(' ');
- put_n(BLUE); put_c(' ');
- put_n(z); put_c(10);
+ rt.put_n(n); rt.put_c(' ');
+ rt.put_n(RED); rt.put_c(' '); rt.put_n(GREEN); rt.put_c(' ');
+ rt.put_n(BLUE); rt.put_c(' ');
+ rt.put_n(z); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/decl_undefined.zc b/tests/programs/decl_undefined.zc
index 0ee9312..860e560 100644
--- a/tests/programs/decl_undefined.zc
+++ b/tests/programs/decl_undefined.zc
@@ -1,2 +1,4 @@
+namespace;
+
fn helper();
fn main() { helper(); return 0; }
diff --git a/tests/programs/discard_m.zc b/tests/programs/discard_m.zc
index 35e9f3b..85accfb 100644
--- a/tests/programs/discard_m.zc
+++ b/tests/programs/discard_m.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// m* on an unnamed u result lets the value be discarded; the plain call is an error
-.u mk(int v) { let p = new(1); p[0] = v; return u*p; }
-fn main() { m*mk(7); m*mk(8); put_n(7); put_c(10); return 0; }
+.u mk(int v) { let p = rt.new(1); p[0] = v; return u*p; }
+fn main() { m*mk(7); m*mk(8); rt.put_n(7); rt.put_c(10); return 0; }
diff --git a/tests/programs/doublefree.zc b/tests/programs/doublefree.zc
index 296b194..c0793e3 100644
--- a/tests/programs/doublefree.zc
+++ b/tests/programs/doublefree.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
memdebug on;
unchecked fn main()
{
- let p = new(1);
- free(p);
- free(p);
- put_s("ok\n");
+ let p = rt.new(1);
+ rt.free(p);
+ rt.free(p);
+ rt.put_s("ok\n");
return 0;
}
diff --git a/tests/programs/enhance.zc b/tests/programs/enhance.zc
index 327b4bd..2d6ea43 100644
--- a/tests/programs/enhance.zc
+++ b/tests/programs/enhance.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// custom opcodes: recipes, lifted vm code, several outputs, and a fallback
enhance clampadd(a, b) micro "a = add a b; a = min a 100; a = max a 0";
enhance cube(x) vm { 0 $ 0 $ * * };
@@ -11,18 +14,18 @@ let qq, rr, seed = 7;
fn rnd() { seed = seed * 1103515245 + 12345; return seed ^ (seed >> 11); }
fn main() {
let i = 0, a, bad = 0;
- put_n(clampadd(70, 50)); put_c(' '); put_n(clampadd(-50, 2)); put_c(' '); put_n(cube(7)); put_c(' ');
+ rt.put_n(clampadd(70, 50)); rt.put_c(' '); rt.put_n(clampadd(-50, 2)); rt.put_c(' '); rt.put_n(cube(7)); rt.put_c(' ');
asm { 17 5 divmod rr ! qq ! }
- put_n(qq); put_c(','); put_n(rr); put_c(' ');
- put_n(noisy(4)); put_c(' ');
- put_n(hi(-1, -1)); put_c(' ');
+ rt.put_n(qq); rt.put_c(','); rt.put_n(rr); rt.put_c(' ');
+ rt.put_n(noisy(4)); rt.put_c(' ');
+ rt.put_n(hi(-1, -1)); rt.put_c(' ');
while (i < 5000) {
a = rnd();
- if (div7(a) != zdiv(a, 7)) bad++;
+ if (div7(a) != rt.zdiv(a, 7)) bad++;
if (urem10(a) < 0 || urem10(a) > 9) bad++;
- if (a / (i + 1) != zdiv(a, i + 1)) bad++;
+ if (a / (i + 1) != rt.zdiv(a, i + 1)) bad++;
i++;
}
- put_n(bad); put_c(10);
+ rt.put_n(bad); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/enumscope.zc b/tests/programs/enumscope.zc
index 5c6d7d0..6c66ee8 100644
--- a/tests/programs/enumscope.zc
+++ b/tests/programs/enumscope.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// enum members are reached through the enum's name as well as plainly
enum color { RED, GREEN = 5, BLUE };
fn main() {
int c = color.BLUE;
- put_n(color.RED); put_c(' '); put_n(GREEN); put_c(' ');
- put_n(c); put_c(' ');
- switch (c) { case color.BLUE: put_s("blue"); break; default: put_s("other"); }
+ rt.put_n(color.RED); rt.put_c(' '); rt.put_n(GREEN); rt.put_c(' ');
+ rt.put_n(c); rt.put_c(' ');
+ switch (c) { case color.BLUE: rt.put_s("blue"); break; default: rt.put_s("other"); }
return 0;
}
diff --git a/tests/programs/enumtype.zc b/tests/programs/enumtype.zc
index 9a6e89b..229be99 100644
--- a/tests/programs/enumtype.zc
+++ b/tests/programs/enumtype.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// enums are a type of their own in typed code: their members, and only those, take them; an enum still becomes an int
typecheck on;
enum color { RED, GREEN = 5, BLUE };
@@ -6,7 +9,7 @@ int main() {
color c = color.BLUE;
color d = RED;
int n = c;
- put_n(n); put_c(32); put_n(paint(GREEN)); put_c(32); put_n(d == color.RED);
- put_c(10);
+ rt.put_n(n); rt.put_c(32); rt.put_n(paint(GREEN)); rt.put_c(32); rt.put_n(d == color.RED);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/f32.zc b/tests/programs/f32.zc
index 0f60dcd..718ed8d 100644
--- a/tests/programs/f32.zc
+++ b/tests/programs/f32.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt, run;
+
// f32: single precision values and packed arrays of them
struct vec3 { f32 x, y, z; };
f32 gsum;
fn put_f(x) { asm { x @ #1220 } return 0; }
-[8]f32 gbuf;
+f32[8] run.gbuf;
f32 half(f32 v) { return v / 2; }
@@ -13,25 +16,25 @@ fn main() {
float c = 16777216.0 + 1.0;
f32 t = 0.1;
float u = 0.1;
- put_f(b); put_c(' '); put_f(c); put_c(' ');
- put_n(t == 0.1); put_n(t == u); put_n(t == (f32)u); put_c(' ');
- put_f(half(3.0)); put_c(' ');
- put_f(gsum * 10); put_c(' '); // 1.000000 (0.1f * 10 in double)
+ put_f(b); rt.put_c(' '); put_f(c); rt.put_c(' ');
+ rt.put_n(t == 0.1); rt.put_n(t == u); rt.put_n(t == (f32)u); rt.put_c(' ');
+ put_f(half(3.0)); rt.put_c(' ');
+ put_f(gsum * 10); rt.put_c(' '); // 1.000000 (0.1f * 10 in double)
vec3 v; v.x = 1.5; v.y = 0.1; v.z = 2;
- put_f(v.x + v.y + v.z); put_c(' ');
+ put_f(v.x + v.y + v.z); rt.put_c(' ');
int i = 0;
- gbuf[0] = 0.1; put_n(gbuf[0] == t); put_n(gbuf[0] == u); put_c(' ');
- while (i < 8) { gbuf[i] = i * 0.25 + 0.1; i++; }
+ run.gbuf[0] = 0.1; rt.put_n(run.gbuf[0] == t); rt.put_n(run.gbuf[0] == u); rt.put_c(' ');
+ while (i < 8) { run.gbuf[i] = i * 0.25 + 0.1; i++; }
float s = 0;
i = 0;
- while (i < 8) { s += gbuf[i]; i++; }
- put_f(s); put_c(' ');
- f32* p = new(f32, 100);
+ while (i < 8) { s += run.gbuf[i]; i++; }
+ put_f(s); rt.put_c(' ');
+ f32* p = rt.new(f32, 100);
i = 0;
while (i < 100) { p[i] = i; i++; }
s = 0; i = 0;
while (i < 100) { s += p[i]; i++; }
- put_f(s); put_c(' ');
- put_n(sizeof(gbuf)); put_n(sizeof([100]f32)); put_c(10);
- free(d*p);
+ put_f(s); rt.put_c(' ');
+ rt.put_n(sizeof(run.gbuf)); rt.put_n(sizeof(f32[100])); rt.put_c(10);
+ rt.free(d*p);
}
diff --git a/tests/programs/f32o3.zc b/tests/programs/f32o3.zc
index 8f1ec2b..94b058c 100644
--- a/tests/programs/f32o3.zc
+++ b/tests/programs/f32o3.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// f32 packed arrays and rounding inside an o3 region
fn put_f(x) { asm { x @ #1220 } return 0; }
o3 float dot(f32* p, int n) {
@@ -7,8 +10,8 @@ o3 float dot(f32* p, int n) {
return s + acc;
}
fn main() {
- f32* p = new(f32, 50);
+ f32* p = rt.new(f32, 50);
for (int i = 0; i < 50; i++) p[i] = i * 0.5;
- put_f(dot(p, 50)); put_c(' '); put_f(p[3]); put_c(' '); put_n(p[3] == 1.6); put_c(10);
- free(d*p);
+ put_f(dot(p, 50)); rt.put_c(' '); put_f(p[3]); rt.put_c(' '); rt.put_n(p[3] == 1.6); rt.put_c(10);
+ rt.free(d*p);
}
diff --git a/tests/programs/fbench.zc b/tests/programs/fbench.zc
index 1658ba7..c3b7086 100644
--- a/tests/programs/fbench.zc
+++ b/tests/programs/fbench.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// float kernel, plain and o3. bench_float.sh times them. the letter picks the
// kernel and the digits are how many times to run it, same shape as bench.zc.
float poly(int n) {
@@ -23,15 +26,15 @@ o3 float poly3(int n) {
return s;
}
fn main() {
- let which = get_c(), reps = 0, ch = get_c(), r = 0;
- while (ch >= 48 && ch <= 57) { reps = reps * 10 + ch - 48; ch = get_c(); }
+ let which = rt.get_c(), reps = 0, ch = rt.get_c(), r = 0;
+ while (ch >= 48 && ch <= 57) { reps = reps * 10 + ch - 48; ch = rt.get_c(); }
while (reps > 0) {
if (which == 97) r = (int)poly(20000);
if (which == 98) r = (int)poly3(20000);
if (which == 99) r = (int)poly(2000);
reps = reps - 1;
}
- put_n(r);
- put_c(10);
+ rt.put_n(r);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/float.zc b/tests/programs/float.zc
index 81b8668..8e9cd35 100644
--- a/tests/programs/float.zc
+++ b/tests/programs/float.zc
@@ -1,7 +1,10 @@
+namespace;
+include rt;
+
fn put_f(x) { asm { x @ #1220 } return 0; }
fn f2i(x) { return asm { x @ #1218 }; }
fn i2f(x) { return asm { x @ #1216 }; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
fn main() {
let a = 1.5;
@@ -17,16 +20,16 @@ fn main() {
put_f(1.0 / 0.0); sp();
put_f(-1.0 / 0.0); sp();
put_f(0.0 / 0.0); sp();
- put_n(1.5 < 2.0); sp();
- put_n(2.0 <= 2.0); sp();
- put_n(2.0 == 2); sp();
- put_n(1.5 == 1); sp();
- put_n(3.0 > 3.5); sp();
- put_n(f2i(3.9)); sp();
- put_n(f2i(-3.9)); sp();
+ rt.put_n(1.5 < 2.0); sp();
+ rt.put_n(2.0 <= 2.0); sp();
+ rt.put_n(2.0 == 2); sp();
+ rt.put_n(1.5 == 1); sp();
+ rt.put_n(3.0 > 3.5); sp();
+ rt.put_n(f2i(3.9)); sp();
+ rt.put_n(f2i(-3.9)); sp();
put_f(i2f(3)); sp();
put_f(i2f(-2)); sp();
- put_n(10 / 4);
- put_c(10);
+ rt.put_n(10 / 4);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/fo3.zc b/tests/programs/fo3.zc
index 593e88a..b2ac93e 100644
--- a/tests/programs/fo3.zc
+++ b/tests/programs/fo3.zc
@@ -1,7 +1,10 @@
+namespace;
+include rt;
+
// o3 lifts float ops: the plain kernel and the o3 kernel agree, a constant
// float expression folds, x - x stays a NaN, and -0 is false inside o3.
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
float poly(int n) {
float s = 0.0;
float x = 1.25;
@@ -36,15 +39,15 @@ o3 int zfalse() {
o3 float addtwo(float a) { return a + 2; }
o3 int below(float a, float b) { return a < b; }
fn main() {
- put_n((int)poly(2000)); sp();
- put_n((int)poly3(2000)); sp();
+ rt.put_n((int)poly(2000)); sp();
+ rt.put_n((int)poly3(2000)); sp();
put_f(folded()); sp();
put_f(subself(0.0 / 0.0)); sp();
- put_n(zfalse()); sp();
+ rt.put_n(zfalse()); sp();
put_f(addtwo(1.25)); sp();
- put_n(below(1.0, 2.0)); sp();
- put_n(below(2.0, 2.0)); sp();
- put_n(below(0.0 / 0.0, 1.0));
- put_c(10);
+ rt.put_n(below(1.0, 2.0)); sp();
+ rt.put_n(below(2.0, 2.0)); sp();
+ rt.put_n(below(0.0 / 0.0, 1.0));
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/ftext.zc b/tests/programs/ftext.zc
index b1c0acf..bb52d1a 100644
--- a/tests/programs/ftext.zc
+++ b/tests/programs/ftext.zc
@@ -1,9 +1,12 @@
-fn sp() { put_c(32); return 0; }
+namespace;
+include rt;
+
+fn sp() { rt.put_c(32); return 0; }
fn pm(x, prec, mode) { asm { x @ prec @ mode @ #1236 } return 0; }
fn parsed(s) { return asm { s @ #1222 }; }
fn ok(a, b) {
let w = asm { a @ b @ ^ };
- if (w) put_n(0); else put_n(1);
+ if (w) rt.put_n(0); else rt.put_n(1);
return 0;
}
@@ -28,10 +31,10 @@ fn main() {
ok(parsed("-inf"), -1.0 / 0.0);
ok(parsed("-0"), z);
ok(parsed("9007199254740993"), lo);
- if (hi == lo) put_n(0); else put_n(1);
- if (parsed("5e-324")) put_n(1); else put_n(0);
- if (parsed("1e-400")) put_n(0); else put_n(1);
- if (parsed("-nan") == parsed("nan")) put_n(0); else put_n(1);
- put_c(10);
+ if (hi == lo) rt.put_n(0); else rt.put_n(1);
+ if (parsed("5e-324")) rt.put_n(1); else rt.put_n(0);
+ if (parsed("1e-400")) rt.put_n(0); else rt.put_n(1);
+ if (parsed("-nan") == parsed("nan")) rt.put_n(0); else rt.put_n(1);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/ftruth.zc b/tests/programs/ftruth.zc
index 9d24a42..e99f9ed 100644
--- a/tests/programs/ftruth.zc
+++ b/tests/programs/ftruth.zc
@@ -1,22 +1,25 @@
+namespace;
+include rt;
+
fn main() {
let z = 0.0 * -1.0;
let p = 0.0;
let n = 1.5;
- if (z) put_n(1); else put_n(0);
- if (p) put_n(1); else put_n(0);
- if (n) put_n(1); else put_n(0);
- if (!z) put_n(1); else put_n(0);
- if (!p) put_n(1); else put_n(0);
- if (!n) put_n(1); else put_n(0);
- if (z && n) put_n(1); else put_n(0);
- if (n && z) put_n(1); else put_n(0);
- if (z || n) put_n(1); else put_n(0);
- if (n || z) put_n(1); else put_n(0);
- if (p || z) put_n(1); else put_n(0);
- for (; z;) put_n(9);
- put_n(z == p);
- put_n(z < p);
- put_n(7);
- put_c(10);
+ if (z) rt.put_n(1); else rt.put_n(0);
+ if (p) rt.put_n(1); else rt.put_n(0);
+ if (n) rt.put_n(1); else rt.put_n(0);
+ if (!z) rt.put_n(1); else rt.put_n(0);
+ if (!p) rt.put_n(1); else rt.put_n(0);
+ if (!n) rt.put_n(1); else rt.put_n(0);
+ if (z && n) rt.put_n(1); else rt.put_n(0);
+ if (n && z) rt.put_n(1); else rt.put_n(0);
+ if (z || n) rt.put_n(1); else rt.put_n(0);
+ if (n || z) rt.put_n(1); else rt.put_n(0);
+ if (p || z) rt.put_n(1); else rt.put_n(0);
+ for (; z;) rt.put_n(9);
+ rt.put_n(z == p);
+ rt.put_n(z < p);
+ rt.put_n(7);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/ftype.zc b/tests/programs/ftype.zc
index 6db7f5a..cbc2444 100644
--- a/tests/programs/ftype.zc
+++ b/tests/programs/ftype.zc
@@ -1,5 +1,8 @@
+namespace;
+include rt;
+
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
struct cell { int tag; float field; }
@@ -31,17 +34,17 @@ fn main() {
put_f(c.field); sp();
buf[0] = 6.5;
put_f(buf[0]); sp();
- put_n(&(1.field)); sp();
+ rt.put_n(&(1.field)); sp();
w = (&c) as word;
- put_n(w.tag); sp();
+ rt.put_n(w.tag); sp();
put_f(w.field); sp();
w.field = 8.5;
put_f(c.field); sp();
- put_n(g > 3); sp();
+ rt.put_n(g > 3); sp();
if (z) n = 1;
do { if (z) n = n + 2; } while (z);
if (!z && g) n = n + 4;
- put_n(n);
- put_c(10);
+ rt.put_n(n);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/gc.zc b/tests/programs/gc.zc
index 81412a3..7d2441b 100644
--- a/tests/programs/gc.zc
+++ b/tests/programs/gc.zc
@@ -1,18 +1,21 @@
+namespace;
+include rt;
+
let keep;
unchecked fn churn(n) {
let i = 0, p;
- while (i < n) { p = new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; }
+ while (i < n) { p = rt.new(10); p[0] = i; if (i % 100 == 0) keep = p; i++; }
return 0;
}
fn main() {
- let base = live_objects(), f;
+ let base = rt.live_objects(), f;
churn(1000);
- put_n(live_objects() - base); put_c(' ');
- f = gc();
- put_n(f >= 990); put_c(' '); // conservative: a stale word or two may keep one alive
- put_n(keep[0]); put_c(' '); // the one a global still points at survives
+ rt.put_n(rt.live_objects() - base); rt.put_c(' ');
+ f = rt.gc();
+ rt.put_n(f >= 990); rt.put_c(' '); // conservative: a stale word or two may keep one alive
+ rt.put_n(keep[0]); rt.put_c(' '); // the one a global still points at survives
churn(200000); // 3.2m words through a 393k word heap: needs the automatic collector
- put_n(gc_runs > 1); put_c(' ');
- put_n(keep[0]); put_c(10);
+ rt.put_n(rt.gc_runs > 1); rt.put_c(' ');
+ rt.put_n(keep[0]); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/generics.zc b/tests/programs/generics.zc
index e841b19..3623031 100644
--- a/tests/programs/generics.zc
+++ b/tests/programs/generics.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt, run;
+
// generics are compiled per set of type arguments: T can be any size, new(T)
// stamps the real type, and a struct can take several parameters
struct pt { int x, y; };
@@ -7,10 +10,11 @@ struct box<T> { int n; T* items; };
K rkey<K, V>(record<K, V>* r) { return r.key; }
V* rval<K, V>(record<K, V>* r) { return &r.val; }
int tsize<T>() { return sizeof(T); }
-T*.u make<T>(int n) { T* p = new(T, n) as T*; return u*p; }
+T*.u make<T>(int n) { T* p = rt.new(T, n) as T*; return u*p; }
record<K, V>*.u mkrec<K, V>(K k) {
- record<K, V>* r = new(record<K, V>);
- r.key = k;
+ record<K, V>* r = rt.new(record<K, V>);
+ // copied references are shared so the record does not consume its input.
+ r.key = run.share_value(k);
return u*r;
}
T pick<T>(T* a, int i) { return a[i]; }
@@ -19,7 +23,7 @@ int sumn<T>(T* a, int n) {
for (int i = 0; i < n; i++) s += a[i];
return s;
}
-fn nameof<T>() { return tname(typeof(T)); }
+fn nameof<T>() { return run.tname(typeof(T)); }
o3 int osum<T>(T* a, int n) {
int s = 0;
for (int i = 0; i < n; i++) s += a[i].x + a[i].y;
@@ -32,23 +36,23 @@ int depth<T>(int n) {
int main() {
record<int, pt>* a = mkrec<int, pt>(9);
a.val.x = 5; a.val.y = 6;
- put_n(rkey<int, pt>(a)); put_c(' ');
- put_n(rval<int, pt>(a).y); put_c(' ');
- put_n(sizeof(record<int, pt>)); put_c(' ');
- put_n(tsize<int>()); put_c(' ');
- put_n(tsize<pt>()); put_c(' ');
- put_n(tsize<record<int, pt>>()); put_c(' ');
- put_n(depth<pt>(5)); put_c(10);
+ rt.put_n(rkey<int, pt>(a)); rt.put_c(' ');
+ rt.put_n(rval<int, pt>(a).y); rt.put_c(' ');
+ rt.put_n(sizeof(record<int, pt>)); rt.put_c(' ');
+ rt.put_n(tsize<int>()); rt.put_c(' ');
+ rt.put_n(tsize<pt>()); rt.put_c(' ');
+ rt.put_n(tsize<record<int, pt>>()); rt.put_c(' ');
+ rt.put_n(depth<pt>(5)); rt.put_c(10);
pt* ps = make<pt>(3);
ps[2].x = 40; ps[2].y = 2;
- put_n(pick<pt>(ps, 2).x + ps[2].y); put_c(' ');
- put_s(nameof<pt>()); put_c(' '); put_s(nameof<int>()); put_c(' ');
- put_n(osum<pt>(ps, 3)); put_c(' ');
+ rt.put_n(pick<pt>(ps, 2).x + ps[2].y); rt.put_c(' ');
+ rt.put_s(nameof<pt>()); rt.put_c(' '); rt.put_s(nameof<int>()); rt.put_c(' ');
+ rt.put_n(osum<pt>(ps, 3)); rt.put_c(' ');
int* is = make<int>(4);
is[0] = 1; is[1] = 2; is[2] = 3; is[3] = 4;
- put_n(sumn<int>(is, 4)); put_c(' ');
+ rt.put_n(sumn<int>(is, 4)); rt.put_c(' ');
record<pt*, int>* b = mkrec<pt*, int>(ps);
- put_n(b.key == ps); put_c(10);
- free(d*a); free(d*b); free(d*ps); free(d*is);
+ rt.put_n(b.key == ps); rt.put_c(10);
+ rt.free(d*a); rt.free(d*b); rt.free(d*ps); rt.free(d*is);
return 0;
}
diff --git a/tests/programs/genmeth.zc b/tests/programs/genmeth.zc
index 305c55c..73f0ced 100644
--- a/tests/programs/genmeth.zc
+++ b/tests/programs/genmeth.zc
@@ -1,11 +1,14 @@
+namespace;
+include rt;
+
// methods on generic structs: each set of type arguments gets its own copy
struct pt { int x, y; };
struct table<K, V> {
int n; K* keys; V* vals;
fn init(int cap) {
this.n = 0;
- this.keys = new(K, cap) as K*;
- this.vals = new(V, cap) as V*;
+ this.keys = rt.new(K, cap) as K*;
+ this.vals = rt.new(V, cap) as V*;
return 0;
}
fn put(K k, V v) {
@@ -25,12 +28,12 @@ int main() {
table<int, int> a;
a.init(8);
a.put(1, 10); a.put(2, 20); a.put(3, 30);
- put_n(a.n); put_c(' '); put_n(a.total()); put_c(' '); put_n(a.width()); put_c(' ');
- table<pt, int>* b = new(table<pt, int>);
+ rt.put_n(a.n); rt.put_c(' '); rt.put_n(a.total()); rt.put_c(' '); rt.put_n(a.width()); rt.put_c(' ');
+ table<pt, int>* b = rt.new(table<pt, int>);
b.init(4);
- put_n(b.width()); put_c(' ');
- table<int, pt>* c = new(table<int, pt>);
+ rt.put_n(b.width()); rt.put_c(' ');
+ table<int, pt>* c = rt.new(table<int, pt>);
c.init(4);
- put_n(c.width()); put_c(10);
+ rt.put_n(c.width()); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/global_transfer.zc b/tests/programs/global_transfer.zc
new file mode 100644
index 0000000..b36ad73
--- /dev/null
+++ b/tests/programs/global_transfer.zc
@@ -0,0 +1,16 @@
+namespace;
+include rt;
+
+// an m or u owner stored into a global is handed over by an automatic u transfer
+let g;
+let h;
+int*.u make() { int* b = rt.new(int); *b = 9; return u*b; }
+fn main() {
+ let x = rt.new(1);
+ x[0] = 5;
+ g = x;
+ let y = make();
+ h = y;
+ rt.put_n(g[0]); rt.put_c(32); rt.put_n(h[0]); rt.put_c(10);
+ return 0;
+}
diff --git a/tests/programs/growheap.zc b/tests/programs/growheap.zc
index 07e10a6..ebb3f8b 100644
--- a/tests/programs/growheap.zc
+++ b/tests/programs/growheap.zc
@@ -1,10 +1,13 @@
+namespace;
+include rt;
+
// the heap grows past its initial size: eight live blocks of 300000 words
// don't fit in the 393216-word start, so the allocator takes more memory from
// the host, and a block bigger than the start fits once they are freed
let keep[8];
unchecked fn fill(n) {
let i = 0, a;
- while (i < n) { a = new(300000); a[0] = i + 1; a[299999] = (i + 1) * 3; keep[i] = a; i++; }
+ while (i < n) { a = rt.new(300000); a[0] = i + 1; a[299999] = (i + 1) * 3; keep[i] = a; i++; }
return 0;
}
unchecked fn total(n) {
@@ -14,19 +17,19 @@ unchecked fn total(n) {
}
unchecked fn drop(n) {
let i = 0;
- while (i < n) { free(keep[i]); keep[i] = 0; i++; }
+ while (i < n) { rt.free(keep[i]); keep[i] = 0; i++; }
return 0;
}
fn main() {
- let a, start = heap_size();
+ let a, start = rt.heap_size();
fill(8);
- put_n(total(8)); put_c(' ');
- put_n(heap_size() > start); put_c(' ');
+ rt.put_n(total(8)); rt.put_c(' ');
+ rt.put_n(rt.heap_size() > start); rt.put_c(' ');
drop(8);
- scrub(); gc();
- a = new(3000000);
+ rt.scrub(); rt.gc();
+ a = rt.new(3000000);
a[2999999] = 7;
- put_n(a[2999999]); put_c(' ');
- put_n(heap_size() >= 3000000); put_c(10);
+ rt.put_n(a[2999999]); rt.put_c(' ');
+ rt.put_n(rt.heap_size() >= 3000000); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/growone.zc b/tests/programs/growone.zc
index 12980ff..174f35a 100644
--- a/tests/programs/growone.zc
+++ b/tests/programs/growone.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// one block bigger than the initial heap: the machine grows, and the block is usable
fn main() {
- let a = new(400000);
+ let a = rt.new(400000);
a[0] = 5;
a[399999] = 7;
- put_n(a[0] + a[399999]); put_c(' ');
- put_n(heap_size() >= 400000); put_c(10);
+ rt.put_n(a[0] + a[399999]); rt.put_c(' ');
+ rt.put_n(rt.heap_size() >= 400000); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/infer_return.zc b/tests/programs/infer_return.zc
index a9f12bd..cd82f18 100644
--- a/tests/programs/infer_return.zc
+++ b/tests/programs/infer_return.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// a owned return with no .u on the signature: the return type is inferred from the body
-fn mk(v) { int* p = new(1); p[0] = v; return p; }
-fn main() { int* q = mk(3); put_n(q[0]); put_c(10); return 0; }
+fn mk(v) { int* p = rt.new(1); p[0] = v; return p; }
+fn main() { int* q = mk(3); rt.put_n(q[0]); rt.put_c(10); return 0; }
diff --git a/tests/programs/interior.zc b/tests/programs/interior.zc
index bccf377..d87a14c 100644
--- a/tests/programs/interior.zc
+++ b/tests/programs/interior.zc
@@ -1,17 +1,20 @@
+namespace;
+include rt;
+
unchecked fn main() {
- let p = new(4), r, i = 0, t, bad = 0;
- mem_set(4);
+ let p = rt.new(4), r, i = 0, t, bad = 0;
+ rt.mem_set(4);
p[0] = 111; p[1] = 222; p[2] = 333; p[3] = 444;
r = p + 1;
- free(p);
- gc();
+ rt.free(p);
+ rt.gc();
while (i < 8) {
- t = new(4);
+ t = rt.new(4);
if (t == r - 1) bad = 1;
i++;
}
if (r[0] != 222) bad = bad + 2;
- put_n(bad);
- put_c(10);
+ rt.put_n(bad);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/joins.zc b/tests/programs/joins.zc
index 98275ad..ec3f862 100644
--- a/tests/programs/joins.zc
+++ b/tests/programs/joins.zc
@@ -1,31 +1,34 @@
+namespace;
+include rt;
+
// joins: something given away on one path is dead afterwards, and the paths
// that still own it free it on the way in. nothing here leaks.
fn take(.d p) { return p[0]; }
fn later(.d p); // not needed any more, but still allowed
-int*.u mk(int v) { int* p = new(int); *p = v; return u*p; }
+int*.u mk(int v) { int* p = rt.new(int); *p = v; return u*p; }
fn count(int n) { let s = 0; switch (n % 4) { case 0: s = 10; case 1, 2: s = 20; break; default: s = 30; } return s; }
fn main() {
- let base = live_objects(), i = 0, hits = 0, k;
+ let base = rt.live_objects(), i = 0, hits = 0, k;
while (i < 50) {
let x = mk(i);
if (i % 3 == 0) take(d*x); // else: freed here by the fixup
i++;
}
- put_n(live_objects() - base); put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(' ');
// give away and break: fine now; the normal exit frees it
i = 0;
let y = mk(7);
while (i < 10) { if (i == 4) { take(d*y); break; } i++; }
- put_n(live_objects() - base); put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(' ');
let z = mk(5);
while (1) { if (z[0] == 5) { hits = take(d*z); break; } }
- put_n(hits); put_c(' ');
- put_n(count(0) + count(1) + count(2) + count(3)); put_c(' ');
+ rt.put_n(hits); rt.put_c(' ');
+ rt.put_n(count(0) + count(1) + count(2) + count(3)); rt.put_c(' ');
k = i > 3 ? i * 2 : 0 - 1;
- put_n(k); put_c(' ');
- put_n(forward(new(int))); put_c(' '); // tagged and defined below: the prescan knows .d
- int** pp; int* q = new(int); *q = 9; pp = &q; put_n(**pp); free(d*q); put_c(' ');
- put_n(live_objects() - base); put_c(10);
+ rt.put_n(k); rt.put_c(' ');
+ rt.put_n(forward(rt.new(int))); rt.put_c(' '); // tagged and defined below: the prescan knows .d
+ int** pp; int* q = rt.new(int); *q = 9; pp = &q; rt.put_n(**pp); rt.free(d*q); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(10);
return 0;
}
fn forward(int*.d p) { return 3 + *p; }
diff --git a/tests/programs/manyerrors.zc b/tests/programs/manyerrors.zc
index 3ba2c5a..d13ade2 100644
--- a/tests/programs/manyerrors.zc
+++ b/tests/programs/manyerrors.zc
@@ -1,6 +1,9 @@
+namespace;
+include rt;
+
// several errors in one run: a syntax error, an analyzer error, a type error
typecheck on;
fn f() { let a = ; return 0; }
-fn g() { let x = new(3); return 0; }
+fn g() { let x = rt.new(3); return 0; }
int h() { char* s = 5; return 1; }
fn main() { return 0 }
diff --git a/tests/programs/memleak.zc b/tests/programs/memleak.zc
index a61c331..ad4c8c0 100644
--- a/tests/programs/memleak.zc
+++ b/tests/programs/memleak.zc
@@ -1,11 +1,14 @@
+namespace;
+include rt;
+
memdebug on;
int* g;
fn main()
{
- int* p = new(int);
+ int* p = rt.new(int);
*p = 7;
g = d*p;
- put_n(memreport());
- put_c(10);
+ rt.put_n(rt.memreport());
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/memory_bounds.zc b/tests/programs/memory_bounds.zc
index 0863d03..a929de3 100644
--- a/tests/programs/memory_bounds.zc
+++ b/tests/programs/memory_bounds.zc
@@ -1,13 +1,16 @@
+namespace;
+include rt;
+
// raw word loads, stores, and stack picks outside memory follow portable semantics.
unchecked int raw_pick(int depth) { return asm { depth @ #6 }; }
unchecked fn main() {
int p = -1;
- put_n(*p); put_c(32); *p = 7;
+ rt.put_n(*p); rt.put_c(32); *p = 7;
p = 0x7FFFFFFF;
- put_n(*p); put_c(32); *p = 9;
+ rt.put_n(*p); rt.put_c(32); *p = 9;
p = 0x100000000;
- put_n(*p); put_c(32);
- put_n(raw_pick(0x100000000)); put_c(32);
- put_n(raw_pick(0 - 0x100000000)); put_c(10);
+ rt.put_n(*p); rt.put_c(32);
+ rt.put_n(raw_pick(0x100000000)); rt.put_c(32);
+ rt.put_n(raw_pick(0 - 0x100000000)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/meta.zc b/tests/programs/meta.zc
index 6afdf36..57c5d5a 100644
--- a/tests/programs/meta.zc
+++ b/tests/programs/meta.zc
@@ -1,43 +1,46 @@
+namespace;
+include rt, run;
+
fn ipow(a, b) { let r = 1; while (b > 0) { r *= a; b--; } return r; }
// a parse word that adds an operator to the compiler's tables
-immediate fn pow_op() { next(); add_binop("**", 11, "ipow c"); return 0; }
+immediate fn pow_op() { run.next(); run.add_binop("**", 11, "ipow c"); return 0; }
pow_op
// unless (cond) stmt: a parse word that emits code itself
immediate fn unless() {
let a;
- next();
- expect(intern("(")); rval(); plainuse(expr()); rval(); expect(intern(")"));
- emitseq(useq[0], ulen[0]); // not
- a = hole(); op(O_JZ); // skip the body when the condition was true
- substmt();
- setlit(a, here);
+ run.next();
+ run.expect(run.intern("(")); run.rval(); run.plainuse(run.expr()); run.rval(); run.expect(run.intern(")"));
+ run.emitseq(run.useq[0], run.ulen[0]); // not
+ a = run.hole(); run.op(run.O_JZ); // skip the body when the condition was true
+ run.substmt();
+ run.setlit(a, run.here);
return 0;
}
// repeat N { body }: a macro, built from token lists
immediate fn repeat() {
let n, body, i = 0;
- next(); n = tv; next();
- body = grab();
- while (i < n) { feed(qdup(body)); i++; }
- free(d*body);
+ run.next(); n = run.tv; run.next();
+ body = run.grab();
+ while (i < n) { run.feed(run.qdup(body)); i++; }
+ rt.free(d*body);
return 0;
}
fn main() {
- put_n(2 ** 10); put_c(' '); put_n(3 + 2 ** 3 * 2); put_c(10);
- unless (1 > 2) put_s("unless ok\n");
- unless (2 > 1) put_s("wrong\n");
- repeat 3 { put_c('r'); }
- put_c(10);
- let q = quote { put_n(40 + 2); put_c(10); return 7; };
- put_n(q[0]); put_c(' ');
- put_n(eval(q)); put_c(10);
- let f = compile(q);
- put_n(f()); put_c(10);
- free(d*q);
+ rt.put_n(2 ** 10); rt.put_c(' '); rt.put_n(3 + 2 ** 3 * 2); rt.put_c(10);
+ unless (1 > 2) rt.put_s("unless ok\n");
+ unless (2 > 1) rt.put_s("wrong\n");
+ repeat 3 { rt.put_c('r'); }
+ rt.put_c(10);
+ let q = quote { rt.put_n(40 + 2); rt.put_c(10); return 7; };
+ rt.put_n(q[0]); rt.put_c(' ');
+ rt.put_n(run.eval(q)); rt.put_c(10);
+ let f = run.compile(q);
+ rt.put_n(f()); rt.put_c(10);
+ rt.free(d*q);
let defs = quote { fn sq(x) { return x * x; } };
- load(defs);
- free(d*defs);
- put_n(evals("return sq(12);")); put_c(10);
+ run.load(defs);
+ rt.free(d*defs);
+ rt.put_n(run.evals("return sq(12);")); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/methodown.zc b/tests/programs/methodown.zc
index 98ba146..2d90f4b 100644
--- a/tests/programs/methodown.zc
+++ b/tests/programs/methodown.zc
@@ -1,15 +1,18 @@
+namespace;
+include rt;
+
// a struct method can return an owned object: its header declares the .u return
struct Node { int v; }
struct Maker {
- static Node*.u make(int n) { Node* p = new(Node); p.v = n; return u*p; }
+ static Node*.u make(int n) { Node* p = rt.new(Node); p.v = n; return u*p; }
}
-Node*.u mk(int n) { Node* p = new(Node); p.v = n; return u*p; }
+Node*.u mk(int n) { Node* p = rt.new(Node); p.v = n; return u*p; }
int main() {
Node*.u a = Maker.make(7);
- put_n(a.v); put_c(32);
- free(d*a);
+ rt.put_n(a.v); rt.put_c(32);
+ rt.free(d*a);
Node*.u b = mk(9);
- put_n(b.v); put_c(10);
- free(d*b);
+ rt.put_n(b.v); rt.put_c(10);
+ rt.free(d*b);
return 0;
}
diff --git a/tests/programs/misc.zc b/tests/programs/misc.zc
index 530322a..2b0f0c2 100644
--- a/tests/programs/misc.zc
+++ b/tests/programs/misc.zc
@@ -1,15 +1,18 @@
+namespace;
+include rt, run;
+
// ct { ... } runs a block while compiling and leaves its result as a constant
immediate fn ct() {
let q, v;
- next();
- q = grab();
- v = eval(q);
- free(d*q);
- lit(v);
+ run.next();
+ q = run.grab();
+ v = run.eval(q);
+ rt.free(d*q);
+ run.lit(v);
return 0;
}
// teach the asm syntax that p means out, like the old repl demo
-immediate fn teach() { next(); mnem[12] = 'p'; return 0; }
+immediate fn teach() { run.next(); run.mnem[12] = 'p'; return 0; }
teach
fn countdown() {
@@ -17,11 +20,11 @@ fn countdown() {
return 0;
}
fn main() {
- put_n(ct { let i = 0, s = 0; while (i < 10) { s += i; i++; } return s; }); put_c(10);
+ rt.put_n(ct { let i = 0, s = 0; while (i < 10) { s += i; i++; } return s; }); rt.put_c(10);
countdown();
- put_s(lazy()); put_c(10);
+ rt.put_s(lazy()); rt.put_c(10);
return 0;
}
// the analyzer is off from here on
unchecked;
-fn lazy() { let p = new(3); p[0] = 'o'; p[1] = 'k'; return p; }
+fn lazy() { let p = rt.new(3); p[0] = 'o'; p[1] = 'k'; return p; }
diff --git a/tests/programs/names.zc b/tests/programs/names.zc
index 6ccb2eb..e5b9d4b 100644
--- a/tests/programs/names.zc
+++ b/tests/programs/names.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
fn f(d) { let u = 3, m = 4; if (d > 0) return u + m + d; return 0; }
fn dmul(d) { return d * 4; }
fn main() {
let u = 1;
- put_n(f(5)); put_c(' ');
- put_n(u); put_c(' ');
- put_n(dmul(2)); put_c(10);
+ rt.put_n(f(5)); rt.put_c(' ');
+ rt.put_n(u); rt.put_c(' ');
+ rt.put_n(dmul(2)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3.zc b/tests/programs/o3.zc
index c875d09..d7026db 100644
--- a/tests/programs/o3.zc
+++ b/tests/programs/o3.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// o3 regions: every kind of control flow, against the same code without o3
struct pt { int x; int y; };
int g = 3;
@@ -31,20 +34,20 @@ o3 int mix(int n) {
return acc;
}
o3 int dyn(int n) {
- []int a = new([]int, n);
- fixed []int f = new(fixed []int, n);
+ int[?] a = rt.new(int[?], n);
+ fixed int[?] f = rt.new(fixed int[?], n);
int s = 0;
for (int i = 0; i < len(a); i++) { a[i] = i * i; f[i] = n - i; }
for (int i = 0; i < n; i++) s = s + a[i] * f[i];
- free(d*a); free(d*f);
+ rt.free(d*a); rt.free(d*f);
return s;
}
o3 int pts(int n) {
- pt* p = new(pt);
+ pt* p = rt.new(pt);
int s = 0;
p->x = 1; p->y = 2;
for (int i = 0; i < n; i++) { p->x = p->x + p->y; p->y = p->x - p->y; s = s + p->x % 1000; }
- free(d*p);
+ rt.free(d*p);
return s;
}
o3 int divs(int x) {
@@ -59,17 +62,17 @@ fn main() {
o3 {
int i = 0, s = 0;
while (i < 100) { s = s + collatz(i + 1); i++; }
- put_n(s); put_c(' ');
- put_n(lone); put_c(' ');
+ rt.put_n(s); rt.put_c(' ');
+ rt.put_n(lone); rt.put_c(' ');
lone++;
}
- put_n(lone); put_c(' ');
- put_n(ack(2, 3)); put_c(' ');
- put_n(many(1, 2, 3)); put_c(' ');
- put_n(mix(100)); put_c(' ');
- put_n(dyn(50)); put_c(' ');
- put_n(pts(30)); put_c(' ');
- put_n(divs(1000)); put_c(' ');
- put_n(divs(-77)); put_c(10);
+ rt.put_n(lone); rt.put_c(' ');
+ rt.put_n(ack(2, 3)); rt.put_c(' ');
+ rt.put_n(many(1, 2, 3)); rt.put_c(' ');
+ rt.put_n(mix(100)); rt.put_c(' ');
+ rt.put_n(dyn(50)); rt.put_c(' ');
+ rt.put_n(pts(30)); rt.put_c(' ');
+ rt.put_n(divs(1000)); rt.put_c(' ');
+ rt.put_n(divs(-77)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3_bounds.zc b/tests/programs/o3_bounds.zc
index fb347c0..eaf92eb 100644
--- a/tests/programs/o3_bounds.zc
+++ b/tests/programs/o3_bounds.zc
@@ -1,2 +1,5 @@
-// an index outside a []T inside o3 code: caught by the inline check
-fn main() { []int a = new([]int, 5); o3 { int i = 7; a[i] = 1; } free(d*a); return 0; }
+namespace;
+include rt;
+
+// an index outside a T[?] inside o3 code: caught by the inline check
+fn main() { int[?] a = rt.new(int[?], 5); o3 { int i = 7; a[i] = 1; } rt.free(d*a); return 0; }
diff --git a/tests/programs/o3bytes.zc b/tests/programs/o3bytes.zc
index bada583..7c971ed 100644
--- a/tests/programs/o3bytes.zc
+++ b/tests/programs/o3bytes.zc
@@ -1,52 +1,55 @@
+namespace;
+include rt;
+
// byte ops called from o3 stay in the region. ld8/st8 and the 16- and 32-bit
// pair are opcodes there, on the interpreter, the arm64 jit and llvm.
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
fn litw(v) { return v + v + 1; }
-fn f() { put_c('A'); return 0; }
+fn f() { rt.put_c('A'); return 0; }
fn main() {
let buf[4], b, i, s, t, p, v, w;
i = 0;
while (i < 4) { buf[i] = 0; i++; }
- b = addr_b(buf);
+ b = rt.addr_b(buf);
i = 0;
s = 0;
o3 {
while (i < 20) {
t = b + i;
- st8(t, i);
- s = s + ld8(t);
+ rt.st8(t, i);
+ s = s + rt.ld8(t);
i++;
}
}
- put_n(s); sp();
- o3 { st16(b, 4660); w = ld16(b); }
- put_n(w); sp();
+ rt.put_n(s); sp();
+ o3 { rt.st16(b, 4660); w = rt.ld16(b); }
+ rt.put_n(w); sp();
t = b + 7;
- o3 { w = ld8(t); }
- put_n(w); sp();
- o3 { w = ld16(t); }
- put_n(w); sp();
+ o3 { w = rt.ld8(t); }
+ rt.put_n(w); sp();
+ o3 { w = rt.ld16(t); }
+ rt.put_n(w); sp();
t = b + 10;
v = 16909060;
- o3 { st32(t, v); w = ld32(t); }
- put_n(w); sp();
+ o3 { rt.st32(t, v); w = rt.ld32(t); }
+ rt.put_n(w); sp();
t = 0 - 1;
- o3 { st8(t, v); w = ld8(t); }
- put_n(w); sp();
- t = addr_b(MW) - 1;
- o3 { w = ld16(t); }
- put_n(w);
- put_c(10);
+ o3 { rt.st8(t, v); w = rt.ld8(t); }
+ rt.put_n(w); sp();
+ t = rt.addr_b(rt.MW) - 1;
+ o3 { w = rt.ld16(t); }
+ rt.put_n(w);
+ rt.put_c(10);
p = f;
f();
while (*p != litw('A')) p++;
- t = addr_b(p);
+ t = rt.addr_b(p);
v = litw('B') & 255;
- o3 { st8(t, v); }
+ o3 { rt.st8(t, v); }
f();
v = litw('C') & 255;
- o3 { st8(t, v); }
+ o3 { rt.st8(t, v); }
f();
- put_c(10);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3call.zc b/tests/programs/o3call.zc
index b2be717..d2292ad 100644
--- a/tests/programs/o3call.zc
+++ b/tests/programs/o3call.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt, run;
+
// new stamps the header, so an o3 caller and an ordinary caller both see a type.
// the call itself is not a boundary: no fatten, and the callee's prologue does not run.
struct node { int v; node* c; };
unchecked o3 node* leaf(int v) {
- node* n = new(node);
+ node* n = rt.new(node);
n.v = v; n.c = 0;
return n;
}
@@ -19,11 +22,11 @@ unchecked o3 int nest(int n) {
unchecked fn main() {
node* n = leaf(4);
int* p = n;
- put_n(p[-1] < 0); put_c(' ');
- put_n(inner() < 0); put_c(' ');
- put_n(n.v); put_c(' ');
- put_n(add(20, 3)); put_c(' ');
- put_n(nest(10)); put_c(' ');
- tprint(typeof_obj(n)); put_c(10);
+ rt.put_n(p[-1] < 0); rt.put_c(' ');
+ rt.put_n(inner() < 0); rt.put_c(' ');
+ rt.put_n(n.v); rt.put_c(' ');
+ rt.put_n(add(20, 3)); rt.put_c(' ');
+ rt.put_n(nest(10)); rt.put_c(' ');
+ run.tprint(rt.typeof_obj(n)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3copy.zc b/tests/programs/o3copy.zc
index 90b9ade..29ac278 100644
--- a/tests/programs/o3copy.zc
+++ b/tests/programs/o3copy.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// copies of a variable that a loop reads again: the global pass reads the variable itself
o3 int g(int n, int b) {
int s = 0, c = b, i = 0;
@@ -9,4 +12,4 @@ o3 int h(int n, int k) {
while (i < n) { t = t + a; if (t > 1000) t = t - 1000; a = k; i++; }
return t + a;
}
-fn main() { put_n(g(1000, 7)); put_c(32); put_n(h(1000, 5)); put_c(10); return 0; }
+fn main() { rt.put_n(g(1000, 7)); rt.put_c(32); rt.put_n(h(1000, 5)); rt.put_c(10); return 0; }
diff --git a/tests/programs/o3deep.zc b/tests/programs/o3deep.zc
index e715d9e..c07199f 100644
--- a/tests/programs/o3deep.zc
+++ b/tests/programs/o3deep.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// o3 recursion nests on the host stack as deep as the machine's own stacks allow
o3 int deep(int n) { if (n == 0) return 0; return 1 + deep(n - 1); }
-fn main() { put_n(deep(30000)); put_c(10); return 0; }
+fn main() { rt.put_n(deep(30000)); rt.put_c(10); return 0; }
diff --git a/tests/programs/o3deep_over.zc b/tests/programs/o3deep_over.zc
index 45816f6..226543e 100644
--- a/tests/programs/o3deep_over.zc
+++ b/tests/programs/o3deep_over.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// recursion can grow beyond the original operand and frame reservations
o3 int deep(int n) { if (n == 0) return 0; return 1 + deep(n - 1); }
-fn main() { put_n(deep(100000)); put_c(10); return 0; }
+fn main() { rt.put_n(deep(100000)); rt.put_c(10); return 0; }
diff --git a/tests/programs/o3direct.zc b/tests/programs/o3direct.zc
index 3c5d7ee..7998129 100644
--- a/tests/programs/o3direct.zc
+++ b/tests/programs/o3direct.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt, run;
+
// o3 calls between functions: arguments in registers, results on the stack, and the ways a call can leave the fast path
fn put_f(x) { asm { x @ #1220 } return 0; }
struct node { int v; node *next; };
@@ -10,24 +13,24 @@ o3 int four(int a, int b, int c, int d) { return three(a, b, c) * 10 + d; }
o3 int zero() { return 7; }
o3 int ack(int m, int n) { if (m == 0) return n + 1; if (n == 0) return ack(m - 1, 1); return ack(m - 1, ack(m, n - 1)); }
o3 float half(float x, int k) { if (k == 0) return x; return half(x / 2.0, k - 1); }
-o3 int noisy(int n) { if (n == 0) return 0; put_n(n); put_c(' '); return n + noisy(n - 1); }
+o3 int noisy(int n) { if (n == 0) return 0; rt.put_n(n); rt.put_c(' '); return n + noisy(n - 1); }
unchecked o3 int sumlist(node *p) { int s = 0; while (p) { s = s + p.v; p = p.next; } return s; }
unchecked o3 int build(int n) {
node *h = 0;
- for (int i = 1; i <= n; i++) { node *x = new(node); x.v = i; x.next = h; h = x; }
+ for (int i = 1; i <= n; i++) { node *x = rt.new(node); x.v = i; x.next = h; h = x; }
int s = sumlist(h);
- while (h) { node *t = h.next; free(h); h = t; }
+ while (h) { node *t = h.next; rt.free(h); h = t; }
return s;
}
unchecked o3 int mix(int a, int b) { return three(a, zero(), b) + fib(a) + four(1, 2, 3, b); }
unchecked fn main() {
- put_n(fib(20)); put_c(' ');
- put_n(ev(10)); put_c(' '); put_n(ev(7)); put_c(' ');
- put_n(three(1, 2, 3)); put_c(' '); put_n(four(4, 5, 6, 7)); put_c(' '); put_n(zero()); put_c(' ');
- put_n(ack(2, 3)); put_c(' ');
- put_f(half(64.0, 3)); put_c(' ');
- put_n(build(100)); put_c(' ');
- put_n(mix(6, 9)); put_c(10);
- put_n(noisy(4)); put_c(10);
+ rt.put_n(fib(20)); rt.put_c(' ');
+ rt.put_n(ev(10)); rt.put_c(' '); rt.put_n(ev(7)); rt.put_c(' ');
+ rt.put_n(three(1, 2, 3)); rt.put_c(' '); rt.put_n(four(4, 5, 6, 7)); rt.put_c(' '); rt.put_n(zero()); rt.put_c(' ');
+ rt.put_n(ack(2, 3)); rt.put_c(' ');
+ put_f(half(64.0, 3)); rt.put_c(' ');
+ rt.put_n(build(100)); rt.put_c(' ');
+ rt.put_n(mix(6, 9)); rt.put_c(10);
+ rt.put_n(noisy(4)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3fat.zc b/tests/programs/o3fat.zc
index 937b0f3..487f279 100644
--- a/tests/programs/o3fat.zc
+++ b/tests/programs/o3fat.zc
@@ -1,20 +1,23 @@
+namespace;
+include rt, run;
+
// o3 objects reaching normal code get their types: through a return (all the way down the list), an assignment, a store into a field
struct node { int v; node* next; };
-struct box { [3]node* slots; int n; };
+struct box { node*[3] slots; int n; };
unchecked o3 node* build(int n) {
node* head = 0;
- for (int i = 0; i < n; i++) { node* k = new(node); k.v = i; k.next = head; head = k; }
+ for (int i = 0; i < n; i++) { node* k = rt.new(node); k.v = i; k.next = head; head = k; }
return head;
}
unchecked fn main() {
node* l = build(5);
- tprint(typeof_obj(l)); put_c(' '); tprint(typeof_obj(l.next.next.next)); put_c(' ');
- put_n(l.next.v); put_c(' ');
+ run.tprint(rt.typeof_obj(l)); rt.put_c(' '); run.tprint(rt.typeof_obj(l.next.next.next)); rt.put_c(' ');
+ rt.put_n(l.next.v); rt.put_c(' ');
box* b = 0;
- o3 { b = new(box); b.slots[1] = new(node); b.n = 2; }
- tprint(typeof_obj(b)); put_c(' '); tprint(typeof_obj(b.slots[1])); put_c(' ');
+ o3 { b = rt.new(box); b.slots[1] = rt.new(node); b.n = 2; }
+ run.tprint(rt.typeof_obj(b)); rt.put_c(' '); run.tprint(rt.typeof_obj(b.slots[1])); rt.put_c(' ');
int* raw = 0;
- o3 { raw = new(int, 6); }
- tprint(typeof_obj(raw)); put_c(10);
+ o3 { raw = rt.new(int, 6); }
+ run.tprint(rt.typeof_obj(raw)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3licm.zc b/tests/programs/o3licm.zc
index 61e6a46..43abfb9 100644
--- a/tests/programs/o3licm.zc
+++ b/tests/programs/o3licm.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// loop invariants are built once in front of the loop, and a value two blocks both build is shared.
// every result below has to match the plain run (ZYNOSHARE=1 turns the pass off).
unchecked o3 int nest(int n, int k) {
@@ -34,13 +37,13 @@ unchecked o3 int twice(int x, int y) {
return r + (x * y + 3) * 7;
}
unchecked fn main() {
- int* a = new(int, 4);
+ int* a = rt.new(int, 4);
a[0] = 5; a[1] = 6;
- put_n(nest(30, 3)); put_c(' ');
- put_n(loads(a, 100)); put_c(' ');
- put_n(stores(a, 10)); put_c(' ');
- put_n(branchy(3, 4, 21)); put_c(' ');
- put_n(twice(5, 2)); put_c(' ');
- put_n(twice(-5, 2)); put_c(10);
+ rt.put_n(nest(30, 3)); rt.put_c(' ');
+ rt.put_n(loads(a, 100)); rt.put_c(' ');
+ rt.put_n(stores(a, 10)); rt.put_c(' ');
+ rt.put_n(branchy(3, 4, 21)); rt.put_c(' ');
+ rt.put_n(twice(5, 2)); rt.put_c(' ');
+ rt.put_n(twice(-5, 2)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/o3push.zc b/tests/programs/o3push.zc
index e5f0090..acb9fab 100644
--- a/tests/programs/o3push.zc
+++ b/tests/programs/o3push.zc
@@ -1,37 +1,40 @@
+namespace;
+include rt;
+
// push in o3 code: the quick path when there is room, dpush when there is not
-o3 int fill([]int a, int n) {
+o3 int fill(int[?] a, int n) {
for (int i = 0; i < n; i++) push(a, i * 3);
return len(a);
}
-o3 int sum([]int a) {
+o3 int sum(int[?] a) {
int s = 0;
for (int i = 0; i < len(a); i++) s += a[i];
return s;
}
-o3 float fsum([]float a) {
+o3 float fsum(float[?] a) {
float s = 0.0;
for (int i = 0; i < len(a); i++) s += a[i];
return s;
}
-o3 int ffill([]float a, int n) {
+o3 int ffill(float[?] a, int n) {
for (int i = 0; i < n; i++) push(a, 0.5 * i);
return len(a);
}
int main() {
- []int a = new([]int, 0);
- put_n(fill(a, 1000)); put_c(' ');
- put_n(sum(a)); put_c(' ');
- put_n(a[999]); put_c(' ');
- put_n(fill(a, 5)); put_c(' ');
- put_n(cap(a) >= 1005); put_c(' ');
- []float f = new([]float, 0);
+ int[?] a = rt.new(int[?], 0);
+ rt.put_n(fill(a, 1000)); rt.put_c(' ');
+ rt.put_n(sum(a)); rt.put_c(' ');
+ rt.put_n(a[999]); rt.put_c(' ');
+ rt.put_n(fill(a, 5)); rt.put_c(' ');
+ rt.put_n(cap(a) >= 1005); rt.put_c(' ');
+ float[?] f = rt.new(float[?], 0);
ffill(f, 10);
- put_n(len(f)); put_c(' '); put_n(fsum(f) == 22.5); put_c(' ');
- put_n(drain(a)); put_c(' '); put_n(len(a)); put_c(10);
- free(d*a); free(d*f);
+ rt.put_n(len(f)); rt.put_c(' '); rt.put_n(fsum(f) == 22.5); rt.put_c(' ');
+ rt.put_n(drain(a)); rt.put_c(' '); rt.put_n(len(a)); rt.put_c(10);
+ rt.free(d*a); rt.free(d*f);
return 0;
}
-o3 int drain([]int a) {
+o3 int drain(int[?] a) {
int s = 0;
while (len(a) > 0) s += pop(a);
return s;
diff --git a/tests/programs/o3scopes.zc b/tests/programs/o3scopes.zc
index 4dbf68c..a23a622 100644
--- a/tests/programs/o3scopes.zc
+++ b/tests/programs/o3scopes.zc
@@ -1,5 +1,8 @@
+namespace;
+include rt;
+
// registers reused by scopes that never overlap, and a fixed array read through its cached items and length
-o3 int scopes(fixed []int f) {
+o3 int scopes(fixed int[?] f) {
int total = 0;
for (int a = 0; a < 3; a++) { int x = a * 2; total += x; }
for (int b = 0; b < 3; b++) { int y = b * 3; total += y; }
@@ -9,9 +12,9 @@ o3 int scopes(fixed []int f) {
return total;
}
fn main() {
- fixed []int f = new(fixed []int, 4);
+ fixed int[?] f = rt.new(fixed int[?], 4);
for (int i = 0; i < 4; i++) f[i] = 10 * i;
- put_n(scopes(f)); put_c(10);
- free(d*f);
+ rt.put_n(scopes(f)); rt.put_c(10);
+ rt.free(d*f);
return 0;
}
diff --git a/tests/programs/o3zero.zc b/tests/programs/o3zero.zc
index cfb3061..7309c1d 100644
--- a/tests/programs/o3zero.zc
+++ b/tests/programs/o3zero.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt;
+
unchecked o3 int raw() {
- int* p = new(4);
+ int* p = rt.new(4);
return p[0] + p[1] + p[2] + p[3] + (p[-1] < 0);
}
fn main() {
- put_n(raw()); put_c(10);
+ rt.put_n(raw()); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/overflow_data.zc b/tests/programs/overflow_data.zc
index db24f8d..da21472 100644
--- a/tests/programs/overflow_data.zc
+++ b/tests/programs/overflow_data.zc
@@ -1 +1,4 @@
-fn main() { syscall(9, 5, syscall(9, 0, 0, 0), 0); while (1) asm { 1 } return 0; }
+namespace;
+include rt;
+
+fn main() { rt.syscall(9, 5, rt.syscall(9, 0, 0, 0), 0); while (1) asm { 1 } return 0; }
diff --git a/tests/programs/overflow_frame.zc b/tests/programs/overflow_frame.zc
index c017453..bc20178 100644
--- a/tests/programs/overflow_frame.zc
+++ b/tests/programs/overflow_frame.zc
@@ -1,2 +1,5 @@
+namespace;
+include rt;
+
fn big(n) { let a[500]; a[0] = n; return big(n + 1) + a[0]; }
-fn main() { syscall(9, 5, syscall(9, 0, 0, 0), 0); return big(0); }
+fn main() { rt.syscall(9, 5, rt.syscall(9, 0, 0, 0), 0); return big(0); }
diff --git a/tests/programs/overflow_return.zc b/tests/programs/overflow_return.zc
index 91e572d..decc5a8 100644
--- a/tests/programs/overflow_return.zc
+++ b/tests/programs/overflow_return.zc
@@ -1,2 +1,5 @@
+namespace;
+include rt;
+
fn deep(n) { return deep(n + 1) + 1; }
-fn main() { syscall(9, 5, syscall(9, 0, 0, 0), 0); return deep(0); }
+fn main() { rt.syscall(9, 5, rt.syscall(9, 0, 0, 0), 0); return deep(0); }
diff --git a/tests/programs/packedfields.zc b/tests/programs/packedfields.zc
index 8f6fe38..97afef0 100644
--- a/tests/programs/packedfields.zc
+++ b/tests/programs/packedfields.zc
@@ -1,29 +1,32 @@
+namespace;
+include rt;
+
// struct fields of the sized types and f32 pack into shared words
struct vtx { f32 x, y, z; u8 r, g, b, a; i16 id; u16 flags; int next; };
struct pair { u8 a; int b; u8 c; };
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
vtx gv;
fn main() {
vtx v;
- vtx* p = new(vtx);
+ vtx* p = rt.new(vtx);
pair q;
- [3]vtx arr;
- put_n(sizeof(vtx)); sp(); put_n(sizeof(pair)); sp();
+ vtx[3] arr;
+ rt.put_n(sizeof(vtx)); sp(); rt.put_n(sizeof(pair)); sp();
v.x = 1.5; v.y = 0.1; v.z = 2; v.r = 200; v.g = 255; v.b = 300; v.a = 7; v.id = 0 - 3; v.flags = 65535; v.next = 99;
- put_f(v.x + v.z); sp(); put_n(v.y == 0.1); sp();
- put_n(v.r); sp(); put_n(v.g); sp(); put_n(v.b); sp(); put_n(v.a); sp(); put_n(v.id); sp(); put_n(v.flags); sp(); put_n(v.next); sp();
+ put_f(v.x + v.z); sp(); rt.put_n(v.y == 0.1); sp();
+ rt.put_n(v.r); sp(); rt.put_n(v.g); sp(); rt.put_n(v.b); sp(); rt.put_n(v.a); sp(); rt.put_n(v.id); sp(); rt.put_n(v.flags); sp(); rt.put_n(v.next); sp();
v.r += 100; v.flags++; v.id--; v.g = v.g + 1;
- put_n(v.r); sp(); put_n(v.flags); sp(); put_n(v.id); sp(); put_n(v.g); sp();
+ rt.put_n(v.r); sp(); rt.put_n(v.flags); sp(); rt.put_n(v.id); sp(); rt.put_n(v.g); sp();
p.r = 9; p.a = 8; p.id = 1000; p.next = 5; p.x = 3.25;
- put_n(p.r); put_n(p.a); sp(); put_n(p.id); sp(); put_n(p.next); sp(); put_f(p.x); sp();
- gv.b = 77; gv.flags = 5; put_n(gv.b); sp(); put_n(gv.flags); sp();
+ rt.put_n(p.r); rt.put_n(p.a); sp(); rt.put_n(p.id); sp(); rt.put_n(p.next); sp(); put_f(p.x); sp();
+ gv.b = 77; gv.flags = 5; rt.put_n(gv.b); sp(); rt.put_n(gv.flags); sp();
arr[1].a = 42; arr[2].r = 17; arr[1].next = 3; arr[0].id = 0 - 9;
- put_n(arr[1].a); sp(); put_n(arr[2].r); sp(); put_n(arr[1].next); sp(); put_n(arr[0].id); sp(); put_n(arr[0].a); sp();
- put_n(sizeof(arr)); sp();
- q.a = 1; q.b = 123456789; q.c = 2; put_n(q.a); put_n(q.c); sp(); put_n(q.b);
- put_c(10);
- free(d*p);
+ rt.put_n(arr[1].a); sp(); rt.put_n(arr[2].r); sp(); rt.put_n(arr[1].next); sp(); rt.put_n(arr[0].id); sp(); rt.put_n(arr[0].a); sp();
+ rt.put_n(sizeof(arr)); sp();
+ q.a = 1; q.b = 123456789; q.c = 2; rt.put_n(q.a); rt.put_n(q.c); sp(); rt.put_n(q.b);
+ rt.put_c(10);
+ rt.free(d*p);
second();
return 0;
}
@@ -34,9 +37,9 @@ o3 int bright(rgba* px, int n) {
return s;
}
fn second() {
- rgba* px = new(rgba, 50);
+ rgba* px = rt.new(rgba, 50);
for (int i = 0; i < 50; i++) { px[i].r = i; px[i].g = i * 2; px[i].b = 255 - i; }
- put_n(bright(px, 50)); put_c(' '); put_n(px[10].a); put_c(' '); put_n(px[49].a); put_c(10);
- free(d*px);
+ rt.put_n(bright(px, 50)); rt.put_c(' '); rt.put_n(px[10].a); rt.put_c(' '); rt.put_n(px[49].a); rt.put_c(10);
+ rt.free(d*px);
return 0;
}
diff --git a/tests/programs/quarantine.zc b/tests/programs/quarantine.zc
index 5e3e188..061c4da 100644
--- a/tests/programs/quarantine.zc
+++ b/tests/programs/quarantine.zc
@@ -1,25 +1,28 @@
+namespace;
+include rt;
+
// free quarantines the block. a stale alias still reads it, and freeing
// through the alias does nothing because the header already says free.
// unchecked so the analyzer doesn't reject the use after free.
unchecked fn main() {
- let p = new(4), q, r, i = 0, t, bad = 0;
+ let p = rt.new(4), q, r, i = 0, t, bad = 0;
p[0] = 111; p[1] = 222; p[2] = 333; p[3] = 444;
q = p;
r = p + 2;
- free(p);
- while (i < 400) { t = new(4); t[0] = 999; t[1] = 888; t[2] = 777; t[3] = 666; i++; }
+ rt.free(p);
+ while (i < 400) { t = rt.new(4); t[0] = 999; t[1] = 888; t[2] = 777; t[3] = 666; i++; }
if (q[0] != 111 || q[1] != 222 || r[0] != 333 || r[1] != 444) bad = 1;
- free(q);
+ rt.free(q);
if (q[0] != 111 || q[1] != 222) bad = 2;
- gc(); // q still points at the block, so the sweep must not reuse it
+ rt.gc(); // q still points at the block, so the sweep must not reuse it
if (q[0] != 111 || r[0] != 333) bad = 3;
p = 0; q = 0; r = 0; t = 0;
- scrub();
- gc();
- t = new(4);
+ rt.scrub();
+ rt.gc();
+ t = rt.new(4);
t[0] = 1234;
- put_n(bad); put_c(' ');
- put_n(t[0]); put_c(10);
- free(t);
+ rt.put_n(bad); rt.put_c(' ');
+ rt.put_n(t[0]); rt.put_c(10);
+ rt.free(t);
return 0;
}
diff --git a/tests/programs/rawpid.zc b/tests/programs/rawpid.zc
index b3e7c2a..e9fec7d 100644
--- a/tests/programs/rawpid.zc
+++ b/tests/programs/rawpid.zc
@@ -1,6 +1,9 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
// syscall 39 is getpid on x86-64 only; the arm64 number differs, so test.sh runs this there alone.
fn main() {
- put_n(Host.raw(39, 0, 0, 0, 0, 0, 0) > 0); put_c(10);
+ rt.put_n(std.Host.raw(39, 0, 0, 0, 0, 0, 0) > 0); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/rawsys.zc b/tests/programs/rawsys.zc
index 753e1b7..7d52040 100644
--- a/tests/programs/rawsys.zc
+++ b/tests/programs/rawsys.zc
@@ -1,5 +1,8 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
fn main() {
- put_n(Host.raw(9999, 0, 0, 0, 0, 0, 0)); put_c(10);
+ rt.put_n(std.Host.raw(9999, 0, 0, 0, 0, 0, 0)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/recycle.zc b/tests/programs/recycle.zc
index 98c9b50..55951a5 100644
--- a/tests/programs/recycle.zc
+++ b/tests/programs/recycle.zc
@@ -1,23 +1,26 @@
+namespace;
+include rt;
+
// a uniquely owned free returns the block to its size class at once.
// a plain free still quarantines; that contract lives in quarantine.zc.
struct node { node* c; int n; };
unchecked fn addr(p) { return p; }
fn main() {
- let base = live_objects(), p, q, slot;
+ let base = rt.live_objects(), p, q, slot;
node* a;
node* b;
- p = new(4);
- a = new(node);
- b = new(node);
+ p = rt.new(4);
+ a = rt.new(node);
+ b = rt.new(node);
p[0] = 111;
a.c = b; a.n = 1; b.c = 0; b.n = 2;
slot = addr(p);
- free(d*p);
- q = new(4);
- free(d*a);
- put_n(q == slot); put_c(' ');
- put_n(q[0]); put_c(' ');
- put_n(live_objects() - base); put_c(10);
- free(d*q);
+ rt.free(d*p);
+ q = rt.new(4);
+ rt.free(d*a);
+ rt.put_n(q == slot); rt.put_c(' ');
+ rt.put_n(q[0]); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(10);
+ rt.free(d*q);
return 0;
}
diff --git a/tests/programs/replace_owner.expected b/tests/programs/replace_owner.expected
new file mode 100644
index 0000000..c0cbecc
--- /dev/null
+++ b/tests/programs/replace_owner.expected
@@ -0,0 +1 @@
+98 7 9 0
diff --git a/tests/programs/replace_owner.zc b/tests/programs/replace_owner.zc
new file mode 100644
index 0000000..8318616
--- /dev/null
+++ b/tests/programs/replace_owner.zc
@@ -0,0 +1,27 @@
+namespace;
+include rt;
+
+// a released owner can receive a same-scope replacement, without copying owners.
+int*.u growing(int n) {
+ int* buffer = rt.new(int), next; int i = 0;
+ while (i < n) {
+ if (!(i & 1)) {
+ next = rt.new(int);
+ *next = i;
+ rt.free(buffer);
+ buffer = next;
+ }
+ i++;
+ }
+ return buffer;
+}
+fn main() {
+ let base = rt.live_objects();
+ {
+ let result = growing(100); rt.put_n(*result); rt.put_c(32);
+ int* slot = rt.new(int), replacement = rt.new(int); *replacement = 7;
+ rt.free(slot); slot = replacement; rt.put_n(*slot); rt.put_c(32);
+ rt.free(slot); slot = rt.new(int); *slot = 9; rt.put_n(*slot); rt.put_c(32);
+ }
+ rt.gc(); rt.put_n(rt.live_objects() - base); rt.put_c(10);
+}
diff --git a/tests/programs/roots.zc b/tests/programs/roots.zc
index 22f12a5..4f05844 100644
--- a/tests/programs/roots.zc
+++ b/tests/programs/roots.zc
@@ -1,17 +1,20 @@
+namespace;
+include rt;
+
// a pointer left below the live stack is not a root. scrub then clears that word.
unchecked fn main() {
let p, slot, before, after;
- p = new(2);
+ p = rt.new(2);
p[0] = 7;
p[1] = 8;
- slot = DSLO + 8;
+ slot = rt.DSLO + 8;
*slot = p;
- before = live_objects();
+ before = rt.live_objects();
p = 0;
- gc();
- after = live_objects();
- put_n(after < before); put_c(32);
- scrub();
- put_n(*slot); put_c(10);
+ rt.gc();
+ after = rt.live_objects();
+ rt.put_n(after < before); rt.put_c(32);
+ rt.scrub();
+ rt.put_n(*slot); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/scrub.zc b/tests/programs/scrub.zc
index ebc6cfa..2ee9dcf 100644
--- a/tests/programs/scrub.zc
+++ b/tests/programs/scrub.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
unchecked fn main() {
- mem_set(2);
- let p = new(2);
+ rt.mem_set(2);
+ let p = rt.new(2);
p[0] = 11;
- free(p);
- put_n(p[0]);
- put_c(10);
+ rt.free(p);
+ rt.put_n(p[0]);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/share.zc b/tests/programs/share.zc
index e9c381f..91a3918 100644
--- a/tests/programs/share.zc
+++ b/tests/programs/share.zc
@@ -1,34 +1,51 @@
+namespace;
+include rt;
+
// shared cons cells, a shared string, and a cycle. the collector reclaims
// them once nothing points at them. free of a shared cell does nothing.
+// the shared cells again without printing, moved by a few blocks. returns the blocks left over
+fn churn(base) {
+ let a = rt.cons(1, 2), b = rt.cons(a, 3), c = rt.cons(a, 4), cyc = rt.cons(0, 1), tri = rt.triple(5, 6, 7);
+ cyc[0] = cyc;
+ a = 0; b = 0; c = 0; cyc = 0; tri = 0;
+ rt.scrub();
+ rt.gc();
+ return rt.live_objects() - base;
+}
fn main() {
- let base = live_objects(), a, b, c, s, p, q, cyc, n, tri;
- a = cons(1, 2);
- b = cons(a, 3);
- c = cons(a, 4);
- put_n(car(a)); put_c(32);
- put_n(cdr(a)); put_c(32);
- put_n(car(car(b))); put_c(32);
- put_n(cdr(c)); put_c(32);
- put_n(car(b) == a); put_c(32);
- put_n(is_shared(a)); put_c(32);
- n = live_objects();
- free(a);
- put_n(live_objects() == n); put_c(32);
- put_n(car(a)); put_c(32);
- s = n_to_s(42);
- p = cons(s, 0);
- q = cons(s, 1);
- put_n(s_to_n(car(p))); put_c(32);
- put_n(car(p) == car(q)); put_c(32);
- cyc = cons(0, 1);
+ let base = rt.live_objects(), a, b, c, s, p, q, cyc, n, tri, k, pad;
+ a = rt.cons(1, 2);
+ b = rt.cons(a, 3);
+ c = rt.cons(a, 4);
+ rt.put_n(rt.car(a)); rt.put_c(32);
+ rt.put_n(rt.cdr(a)); rt.put_c(32);
+ rt.put_n(rt.car(rt.car(b))); rt.put_c(32);
+ rt.put_n(rt.cdr(c)); rt.put_c(32);
+ rt.put_n(rt.car(b) == a); rt.put_c(32);
+ rt.put_n(rt.is_shared(a)); rt.put_c(32);
+ n = rt.live_objects();
+ rt.free(a);
+ rt.put_n(rt.live_objects() == n); rt.put_c(32);
+ rt.put_n(rt.car(a)); rt.put_c(32);
+ s = rt.n_to_s(42);
+ p = rt.cons(s, 0);
+ q = rt.cons(s, 1);
+ rt.put_n(rt.s_to_n(rt.car(p))); rt.put_c(32);
+ rt.put_n(rt.car(p) == rt.car(q)); rt.put_c(32);
+ cyc = rt.cons(0, 1);
cyc[0] = cyc;
- put_n(cdr(cyc)); put_c(32);
- put_n(car(cyc) == cyc); put_c(32);
- tri = triple(5, 6, 7);
- put_n(tget(tri, 1)); put_c(32);
+ rt.put_n(rt.cdr(cyc)); rt.put_c(32);
+ rt.put_n(rt.car(cyc) == cyc); rt.put_c(32);
+ tri = rt.triple(5, 6, 7);
+ rt.put_n(rt.tget(tri, 1)); rt.put_c(32);
a = 0; b = 0; c = 0; s = 0; p = 0; q = 0; cyc = 0; tri = 0;
- scrub();
- gc();
- put_n(live_objects() - base); put_c(10);
+ rt.scrub();
+ rt.gc();
+ // the collector marks conservatively: on a small map a word in the code can equal a block's address by
+ // chance and keep it. shifting where the blocks land must therefore reach a clean count
+ n = rt.live_objects() - base;
+ k = 0;
+ while (n && k < 40) { pad = rt.cons(k, k); rt.scrub(); rt.gc(); n = churn(rt.live_objects()); k++; }
+ rt.put_n(n); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/share_dbg.zc b/tests/programs/share_dbg.zc
index 5485b51..63b8cba 100644
--- a/tests/programs/share_dbg.zc
+++ b/tests/programs/share_dbg.zc
@@ -1,10 +1,13 @@
+namespace;
+include rt;
+
// memdebug still checks a shared cell. free does not quarantine it, and car
// reads the payload through checkptr.
memdebug on;
fn main() {
- let a = cons(7, 8);
- free(a);
- put_n(car(a)); put_c(32);
- put_n(is_shared(a)); put_c(10);
+ let a = rt.cons(7, 8);
+ rt.free(a);
+ rt.put_n(rt.car(a)); rt.put_c(32);
+ rt.put_n(rt.is_shared(a)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/sized.zc b/tests/programs/sized.zc
index 0a18467..1be0b31 100644
--- a/tests/programs/sized.zc
+++ b/tests/programs/sized.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt, run;
+
// sized integers: scalars wrap to their size, arrays and pointers of them are packed
-struct pix { u8 r, g, b, a; i16 dx; [4]u8 tag; };
+struct pix { u8 r, g, b, a; i16 dx; u8[4] tag; };
u8 gbyte = 300;
i8 gneg = 200;
u16 gword[5];
-[10]u8 gbuf;
+u8[10] run.gbuf;
u8 add8(u8 a, u8 b) { return a + b; }
@@ -12,13 +15,13 @@ fn scalars() {
i8 s = 100;
i16 h = 32767;
u32 w = 4294967295;
- a = a + 10; put_n(a); put_c(' '); // 4
- s = s + 100; put_n(s); put_c(' '); // -56
- h++; put_n(h); put_c(' '); // -32768
- w++; put_n(w); put_c(' '); // 0
- put_n(gbyte); put_c(' '); put_n(gneg); put_c(' '); // 44 -56
- put_n(add8(200, 100)); put_c(' '); // 44
- put_n((i8)200); put_c(' '); put_n(300 as u8); put_c(10); // -56 44
+ a = a + 10; rt.put_n(a); rt.put_c(' '); // 4
+ s = s + 100; rt.put_n(s); rt.put_c(' '); // -56
+ h++; rt.put_n(h); rt.put_c(' '); // -32768
+ w++; rt.put_n(w); rt.put_c(' '); // 0
+ rt.put_n(gbyte); rt.put_c(' '); rt.put_n(gneg); rt.put_c(' '); // 44 -56
+ rt.put_n(add8(200, 100)); rt.put_c(' '); // 44
+ rt.put_n((i8)200); rt.put_c(' '); rt.put_n(300 as u8); rt.put_c(10); // -56 44
return 0;
}
fn arrays() {
@@ -29,36 +32,36 @@ fn arrays() {
int i = 0, sum = 0;
while (i < 20) { buf[i] = i * 20; i++; } // wraps past 255
i = 0; while (i < 20) { sum = sum + buf[i]; i++; }
- put_n(sum); put_c(' '); // 1250
- sh[3] = 40000; put_n(sh[3]); put_c(' '); // -25536
- sh[3] += 30000; put_n(sh[3]); put_c(' '); // 4464
- ws[1] = 5000000000; put_n(ws[1]); put_c(' '); // 705032704
- sb[8] = 127; sb[8]++; put_n(sb[8]); put_c(' '); // -128
- sb[0] = 200; put_n(sb[0] < 0); put_c(' '); // 1: -56 is negative
- ws[0] = 4000000000; put_n(ws[0] + ws[0]); put_c(' '); // arithmetic is done in int: 8000000000
- put_n(sizeof(buf)); put_c(' '); // 3 words
- put_n(sizeof(sh)); put_c(10); // 2 words
+ rt.put_n(sum); rt.put_c(' '); // 1250
+ sh[3] = 40000; rt.put_n(sh[3]); rt.put_c(' '); // -25536
+ sh[3] += 30000; rt.put_n(sh[3]); rt.put_c(' '); // 4464
+ ws[1] = 5000000000; rt.put_n(ws[1]); rt.put_c(' '); // 705032704
+ sb[8] = 127; sb[8]++; rt.put_n(sb[8]); rt.put_c(' '); // -128
+ sb[0] = 200; rt.put_n(sb[0] < 0); rt.put_c(' '); // 1: -56 is negative
+ ws[0] = 4000000000; rt.put_n(ws[0] + ws[0]); rt.put_c(' '); // arithmetic is done in int: 8000000000
+ rt.put_n(sizeof(buf)); rt.put_c(' '); // 3 words
+ rt.put_n(sizeof(sh)); rt.put_c(10); // 2 words
return 0;
}
fn heap() {
- u8* p = new(u8, 1000);
+ u8* p = rt.new(u8, 1000);
int i = 0, sum = 0;
while (i < 1000) { p[i] = i; i++; }
i = 0; while (i < 1000) { sum = sum + p[i]; i++; }
- put_n(sum); put_c(' '); // 1000 bytes of 0..255: 3 * 32640 + 28 * ... = 127..
- put_n(osize(p) < 256); put_c(32); // 125 words plus the header, not 1000
- *p = 77; put_n(p[0]); put_c(' ');
- free(d*p);
- gbuf[9] = 255; gword[4] = 65535; gword[4]++;
- put_n(gbuf[9]); put_c(' '); put_n(gword[4]); put_c(10);
+ rt.put_n(sum); rt.put_c(' '); // 1000 bytes of 0..255: 3 * 32640 + 28 * ... = 127..
+ rt.put_n(rt.osize(p) < 256); rt.put_c(32); // 125 words plus the header, not 1000
+ *p = 77; rt.put_n(p[0]); rt.put_c(' ');
+ rt.free(d*p);
+ run.gbuf[9] = 255; gword[4] = 65535; gword[4]++;
+ rt.put_n(run.gbuf[9]); rt.put_c(' '); rt.put_n(gword[4]); rt.put_c(10);
return 0;
}
fn fields() {
- pix* q = new(pix);
+ pix* q = rt.new(pix);
q.r = 255; q.g = 256; q.dx = 65535; q.tag[2] = 7; q.tag[3] = 300;
- put_n(q.r); put_c(' '); put_n(q.g); put_c(' '); put_n(q.dx); put_c(' ');
- put_n(q.tag[2]); put_c(' '); put_n(q.tag[3]); put_c(' '); put_n(sizeof(pix)); put_c(10);
- free(d*q);
+ rt.put_n(q.r); rt.put_c(' '); rt.put_n(q.g); rt.put_c(' '); rt.put_n(q.dx); rt.put_c(' ');
+ rt.put_n(q.tag[2]); rt.put_c(' '); rt.put_n(q.tag[3]); rt.put_c(' '); rt.put_n(sizeof(pix)); rt.put_c(10);
+ rt.free(d*q);
return 0;
}
o3 fn checksum(u8* p, int n) {
@@ -67,11 +70,11 @@ o3 fn checksum(u8* p, int n) {
return b * 256 + a;
}
fn o3run() {
- u8* p = new(u8, 5000);
+ u8* p = rt.new(u8, 5000);
int i = 0;
while (i < 5000) { p[i] = i * 7; i++; }
- put_n(checksum(p, 5000)); put_c(10);
- free(d*p);
+ rt.put_n(checksum(p, 5000)); rt.put_c(10);
+ rt.free(d*p);
return 0;
}
fn main() {
diff --git a/tests/programs/sizedvec.zc b/tests/programs/sizedvec.zc
index 2055ade..1b84df3 100644
--- a/tests/programs/sizedvec.zc
+++ b/tests/programs/sizedvec.zc
@@ -1,39 +1,42 @@
-// growable arrays of the sized types and f32: []u8, []i16, []f32
+namespace;
+include rt;
+
+// growable arrays of the sized types and f32: u8[?], i16[?], f32[?]
fn put_f(x) { asm { x @ #1220 } return 0; }
-fn sp() { put_c(32); return 0; }
+fn sp() { rt.put_c(32); return 0; }
fn main() {
- []u8 b = new([]u8, 0);
- []i16 h = new([]i16, 3);
- []f32 f = new([]f32, 0);
+ u8[?] b = rt.new(u8[?], 0);
+ i16[?] h = rt.new(i16[?], 3);
+ f32[?] f = rt.new(f32[?], 0);
int i = 0, s = 0;
while (i < 100) { push(b, i * 7); i++; }
i = 0;
while (i < 100) { s = s + b[i]; i++; }
- put_n(len(b)); sp(); put_n(s); sp(); put_n(b[99]); sp();
- b[5] = 300; put_n(b[5]); sp();
- put_n(pop(b)); sp(); put_n(len(b)); sp();
+ rt.put_n(len(b)); sp(); rt.put_n(s); sp(); rt.put_n(b[99]); sp();
+ b[5] = 300; rt.put_n(b[5]); sp();
+ rt.put_n(pop(b)); sp(); rt.put_n(len(b)); sp();
h[0] = 40000; h[2] = 0 - 5; push(h, 70000);
- put_n(h[0]); sp(); put_n(h[1]); sp(); put_n(h[2]); sp(); put_n(h[3]); sp();
+ rt.put_n(h[0]); sp(); rt.put_n(h[1]); sp(); rt.put_n(h[2]); sp(); rt.put_n(h[3]); sp();
push(f, 0.1); push(f, 2.5); push(f, 1.0);
- put_n(f[0] == 0.1); sp(); put_f(f[1]); sp(); put_f(f[0] + f[2]); sp();
+ rt.put_n(f[0] == 0.1); sp(); put_f(f[1]); sp(); put_f(f[0] + f[2]); sp();
resize(b, 3); resize(b, 12);
- put_n(b[2]); put_n(b[3]); put_n(b[11]); sp();
- put_n(cap(b) >= 12);
- put_c(10);
- free(d*b); free(d*h); free(d*f);
+ rt.put_n(b[2]); rt.put_n(b[3]); rt.put_n(b[11]); sp();
+ rt.put_n(cap(b) >= 12);
+ rt.put_c(10);
+ rt.free(d*b); rt.free(d*h); rt.free(d*f);
second();
return 0;
}
-o3 int sumv([]u8 v) {
+o3 int sumv(u8[?] v) {
int s = 0;
for (int i = 0; i < len(v); i++) s += v[i];
return s;
}
fn second() {
- []u8 v = new([]u8, 0);
+ u8[?] v = rt.new(u8[?], 0);
int i = 0;
while (i < 300) { push(v, i); i++; }
- put_n(sumv(v)); put_c(10);
- free(d*v);
+ rt.put_n(sumv(v)); rt.put_c(10);
+ rt.free(d*v);
return 0;
}
diff --git a/tests/programs/static.zc b/tests/programs/static.zc
index ef54339..1b792dc 100644
--- a/tests/programs/static.zc
+++ b/tests/programs/static.zc
@@ -1,2 +1,5 @@
+namespace;
+include rt;
+
struct Str { int len; static fn size(s) { return s * 2; } static fn none() { return 5; } fn get() { return this.len; } }
-int main() { Str a; a.len = 9; put_n(Str.size(7)); put_c(32); put_n(Str.none()); put_c(32); put_n(a.get()); put_c(10); return 0; }
+int main() { Str a; a.len = 9; rt.put_n(Str.size(7)); rt.put_c(32); rt.put_n(Str.none()); rt.put_c(32); rt.put_n(a.get()); rt.put_c(10); return 0; }
diff --git a/tests/programs/stdbuf.zc b/tests/programs/stdbuf.zc
index ab8f9dc..acb1d2f 100644
--- a/tests/programs/stdbuf.zc
+++ b/tests/programs/stdbuf.zc
@@ -1,18 +1,21 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
fn main() {
- let a = arena(8), p, q, b, i = 0, s = 0;
- p = Arena.alloc(a, 4);
- q = Arena.alloc(a, 4);
- put_n(q - p); put_c(' ');
- Arena.reset(a);
- put_n(Arena.alloc(a, 4) == p); put_c(' ');
- b = bnew(8);
- while (i < 4) { Buf.set(b, i, 'A' + i); i++; }
+ let a = std.arena(8), p, q, b, i = 0, s = 0;
+ p = std.Arena.alloc(a, 4);
+ q = std.Arena.alloc(a, 4);
+ rt.put_n(q - p); rt.put_c(' ');
+ std.Arena.reset(a);
+ rt.put_n(std.Arena.alloc(a, 4) == p); rt.put_c(' ');
+ b = std.bnew(8);
+ while (i < 4) { std.Buf.set(b, i, 'A' + i); i++; }
i = 0;
- while (i < Buf.length(b)) { s = s + Buf.get(b, i); i++; }
- put_n(s); put_c(' ');
- put_n(Buf.capacity(b)); put_c(10);
- free(d*a);
- free(d*b);
+ while (i < std.Buf.length(b)) { s = s + std.Buf.get(b, i); i++; }
+ rt.put_n(s); rt.put_c(' ');
+ rt.put_n(std.Buf.capacity(b)); rt.put_c(10);
+ rt.free(d*a);
+ rt.free(d*b);
return 0;
}
diff --git a/tests/programs/stdmore.zc b/tests/programs/stdmore.zc
index fb225ec..e7975e6 100644
--- a/tests/programs/stdmore.zc
+++ b/tests/programs/stdmore.zc
@@ -1,32 +1,44 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
fn main() {
let buf[32];
- put_n(Text.len("hello")); put_c(' ');
- put_n(Text.eq("abc", "abc")); put_c(' ');
- put_n(Text.eq("abc", "abd")); put_c(' ');
- put_n(Text.eq("ab", "abc")); put_c(' ');
- put_n(Text.copy(buf, "copy me")); put_c(' ');
- put_s(buf); put_c(' ');
- put_n(Text.find("needle in a haystack", "hay")); put_c(' ');
- put_n(Text.find("abc", "zz")); put_c(' ');
- put_n(Text.find("abc", "")); put_c(10);
- Text.copy(buf, "MiXeD 123");
- put_n(Text.lower(buf)); put_c(' ');
- put_s(buf); put_c(' ');
- put_n(Text.upper(buf)); put_c(' ');
- put_s(buf); put_c(10);
- Text.copy(buf, " \t padded line \r\n");
- put_n(Text.trim(buf)); put_c(' ');
- put_c('['); put_s(buf); put_c(']'); put_c(10);
- put_n(Num.abs(0 - 42)); put_c(' ');
- put_n(Num.min(3, 9)); put_c(' ');
- put_n(Num.max(3, 9)); put_c(' ');
- put_n(Num.clamp(50, 0, 10)); put_c(' ');
- put_n(Num.gcd(0 - 84, 36)); put_c(' ');
- put_n(Num.pow(3, 4)); put_c(' ');
- put_n(Num.isqrt(99)); put_c(' ');
- put_n(Num.isqrt(100)); put_c(' ');
- put_n(Num.sign(0 - 5)); put_c(' ');
- put_n(Num.sign(0)); put_c(10);
+ rt.put_n(std.Text.len("hello")); rt.put_c(' ');
+ rt.put_n(std.Text.eq("abc", "abc")); rt.put_c(' ');
+ rt.put_n(std.Text.eq("abc", "abd")); rt.put_c(' ');
+ rt.put_n(std.Text.eq("ab", "abc")); rt.put_c(' ');
+ rt.put_n(std.Text.copy(buf, "copy me")); rt.put_c(' ');
+ rt.put_s(buf); rt.put_c(' ');
+ rt.put_n(std.Text.find("needle in a haystack", "hay")); rt.put_c(' ');
+ rt.put_n(std.Text.find("abc", "zz")); rt.put_c(' ');
+ rt.put_n(std.Text.find("abc", "")); rt.put_c(' ');
+ rt.put_n(std.Text.ends("needle", "dle")); rt.put_c(' ');
+ rt.put_n(std.Text.ends("a", "abc")); rt.put_c(' ');
+ rt.put_n(std.Text.ends("a", "")); rt.put_c(10);
+ std.Text.copy(buf, "MiXeD 123");
+ rt.put_n(std.Text.lower(buf)); rt.put_c(' ');
+ rt.put_s(buf); rt.put_c(' ');
+ rt.put_n(std.Text.upper(buf)); rt.put_c(' ');
+ rt.put_s(buf); rt.put_c(10);
+ std.Text.copy(buf, " \t padded line \r\n");
+ rt.put_n(std.Text.trim(buf)); rt.put_c(' ');
+ rt.put_c('['); rt.put_s(buf); rt.put_c(']'); rt.put_c(10);
+ rt.put_n(std.Num.abs(0 - 42)); rt.put_c(' ');
+ rt.put_n(std.Num.min(3, 9)); rt.put_c(' ');
+ rt.put_n(std.Num.max(3, 9)); rt.put_c(' ');
+ rt.put_n(std.Num.clamp(50, 0, 10)); rt.put_c(' ');
+ rt.put_n(std.Num.gcd(0 - 84, 36)); rt.put_c(' ');
+ rt.put_n(std.Num.pow(3, 4)); rt.put_c(' ');
+ rt.put_n(std.Num.isqrt(99)); rt.put_c(' ');
+ rt.put_n(std.Num.isqrt(100)); rt.put_c(' ');
+ rt.put_n(std.Num.sign(0 - 5)); rt.put_c(' ');
+ rt.put_n(std.Num.sign(0)); rt.put_c(10);
+ rt.put_n(std.Bytes.len(b"packed")); rt.put_c(' ');
+ rt.put_n(std.Bytes.eq(b"abc", b"abc")); rt.put_c(' ');
+ rt.put_n(std.Bytes.find(b"needle", b"ed")); rt.put_c(' ');
+ rt.put_n(std.Bytes.find(b"abc", b"z")); rt.put_c(' ');
+ rt.put_n(std.Bytes.ends(b"packed", b"ed")); rt.put_c(' ');
+ rt.put_n(std.Bytes.ends(b"a", b"abc")); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/strings.zc b/tests/programs/strings.zc
index 431bd4e..cde3a94 100644
--- a/tests/programs/strings.zc
+++ b/tests/programs/strings.zc
@@ -1,37 +1,40 @@
+namespace;
+include rt;
+
fn main() {
let a = b"hi", b = b"!", c = a + b;
let mid = c[1:3];
- let neg = s_to_n(b"-42");
- let p = n_to_s(42);
- let q = n_to_s(0 - 42);
- let ten = s_to_n(b"10");
- let big = n_to_s(1 << 63);
+ let neg = rt.s_to_n(b"-42");
+ let p = rt.n_to_s(42);
+ let q = rt.n_to_s(0 - 42);
+ let ten = rt.s_to_n(b"10");
+ let big = rt.n_to_s(1 << 63);
let empty = b"";
let tail = c[2:99];
let esc = b"a\nb";
let z = b"" + b"ab";
- put_s(c); put_c(32);
- put_n(len(c)); put_c(32);
- put_n(len_s(c)); put_c(32);
- put_n(c[0]); put_c(32);
- put_s(mid); put_c(32);
- put_n(c == b"hi!"); put_c(32);
- put_n(c != b"hi"); put_c(32);
- put_n(c < b"hj"); put_c(32);
- put_n(neg); put_c(32);
- put_s(p); put_c(32);
- put_s(q); put_c(32);
- put_n(ten + 1); put_c(32);
- put_n(p == b"42"); put_c(32);
- put_s(big); put_c(32);
- put_n(len(empty)); put_c(32);
- put_n(len(tail)); put_c(32);
- put_n(len_s(esc)); put_c(32);
- put_n(at_s(esc, 1)); put_c(32);
- put_n(b"ab" > b"a"); put_c(32);
- put_n(b"ab" >= b"ab"); put_c(32);
- put_n(b"a" <= b"a"); put_c(32);
- put_s("W"); put_c(32);
- put_s(z); put_c(10);
+ rt.put_s(c); rt.put_c(32);
+ rt.put_n(len(c)); rt.put_c(32);
+ rt.put_n(rt.len_s(c)); rt.put_c(32);
+ rt.put_n(c[0]); rt.put_c(32);
+ rt.put_s(mid); rt.put_c(32);
+ rt.put_n(c == b"hi!"); rt.put_c(32);
+ rt.put_n(c != b"hi"); rt.put_c(32);
+ rt.put_n(c < b"hj"); rt.put_c(32);
+ rt.put_n(neg); rt.put_c(32);
+ rt.put_s(p); rt.put_c(32);
+ rt.put_s(q); rt.put_c(32);
+ rt.put_n(ten + 1); rt.put_c(32);
+ rt.put_n(p == b"42"); rt.put_c(32);
+ rt.put_s(big); rt.put_c(32);
+ rt.put_n(len(empty)); rt.put_c(32);
+ rt.put_n(len(tail)); rt.put_c(32);
+ rt.put_n(rt.len_s(esc)); rt.put_c(32);
+ rt.put_n(rt.at_s(esc, 1)); rt.put_c(32);
+ rt.put_n(b"ab" > b"a"); rt.put_c(32);
+ rt.put_n(b"ab" >= b"ab"); rt.put_c(32);
+ rt.put_n(b"a" <= b"a"); rt.put_c(32);
+ rt.put_s("W"); rt.put_c(32);
+ rt.put_s(z); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/structret.zc b/tests/programs/structret.zc
index 708c83c..5e99653 100644
--- a/tests/programs/structret.zc
+++ b/tests/programs/structret.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// structs returned from native functions: the stub makes the result (a new object,
// owned by the caller) and the native call fills it in. the helper library is built
// by test.sh (build/sbv.so).
@@ -14,11 +17,11 @@ extern struct Mixed mkmixed(long a, double x);
extern struct Vec3 mkv3(double x);
int main() {
Pair* p; Vec* v; Trio* t; Mixed* m; Vec3* w;
- cload(b"build/sbv.so");
- p = mkpair(3, 4); put_n(p.a); put_c(32); put_n(p.b); put_c(32);
- v = mkvec(2.5, 3.0); put_f(v.x); put_c(32); put_f(v.y); put_c(32);
- t = mktrio(7, 8, 9); put_n(t.a + t.b + t.c); put_c(32);
- m = mkmixed(7, 0.5); put_n(m.a); put_c(32); put_f(m.x); put_c(32);
- w = mkv3(1.5); put_f(w.z); put_c(10);
+ rt.cload(b"build/sbv.so");
+ p = mkpair(3, 4); rt.put_n(p.a); rt.put_c(32); rt.put_n(p.b); rt.put_c(32);
+ v = mkvec(2.5, 3.0); put_f(v.x); rt.put_c(32); put_f(v.y); rt.put_c(32);
+ t = mktrio(7, 8, 9); rt.put_n(t.a + t.b + t.c); rt.put_c(32);
+ m = mkmixed(7, 0.5); rt.put_n(m.a); rt.put_c(32); put_f(m.x); rt.put_c(32);
+ w = mkv3(1.5); put_f(w.z); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/structval.zc b/tests/programs/structval.zc
index a1bd041..c7d0573 100644
--- a/tests/programs/structval.zc
+++ b/tests/programs/structval.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// structs by value in native calls: a zc struct of word fields is passed to a c
// function as its words. the helper library is built by test.sh (build/sbv.so).
struct Pair { int a; int b; }
@@ -11,16 +14,16 @@ extern long trio_sum(long a, long b, long c, long d, long e, long f, struct Trio
extern long eight(long a, long b, long c, long d, long e, long f, long g, long h, struct Pair p);
int main() {
Pair p; Pair q; Vec v; Trio t;
- cload(b"build/sbv.so");
+ rt.cload(b"build/sbv.so");
p.a = 3; p.b = 4;
- put_n(pair_sum(p)); put_c(32);
+ rt.put_n(pair_sum(p)); rt.put_c(32);
q.a = 10; q.b = 20;
- put_n(pair_sum2(p, q)); put_c(32);
+ rt.put_n(pair_sum2(p, q)); rt.put_c(32);
v.x = 1.5; v.y = 2.0;
- put_n(vec_scaled(v, 2)); put_c(32);
- put_n(many(1, 2, 3, 4, 5, 6, p)); put_c(32);
+ rt.put_n(vec_scaled(v, 2)); rt.put_c(32);
+ rt.put_n(many(1, 2, 3, 4, 5, 6, p)); rt.put_c(32);
t.a = 7; t.b = 8; t.c = 9;
- put_n(trio_sum(1, 2, 3, 4, 5, 6, t)); put_c(32);
- put_n(eight(1, 2, 3, 4, 5, 6, 7, 8, p)); put_c(10);
+ rt.put_n(trio_sum(1, 2, 3, 4, 5, 6, t)); rt.put_c(32);
+ rt.put_n(eight(1, 2, 3, 4, 5, 6, 7, 8, p)); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/sys.zc b/tests/programs/sys.zc
index 52924fa..aa82097 100644
--- a/tests/programs/sys.zc
+++ b/tests/programs/sys.zc
@@ -1,11 +1,14 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
fn main() {
let s, n;
- n = Host.writefile("/tmp/zc-sys-out.txt", "zy");
- s = readfile("/tmp/zc-sys-out.txt");
- put_n(n); put_c(' '); put_s(s); put_c(' ');
- if (Host.now() > 1000000000) put_s("time\n");
- else put_s("notime\n");
- free(d*s);
+ n = std.Host.writefile("/tmp/zc-sys-out.txt", "zy");
+ s = rt.readfile("/tmp/zc-sys-out.txt");
+ rt.put_n(n); rt.put_c(' '); rt.put_s(s); rt.put_c(' ');
+ if (std.Host.now() > 1000000000) rt.put_s("time\n");
+ else rt.put_s("notime\n");
+ rt.free(d*s);
return 0;
}
diff --git a/tests/programs/tagenum.zc b/tests/programs/tagenum.zc
index f438c5b..013f191 100644
--- a/tests/programs/tagenum.zc
+++ b/tests/programs/tagenum.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// tagged enums: a member can carry fields, a constructor builds it, and a
// switch matches on the member and binds its fields
enum shape { circle { int r; }, rect { int w; int h; }, dot };
@@ -15,12 +18,12 @@ fn main() {
shape* a = shape.circle(3);
shape* b = shape.rect(4, 5);
shape* c = shape.dot();
- put_n(area(a)); put_c(32);
- put_n(area(b)); put_c(32);
- put_n(area(c)); put_c(32);
- put_n(a.tag); put_c(32);
- put_n(b.tag); put_c(32);
- put_n(c.tag); put_c(10);
- free(d*a); free(d*b); free(d*c);
+ rt.put_n(area(a)); rt.put_c(32);
+ rt.put_n(area(b)); rt.put_c(32);
+ rt.put_n(area(c)); rt.put_c(32);
+ rt.put_n(a.tag); rt.put_c(32);
+ rt.put_n(b.tag); rt.put_c(32);
+ rt.put_n(c.tag); rt.put_c(10);
+ rt.free(d*a); rt.free(d*b); rt.free(d*c);
return 0;
}
diff --git a/tests/programs/tagenum_two.zc b/tests/programs/tagenum_two.zc
index eef45dd..8fda748 100644
--- a/tests/programs/tagenum_two.zc
+++ b/tests/programs/tagenum_two.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// two tagged enums may share a member name: each keeps its own fields and tag
enum a { item { int x; }, other };
enum b { item { int y; }, nope };
@@ -14,7 +17,7 @@ o3 int tot(a* p, int n) {
int main() {
a* p = a.item(3);
b* q = b.item(8);
- put_n(p.item_x); put_c(32); put_n(q.item_y); put_c(32); put_n(tot(p, 4)); put_c(10);
- free(d*p); free(d*q);
+ rt.put_n(p.item_x); rt.put_c(32); rt.put_n(q.item_y); rt.put_c(32); rt.put_n(tot(p, 4)); rt.put_c(10);
+ rt.free(d*p); rt.free(d*q);
return 0;
}
diff --git a/tests/programs/tagenum_warn.zc b/tests/programs/tagenum_warn.zc
index f50ab7c..1f31311 100644
--- a/tests/programs/tagenum_warn.zc
+++ b/tests/programs/tagenum_warn.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// a switch on a tagged enum that leaves out a member, with no default, warns
enum shape { circle { int r; }, rect { int w; int h; }, dot };
@@ -11,7 +14,7 @@ fn name(shape* s) {
fn main() {
shape* a = shape.rect(2, 2);
- put_n(name(a)); put_c(10);
- free(d*a);
+ rt.put_n(name(a)); rt.put_c(10);
+ rt.free(d*a);
return 0;
}
diff --git a/tests/programs/temporary_borrows.expected b/tests/programs/temporary_borrows.expected
new file mode 100644
index 0000000..94e4967
--- /dev/null
+++ b/tests/programs/temporary_borrows.expected
@@ -0,0 +1 @@
+a0 b0 99 0 100 0 1 0 102 0 3 0 1 106 0 114 0 13
diff --git a/tests/programs/temporary_borrows.zc b/tests/programs/temporary_borrows.zc
new file mode 100644
index 0000000..40e00ba
--- /dev/null
+++ b/tests/programs/temporary_borrows.zc
@@ -0,0 +1,29 @@
+namespace;
+include rt;
+
+// original allocations are released after their aliases' last expression use, across branches and loops.
+word latest; int made;
+unchecked char*.u message(int code) {
+ char* p = rt.new(2); p[0] = code; p[1] = 0; latest = p; made++; return p;
+}
+char* alias(char* p) { return p; }
+int read(char* p) { return p[0]; }
+int output(char* p) { rt.put_s(p); return 0; }
+int recursive(char* p, int n) { if (n) return recursive(p, n - 1); return read(p); }
+int returning() { return read(alias(message('r'))); }
+fn main() {
+ rt.put_s(message('a')); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ output(message('b')); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(read(alias(message('c')))); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(alias(message('d'))[0]); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(rt.eq_w(message('e'), message('e'))); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(recursive(message('f'), 3)); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ int n = 0; while (n < 3 && read(message('g')) == 'g') { n++; }
+ rt.put_n(n); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ int skipped = 0 && read(message('h')); int yes = 1 || read(message('i'));
+ rt.put_n(skipped + yes); rt.put_c(32);
+ int choice = alias(message(0)) ? read(message('j')) : 2;
+ rt.put_n(choice); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(returning()); rt.put_c(32); rt.put_n(rt.isobj(latest)); rt.put_c(32);
+ rt.put_n(made); rt.put_c(10);
+}
diff --git a/tests/programs/typedmethods.zc b/tests/programs/typedmethods.zc
index facd9f1..570ae17 100644
--- a/tests/programs/typedmethods.zc
+++ b/tests/programs/typedmethods.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// struct methods declare a return type and typed parameters, like functions do
struct Str {
int len;
@@ -8,9 +11,9 @@ struct Str {
int main() {
Str a;
a.len = 9;
- put_n(Str.size(7)); put_c(32);
- put_n(Str.none()); put_c(32);
- put_n(a.plus(4));
- put_c(10);
+ rt.put_n(Str.size(7)); rt.put_c(32);
+ rt.put_n(Str.none()); rt.put_c(32);
+ rt.put_n(a.plus(4));
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/typeoff.zc b/tests/programs/typeoff.zc
index d82bca8..aa71bea 100644
--- a/tests/programs/typeoff.zc
+++ b/tests/programs/typeoff.zc
@@ -1,2 +1,5 @@
+namespace;
+include rt;
+
// the typechecker is off unless asked for: this mismatch compiles and runs
-fn main() { char* s = 5; put_n(s as int + 1); put_c(10); return 0; }
+fn main() { char* s = 5; rt.put_n(s as int + 1); rt.put_c(10); return 0; }
diff --git a/tests/programs/typeok.zc b/tests/programs/typeok.zc
index 26ab3ad..72a254a 100644
--- a/tests/programs/typeok.zc
+++ b/tests/programs/typeok.zc
@@ -1,21 +1,24 @@
+namespace;
+include rt;
+
// passes the typechecker: words mix with everything, literal 0 is null,
// arrays decay to pointers, generic calls bind their parameters
typecheck on;
struct pair<A, B> { A a; B b; };
-pair<A, B>*.u mk<A, B>(A x, B y) { pair<A, B>* p = new(pair<A, B>); p.a = x; p.b = y; return u*p; }
+pair<A, B>*.u mk<A, B>(A x, B y) { pair<A, B>* p = rt.new(pair<A, B>); p.a = x; p.b = y; return u*p; }
A left<A, B>(pair<A, B>* p) { return p.a; }
int strlen2(char* s) { int n = 0; while (s[n]) n++; return n; }
int main() {
pair<int, char*>* p = mk(3, "four");
int a = left(p);
char* s = p.b;
- [8]char buf;
+ char[8] buf;
char* q = buf;
int* nothing = 0;
let w = 5;
int mixed = w + 1;
q[0] = 'h'; q[1] = 0;
- put_n(a + strlen2(s) + strlen2(buf) + mixed); put_c(10);
- free(d*p);
+ rt.put_n(a + strlen2(s) + strlen2(buf) + mixed); rt.put_c(10);
+ rt.free(d*p);
return 0;
}
diff --git a/tests/programs/types.zc b/tests/programs/types.zc
index 86488db..5eaa964 100644
--- a/tests/programs/types.zc
+++ b/tests/programs/types.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt, run;
+
struct point { int x, y; };
struct rect { point a, b; int tag; };
struct list<T> { int len; T* items; };
@@ -5,14 +8,14 @@ struct node { int v; node* next; };
type num = int;
int counter = 5;
-[4]int squares;
+int[4] squares;
point origin;
int area(rect* r) { return (r.b.x - r.a.x) * (r.b.y - r.a.y); }
list<T>*.u mklist<T>(int cap) {
- list<T>* l = new(list<T>);
+ list<T>* l = rt.new(list<T>);
l.len = 0;
- l.items = new(T, cap) as T*;
+ l.items = rt.new(T, cap) as T*;
return u*l;
}
T first<T>(list<T>* l) { return l.items[0]; }
@@ -21,35 +24,35 @@ int sum(node* n) { int s = 0; while (n) { s += n.v; n = n.next; } return s; }
fn main() {
rect r;
r.a.x = 1; r.a.y = 2; r.b.x = 4; r.b.y = 6;
- put_n(area(&r)); put_c(' ');
- put_n(sizeof(rect)); put_c(' '); put_n(sizeof(point)); put_c(' '); put_n(sizeof([3]rect)); put_c(' ');
- let p = new(point); // let infers *point
+ rt.put_n(area(&r)); rt.put_c(' ');
+ rt.put_n(sizeof(rect)); rt.put_c(' '); rt.put_n(sizeof(point)); rt.put_c(' '); rt.put_n(sizeof(rect[3])); rt.put_c(' ');
+ let p = rt.new(point); // let infers *point
p.x = 7; p->y = 8;
- put_n(p.x * p.y); put_c(' ');
- free(d*p);
+ rt.put_n(p.x * p.y); rt.put_c(' ');
+ rt.free(d*p);
list<int>* l = mklist<int>(4);
l.items[0] = 42; l.len = 1;
- put_n(first(l)); put_c(' ');
- free(d*l);
- node* a = new(node), b = new(node);
+ rt.put_n(first(l)); rt.put_c(' ');
+ rt.free(d*l);
+ node* a = rt.new(node), b = rt.new(node);
a.v = 3; b.v = 4; a.next = b;
- put_n(sum(a)); put_c(' ');
- free(d*a); // b went with it: a.next = b made a its owner
- [3]point pts;
+ rt.put_n(sum(a)); rt.put_c(' ');
+ rt.free(d*a); // b went with it: a.next = b made a its owner
+ point[3] pts;
pts[2].y = 9;
- put_n(pts[2].y + counter); put_c(' ');
+ rt.put_n(pts[2].y + counter); rt.put_c(' ');
num k = 3;
- put_n(k); put_c(10);
+ rt.put_n(k); rt.put_c(10);
// reflection
- tprint(typeof(r)); put_c(' '); tprint(typeof(&r)); put_c(' '); tprint(typeof(l)); put_c(' ');
- tprint(sigof(mklist)); put_c(' '); tprint(sigof(first)); put_c(' '); tprint(sigofs("free")); put_c(10);
+ run.tprint(typeof(r)); rt.put_c(' '); run.tprint(typeof(&r)); rt.put_c(' '); run.tprint(typeof(l)); rt.put_c(' ');
+ run.tprint(run.sigof(mklist)); rt.put_c(' '); run.tprint(run.sigof(first)); rt.put_c(' '); run.tprint(run.sigofs("free")); rt.put_c(10);
let t = typeof(r), i = 0;
- while (i < tnfields(t)) { put_s(tfname(t, i)); put_c(':'); tprint(tftype(t, i)); put_c('@'); put_n(tfoff(t, i)); put_c(' '); i++; }
- put_c(10);
- point* q = new(point);
- tprint(typeof_obj(q)); put_c(' '); put_n(typeof_obj(q) == typeof(point)); put_c(' '); put_n(tkind(typeof_obj(q)) == TY_STRUCT);
- free(d*q);
- put_c(10);
+ while (i < run.tnfields(t)) { rt.put_s(run.tfname(t, i)); rt.put_c(':'); run.tprint(run.tftype(t, i)); rt.put_c('@'); rt.put_n(run.tfoff(t, i)); rt.put_c(' '); i++; }
+ rt.put_c(10);
+ point* q = rt.new(point);
+ run.tprint(rt.typeof_obj(q)); rt.put_c(' '); rt.put_n(rt.typeof_obj(q) == typeof(point)); rt.put_c(' '); rt.put_n(run.tkind(rt.typeof_obj(q)) == run.TY_STRUCT);
+ rt.free(d*q);
+ rt.put_c(10);
return 0;
}
diff --git a/tests/programs/uaf.zc b/tests/programs/uaf.zc
index 4c14e91..18cb663 100644
--- a/tests/programs/uaf.zc
+++ b/tests/programs/uaf.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt;
+
memdebug on;
unchecked fn main()
{
- let p = new(2);
+ let p = rt.new(2);
p[0] = 42;
- free(p);
+ rt.free(p);
return p[0];
}
diff --git a/tests/programs/uaf_in.zc b/tests/programs/uaf_in.zc
index 89ad9f9..d9354a0 100644
--- a/tests/programs/uaf_in.zc
+++ b/tests/programs/uaf_in.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
memdebug on;
unchecked fn main()
{
- let p = new(4), r;
+ let p = rt.new(4), r;
p[2] = 5;
r = p + 2;
- free(p);
+ rt.free(p);
return r[0];
}
diff --git a/tests/programs/umd.zc b/tests/programs/umd.zc
index fb1640e..e7ddc88 100644
--- a/tests/programs/umd.zc
+++ b/tests/programs/umd.zc
@@ -1,16 +1,19 @@
+namespace;
+include rt;
+
// lists as [len, items...], items owned by the list
.u mklist(n) {
- let l = new(n + 1);
+ let l = rt.new(n + 1);
l[0] = 0;
return u*l;
}
fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; }
fn sum(.m l) { let s = 0, i = 1; while (i <= l[0]) { s += l[i][0]; i++; } return s; }
-.u box(v) { let b = new(1); b[0] = v; return u*b; }
+.u box(v) { let b = rt.new(1); b[0] = v; return u*b; }
fn consume(.d b) { return b[0]; }
fn main() {
- let base = live_objects();
+ let base = rt.live_objects();
{
let l = mklist(8); // u from mklist arrives m*here
let i = 0;
@@ -20,10 +23,10 @@ fn main() {
push(l, b);
i++;
}
- put_n(sum(l)); put_c(' ');
- put_n(live_objects() - base); put_c(' '); // list + 5 boxes
+ rt.put_n(sum(l)); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(' '); // list + 5 boxes
}
- put_n(live_objects() - base); put_c(' '); // freed at the block's end, children too
+ rt.put_n(rt.live_objects() - base); rt.put_c(' '); // freed at the block's end, children too
// u handed up one block by assignment, and as a block value
let outer;
@@ -33,18 +36,18 @@ fn main() {
outer = t;
}
let v = { let w = box(8); u*w };
- put_n(outer[0] + v[0]); put_c(' ');
+ rt.put_n(outer[0] + v[0]); rt.put_c(' ');
// d given away to a callee
let g = box(99);
- put_n(consume(d*g)); put_c(' ');
+ rt.put_n(consume(d*g)); rt.put_c(' ');
// containers: child takes its parent's tag
- let p = new(2), c = new(1);
+ let p = rt.new(2), c = rt.new(1);
c[0] = 5;
p[0] = c;
- p[1] = new(3);
- put_n(p[0][0]); put_c(' ');
- put_n(live_objects() - base); put_c(10);
+ p[1] = rt.new(3);
+ rt.put_n(p[0][0]); rt.put_c(' ');
+ rt.put_n(rt.live_objects() - base); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/undefined_call.zc b/tests/programs/undefined_call.zc
index e6a3b48..1f527c8 100644
--- a/tests/programs/undefined_call.zc
+++ b/tests/programs/undefined_call.zc
@@ -1 +1,3 @@
+namespace;
+
fn main() { nope(); return 0; }
diff --git a/tests/programs/use_std.zc b/tests/programs/use_std.zc
index c15e49b..db319d9 100644
--- a/tests/programs/use_std.zc
+++ b/tests/programs/use_std.zc
@@ -1,9 +1,12 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
+
+include std;
fn main() {
let out[12];
- Text.itoa(42, out);
- put_s(out); put_c(' ');
- put_n(Text.atoi("-7")); put_c(' ');
- put_n(Text.starts("hello", "he")); put_c(10);
+ std.Text.itoa(42, out);
+ rt.put_s(out); rt.put_c(' ');
+ rt.put_n(std.Text.atoi("-7")); rt.put_c(' ');
+ rt.put_n(std.Text.starts("hello", "he")); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/wide.zc b/tests/programs/wide.zc
index c20004b..e31601d 100644
--- a/tests/programs/wide.zc
+++ b/tests/programs/wide.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// a word is 64 bits: shifts past 31, and equality uses bit 63
fn main() {
- put_n(1 << 40); put_c(' ');
- put_n((1 << 40) >> 40); put_c(' ');
- put_n((1 << 40) == (1 << 40)); put_c(' ');
- put_n((1 << 40) != 0); put_c(' ');
- put_n(~0 >> 63); put_c(10);
+ rt.put_n(1 << 40); rt.put_c(' ');
+ rt.put_n((1 << 40) >> 40); rt.put_c(' ');
+ rt.put_n((1 << 40) == (1 << 40)); rt.put_c(' ');
+ rt.put_n((1 << 40) != 0); rt.put_c(' ');
+ rt.put_n(~0 >> 63); rt.put_c(10);
return 0;
}
diff --git a/tests/programs/zc0plain.zc b/tests/programs/zc0plain.zc
index 1092f76..f573b17 100644
--- a/tests/programs/zc0plain.zc
+++ b/tests/programs/zc0plain.zc
@@ -1,3 +1,5 @@
+namespace;
+
// the stage 0 compiler (src/tools/zc0.c) has no types. it reads them and throws
// them away, so a typed program and the same program without the types come
// out as the same image. tests/programs/zc0typed.zc is this file with the types on.
diff --git a/tests/programs/zc0typed.zc b/tests/programs/zc0typed.zc
index 4b7f438..81209bf 100644
--- a/tests/programs/zc0typed.zc
+++ b/tests/programs/zc0typed.zc
@@ -1,20 +1,22 @@
+namespace;
+
// the stage 0 compiler (src/tools/zc0.c) has no types. it reads them and throws
// them away, so a typed program and the same program without the types come
// out as the same image. tests/programs/zc0plain.zc is this file with the types off.
int total;
-[8]int table;
-[]word names;
+int[8] table;
+word[?] names;
const int LIMIT = 10;
int add(int a, int b) { return a + b; }
-.u grow([]word v, int n) { return v; }
+.u grow(word[?] v, int n) { return v; }
bool keep(int.d x, .m y) { return x != y; }
int apply(int(int) f, int* p, vec<vec<int>>*.u q) { return f(*p); }
int sq(int x) { return x * x; }
fn start() {
int i = 0, sum = 0;
- [4]int a;
+ int[4] a;
int* p = a;
for (int j = 0; j < LIMIT; j++) sum = add(sum, sq(j));
while (i < 4) { a[i] = i; i++; }