aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/bf.zc15
-rw-r--r--examples/cli.zc17
-rw-r--r--examples/cli2.zc35
-rw-r--r--examples/dump.zc41
-rw-r--r--examples/echo.zc5
-rw-r--r--examples/fact.zc7
-rw-r--r--examples/hello.zc5
-rw-r--r--examples/lang.zc49
-rw-r--r--examples/learn/01-hello.zc5
-rw-r--r--examples/learn/02-loops.zc5
-rw-r--r--examples/learn/03-do-continue.zc5
-rw-r--r--examples/learn/04-enums.zc5
-rw-r--r--examples/learn/05-small-ints.zc11
-rw-r--r--examples/learn/06-floats.zc7
-rw-r--r--examples/learn/07-bytes.zc9
-rw-r--r--examples/learn/08-byte-strings.zc9
-rw-r--r--examples/learn/09-shared.zc13
-rw-r--r--examples/learn/10-owned.zc7
-rw-r--r--examples/learn/11-tags.zc7
-rw-r--r--examples/learn/12-aliases.zc7
-rw-r--r--examples/learn/13-memdebug.out2
-rw-r--r--examples/learn/13-memdebug.zc9
-rw-r--r--examples/learn/14-include.zc10
-rw-r--r--examples/learn/15-generics.zc7
-rw-r--r--examples/learn/16-tagged-enums.zc11
-rw-r--r--examples/learn/17-switch.zc7
-rw-r--r--examples/learn/18-o3.zc11
-rw-r--r--examples/learn/19-growable.out4
-rw-r--r--examples/learn/19-growable.zc17
-rw-r--r--examples/learn/20-text-num.zc8
-rw-r--r--examples/learn/21-host.zc6
-rw-r--r--examples/learn/22-raw-x86.zc6
-rw-r--r--examples/learn/23-c-abi.zc9
-rw-r--r--examples/learn/24-backtick.zc5
-rw-r--r--examples/learn/25-closures.zc7
-rw-r--r--examples/learn/26-closure-state.out2
-rw-r--r--examples/learn/26-closure-state.zc9
-rw-r--r--examples/learn/27-namespaces.out1
-rw-r--r--examples/learn/27-namespaces.zc7
-rw-r--r--examples/learn/28-string-inference.out1
-rw-r--r--examples/learn/28-string-inference.zc8
-rw-r--r--examples/learn/29-block-comments.out1
-rw-r--r--examples/learn/29-block-comments.zc11
-rw-r--r--examples/learn/30-typed-closure.out1
-rw-r--r--examples/learn/30-typed-closure.zc12
-rw-r--r--examples/learn/31-array-algorithms.out1
-rw-r--r--examples/learn/31-array-algorithms.zc11
-rw-r--r--examples/learn/32-inferred-calls.out1
-rw-r--r--examples/learn/32-inferred-calls.zc25
-rw-r--r--examples/learn/33-const-fixed.out1
-rw-r--r--examples/learn/33-const-fixed.zc14
-rw-r--r--examples/life.zc25
-rw-r--r--examples/lists.zc37
-rw-r--r--examples/mandel.zc11
-rw-r--r--examples/opt_test.zc25
-rw-r--r--examples/primes.zc25
-rw-r--r--examples/quine.zc5
-rw-r--r--examples/repl.zc21
-rw-r--r--examples/selfpatch.zc11
-rw-r--r--examples/staged.zc27
-rw-r--r--examples/strings.zc13
-rw-r--r--examples/struct_closure_opt.zc25
-rw-r--r--examples/tree.zc23
-rw-r--r--examples/typed.zc37
-rw-r--r--examples/wiring.zc17
65 files changed, 490 insertions, 301 deletions
diff --git a/examples/bf.zc b/examples/bf.zc
index 5169b2b..71cf40d 100644
--- a/examples/bf.zc
+++ b/examples/bf.zc
@@ -1,10 +1,13 @@
+namespace;
+include rt, run;
+
// a brainfuck compiler. it turns a brainfuck program into zc source, hands
// that to the compiler that's sitting in memory, and runs the result, which on
// arm64 means native code. runs of + - < > fold into one statement each.
// give it a program after a backtick, or it runs the hello world below.
let out[30000], n, depth;
-fn emit(s) { let i = 0; while (s[i]) { out[n] = s[i]; n++; i++; } return 0; }
-fn emitn(int v) { if (v >= 10) emitn(v / 10); out[n] = '0' + v % 10; n++; return 0; }
+void emit(s) { let i = 0; while (s[i]) { out[n] = s[i]; n++; i++; } return; }
+void emitn(int v) { if (v >= 10) emitn(v / 10); out[n] = '0' + v % 10; n++; return; }
// how many times does c repeat from s[i]
int run(s, int i, int c) { int k = 0; while (s[i + k] == c) k++; return k; }
@@ -37,12 +40,12 @@ let hello = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+
let prog[20000];
fn main() {
let src = hello, k = 0, lines = 0, i = 0;
- while (!eof() && k < 19999) { let c = get_c(); if (c != 10) { prog[k] = c; k++; } }
+ while (!rt.eof() && k < 19999) { let c = rt.get_c(); if (c != 10) { prog[k] = c; k++; } }
prog[k] = 0;
if (k) src = prog;
- if (translate(src)) { put_s("unbalanced brackets\n"); return 1; }
+ if (translate(src)) { rt.put_s("unbalanced brackets\n"); return 1; }
while (out[i]) { if (out[i] == 10) lines++; i++; }
- put_s("compiled to "); put_n(lines); put_s(" lines of zc, running it:\n");
- evals(out);
+ rt.put_s("compiled to "); rt.put_n(lines); rt.put_s(" lines of zc, running it:\n");
+ run.evals(out);
return 0;
}
diff --git a/examples/cli.zc b/examples/cli.zc
index 113a0da..1ea0e6a 100644
--- a/examples/cli.zc
+++ b/examples/cli.zc
@@ -1,12 +1,15 @@
+namespace;
+include rt, std;
+
// print the length and first character of the file named by ZC_FILE
-include "src/lib/std.zc";
+include std;
fn main() {
let name[80], s, n;
- n = Host.env("ZC_FILE", name, 80);
- if (n < 0) { put_s("no file\n"); return 1; }
- s = readfile(name);
- if (!s) { put_s("can't read\n"); return 1; }
- put_n(len_w(s)); put_c(' '); put_c(s[0]); put_c(10);
- free(d*s);
+ n = std.Host.env("ZC_FILE", name, 80);
+ if (n < 0) { rt.put_s("no file\n"); return 1; }
+ s = rt.readfile(name);
+ if (!s) { rt.put_s("can't read\n"); return 1; }
+ rt.put_n(rt.len_w(s)); rt.put_c(' '); rt.put_c(s[0]); rt.put_c(10);
+ rt.free(s);
return 0;
}
diff --git a/examples/cli2.zc b/examples/cli2.zc
index 0c3de12..7bff8a1 100644
--- a/examples/cli2.zc
+++ b/examples/cli2.zc
@@ -1,29 +1,32 @@
+namespace;
+include rt, std;
+
// the command line, the environment, and capturing what a program writes.
// run it as: ./bin/zy examples/cli2.zc one two (the first is this file's path
// when zy is given one, otherwise <eval>, exactly as argv[0] is in c)
-include "src/lib/std.zc";
+include std;
-fn main() {
- put_s("argv: ");
- for (int i = 0; i < argc; i++) { put_s(argv[i]); if (i + 1 < argc) put_s(" "); }
- put_c(10);
+void main() {
+ rt.put_s("argv: ");
+ for (int i = 0; i < std.argc; i++) { rt.put_s(std.argv[i]); if (i + 1 < std.argc) rt.put_s(" "); }
+ rt.put_c(10);
// envp holds NAME=value strings, so a program can walk all of them
let n = 0;
- for (int i = 0; i < envc; i++) if (Text.starts(envp[i], "HOME=")) n = n + 1;
- put_s("HOME is set: "); put_n(n > 0); put_c(10);
+ for (int i = 0; i < std.envc; i++) if (std.Text.starts(std.envp[i], "HOME=")) n = n + 1;
+ rt.put_s("HOME is set: "); rt.put_n(n > 0); rt.put_c(10);
// the same name the old way, one lookup instead of a walk
let v[80];
- put_n(Host.env("HOME", v, 80) > 0); put_c(10);
+ rt.put_n(std.Host.env("HOME", v, 80) > 0); rt.put_c(10);
// capture what the program writes, instead of printing it. every put_c,
// put_s and put_n from here on lands in the buffer.
- let buf = capture.start();
- put_s("this goes into the buffer, not the terminal");
- put_c(10);
- buf.end(); // stops the capture and terminates the string
- put_s("captured "); put_n(len_w(buf)); put_s(" characters: ");
- put_s(buf);
- return 0;
-} \ No newline at end of file
+ let buf = std.capture.start();
+ rt.put_s("this goes into the buffer, not the terminal");
+ rt.put_c(10);
+ std.capture.end(buf); // stops the capture and terminates the string
+ rt.put_s("captured "); rt.put_n(rt.len_w(buf)); rt.put_s(" characters: ");
+ rt.put_s(buf);
+ return;
+}
diff --git a/examples/dump.zc b/examples/dump.zc
index df9a864..540471a 100644
--- a/examples/dump.zc
+++ b/examples/dump.zc
@@ -1,30 +1,33 @@
+namespace;
+include rt, run;
+
// printing any struct with no printing code: the heap knows each object's
// type, and reflection walks its fields
struct person { char* name; int age; };
struct item { char* name; int count; person* owner; };
-fn dump(p) {
- let t = typeof_obj(p), i = 0;
- if (!t) { put_s("?"); return 0; }
- tprint(t); put_s(" { ");
- while (i < tnfields(t)) {
- let ft = tftype(t, i), v = p[tfoff(t, i)];
- if (i) put_s(", ");
- put_s(tfname(t, i)); put_s(": ");
- if (tkind(ft) == TY_PTR && telem(ft) == typeof(char)) { put_c('"'); put_s(v); put_c('"'); }
- else if (tkind(ft) == TY_PTR) { if (v) dump(v); else put_s("null"); }
- else put_n(v);
+void dump(p) {
+ let t = rt.typeof_obj(p), i = 0;
+ if (!t) { rt.put_s("?"); return; }
+ run.tprint(t); rt.put_s(" { ");
+ while (i < run.tnfields(t)) {
+ let ft = run.tftype(t, i), v = p[run.tfoff(t, i)];
+ if (i) rt.put_s(", ");
+ rt.put_s(run.tfname(t, i)); rt.put_s(": ");
+ if (run.tkind(ft) == run.TY_PTR && run.telem(ft) == typeof(char)) { rt.put_c('"'); rt.put_s(v); rt.put_c('"'); }
+ else if (run.tkind(ft) == run.TY_PTR) { if (v) dump(v); else rt.put_s("null"); }
+ else rt.put_n(v);
i++;
}
- put_s(" }");
- return 0;
+ rt.put_s(" }");
+ return;
}
-fn main() {
- person* ana = new(person);
+void main() {
+ person* ana = rt.new(person);
ana.name = "ana"; ana.age = 30;
- item* lamp = new(item);
+ item* lamp = rt.new(item);
lamp.name = "lamp"; lamp.count = 3; lamp.owner = ana;
- dump(lamp); put_c(10);
- free(d*lamp);
- return 0;
+ dump(lamp); rt.put_c(10);
+ rt.free(lamp);
+ return;
}
diff --git a/examples/echo.zc b/examples/echo.zc
index 79eb877..bab0af3 100644
--- a/examples/echo.zc
+++ b/examples/echo.zc
@@ -1,2 +1,5 @@
+namespace;
+include rt;
+
// everything after the backtick is left unread, for the program itself
-fn main() { while (!eof()) put_c(get_c()); return 0; }
+void main() { while (!rt.eof()) rt.put_c(rt.get_c()); return; }
diff --git a/examples/fact.zc b/examples/fact.zc
index 1790900..ae65453 100644
--- a/examples/fact.zc
+++ b/examples/fact.zc
@@ -1,4 +1,7 @@
+namespace;
+include rt;
+
fn fact(n) { if (n < 2) return 1; return n * fact(n - 1); }
// prints in binary, like the old asm example
-fn bin(n) { if (n > 1) bin(n >> 1); put_c('0' + (n & 1)); return 0; }
-fn main() { bin(fact(10)); put_c(10); put_n(fact(10)); put_c(10); return 0; }
+void bin(n) { if (n > 1) bin(n >> 1); rt.put_c('0' + (n & 1)); return; }
+void main() { bin(fact(10)); rt.put_c(10); rt.put_n(fact(10)); rt.put_c(10); return; }
diff --git a/examples/hello.zc b/examples/hello.zc
index c0a0a97..876346d 100644
--- a/examples/hello.zc
+++ b/examples/hello.zc
@@ -1 +1,4 @@
-fn main() { put_s("hello, world!\n"); return 0; }
+namespace;
+include rt;
+
+void main() { rt.put_s("hello, world!\n"); return; }
diff --git a/examples/lang.zc b/examples/lang.zc
index 6e992b4..dc814d1 100644
--- a/examples/lang.zc
+++ b/examples/lang.zc
@@ -1,49 +1,52 @@
+namespace;
+include rt, run;
+
// growing the language from inside a program, while it compiles
// x |> f calls f(x). on a stack machine that's just "call": the value is
// already on the stack, under f's address.
-immediate fn pipe_op() { next(); add_binop("|>", 1, "c"); return 0; }
+immediate fn pipe_op() { run.next(); run.add_binop("|>", 1, "c"); return 0; }
pipe_op
// unless (c) stmt
immediate fn unless() {
let a;
- next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")"));
- emitseq(useq[0], ulen[0]); // not
- a = hole(); op(O_JZ);
- substmt();
- setlit(a, here);
+ run.next(); run.expect(run.intern("(")); 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);
+ run.substmt();
+ run.setlit(a, run.here);
return 0;
}
// assert (c): the failure message carries the line it was written on
-fn assert_fail(int line) { put_s("assertion failed on line "); put_n(line); put_c(10); halt(); return 0; }
+void assert_fail(int line) { rt.put_s("assertion failed on line "); rt.put_n(line); rt.put_c(10); rt.halt(); return; }
immediate fn assert() {
- let a, l = tline;
- next(); expect(intern("(")); plainuse(expr()); rval(); expect(intern(")"));
- emitseq(useq[0], ulen[0]); // not: the jump below skips the failure when it holds
- a = hole(); op(O_JZ);
- lit(l); callname(intern("assert_fail")); op(O_DROP);
- setlit(a, here);
+ let a, l = run.tline;
+ run.next(); run.expect(run.intern("(")); run.plainuse(run.expr()); run.rval(); run.expect(run.intern(")"));
+ run.emitseq(run.useq[0], run.ulen[0]); // not: the jump below skips the failure when it holds
+ a = run.hole(); run.op(run.O_JZ);
+ run.lit(l); run.callname(run.intern("assert_fail")); run.op(run.O_DROP);
+ run.setlit(a, run.here);
return 0;
}
// times N { body }: the body pasted N times, at compile time
immediate fn times() {
let n, b, i = 0;
- next(); n = tv; next();
- b = grab();
- while (i < n) { feed(qdup(b)); i++; }
- free(d*b);
+ run.next(); n = run.tv; run.next();
+ b = run.grab();
+ while (i < n) { run.feed(run.qdup(b)); i++; }
+ rt.free(b);
return 0;
}
fn double(x) { return x * 2; }
fn inc(x) { return x + 1; }
-fn main() {
- put_n(5 |> double |> inc |> double); put_c(10);
- unless (1 > 2) put_s("one isn't bigger than two\n");
- times 3 { put_c('*'); }
- put_c(10);
+void main() {
+ rt.put_n(5 |> double |> inc |> double); rt.put_c(10);
+ unless (1 > 2) rt.put_s("one isn't bigger than two\n");
+ times 3 { rt.put_c('*'); }
+ rt.put_c(10);
assert(double(4) == 8);
assert(inc(1) == 3);
- return 0;
+ return;
}
diff --git a/examples/learn/01-hello.zc b/examples/learn/01-hello.zc
index 10cf4bf..c102c6c 100644
--- a/examples/learn/01-hello.zc
+++ b/examples/learn/01-hello.zc
@@ -1,4 +1,5 @@
+namespace;
+include rt;
fn main() {
- put_s("hello, world!\n");
- return 0;
+ rt.put_s("hello, world!\n");
}
diff --git a/examples/learn/02-loops.zc b/examples/learn/02-loops.zc
index 832e32f..66d7ea7 100644
--- a/examples/learn/02-loops.zc
+++ b/examples/learn/02-loops.zc
@@ -1,6 +1,7 @@
+namespace;
+include rt;
fn main() {
let i = 0, n = 0;
while (i < 4) { n = n + i; i++; }
- put_n(n); put_c(10);
- return 0;
+ rt.put_n(n); rt.put_c(10);
}
diff --git a/examples/learn/03-do-continue.zc b/examples/learn/03-do-continue.zc
index 70959f4..74aa29c 100644
--- a/examples/learn/03-do-continue.zc
+++ b/examples/learn/03-do-continue.zc
@@ -1,6 +1,7 @@
+namespace;
+include rt;
fn main() {
int n = 0, i = 0;
do { i++; if (i == 2) continue; n = n + i; } while (i < 5);
- put_n(n); put_c(10);
- return 0;
+ rt.put_n(n); rt.put_c(10);
}
diff --git a/examples/learn/04-enums.zc b/examples/learn/04-enums.zc
index 8f80e3c..8b3c0dc 100644
--- a/examples/learn/04-enums.zc
+++ b/examples/learn/04-enums.zc
@@ -1,5 +1,6 @@
+namespace;
+include rt;
enum color { RED, GREEN = 5, BLUE };
fn main() {
- put_n(RED); put_c(32); put_n(GREEN); put_c(32); put_n(BLUE); put_c(10);
- return 0;
+ rt.put_n(RED); rt.put_c(32); rt.put_n(GREEN); rt.put_c(32); rt.put_n(BLUE); rt.put_c(10);
}
diff --git a/examples/learn/05-small-ints.zc b/examples/learn/05-small-ints.zc
index b288181..85555ce 100644
--- a/examples/learn/05-small-ints.zc
+++ b/examples/learn/05-small-ints.zc
@@ -1,9 +1,10 @@
+namespace;
+include rt;
fn main() {
u8 a = 250; a = a + 10;
- put_n(a); put_c(10);
- put_n(sizeof([100]u8)); put_c(10);
- u8* px = new(u8, 4096);
+ rt.put_n(a); rt.put_c(10);
+ rt.put_n(sizeof(u8[100])); rt.put_c(10);
+ u8* px = rt.new(u8, 4096);
px[10] = 300;
- put_n(px[10]); put_c(10);
- return 0;
+ rt.put_n(px[10]); rt.put_c(10);
}
diff --git a/examples/learn/06-floats.zc b/examples/learn/06-floats.zc
index 06d23fa..bc0f4b3 100644
--- a/examples/learn/06-floats.zc
+++ b/examples/learn/06-floats.zc
@@ -1,6 +1,7 @@
-fn put_f(x) { asm { x @ #1220 } return 0; }
+namespace;
+include rt;
+void put_f(float x) { asm { x @ #1220 } }
fn main() {
let a = 1.5;
- put_f(a + 2.5); put_c(10);
- return 0;
+ put_f(a + 2.5); rt.put_c(10);
}
diff --git a/examples/learn/07-bytes.zc b/examples/learn/07-bytes.zc
index 7d06282..cf07db6 100644
--- a/examples/learn/07-bytes.zc
+++ b/examples/learn/07-bytes.zc
@@ -1,7 +1,8 @@
+namespace;
+include rt;
fn main() {
let w = 0;
- st8(addr_b(&w), 0x11);
- st8(addr_b(&w) + 1, 0x22);
- put_n(ld8(addr_b(&w))); put_c(32); put_n(w); put_c(10);
- return 0;
+ rt.st8(rt.addr_b(&w), 0x11);
+ rt.st8(rt.addr_b(&w) + 1, 0x22);
+ rt.put_n(rt.ld8(rt.addr_b(&w))); rt.put_c(32); rt.put_n(w); rt.put_c(10);
}
diff --git a/examples/learn/08-byte-strings.zc b/examples/learn/08-byte-strings.zc
index 0959ceb..fb7a8d9 100644
--- a/examples/learn/08-byte-strings.zc
+++ b/examples/learn/08-byte-strings.zc
@@ -1,8 +1,9 @@
+namespace;
+include rt;
fn main() {
let name = b"zc";
let hi = b"hello, " + name;
- put_s(hi); put_c(10);
- put_n(len(hi)); put_c(32);
- put_n(s_to_n(b"40") + 2); put_c(10);
- return 0;
+ rt.put_s(hi); rt.put_c(10);
+ rt.put_n(len(hi)); rt.put_c(32);
+ rt.put_n(rt.s_to_n(b"40") + 2); rt.put_c(10);
}
diff --git a/examples/learn/09-shared.zc b/examples/learn/09-shared.zc
index ab3ca06..db5c407 100644
--- a/examples/learn/09-shared.zc
+++ b/examples/learn/09-shared.zc
@@ -1,8 +1,9 @@
+namespace;
+include rt;
fn main() {
- let tail = cons(1, 2);
- let left = cons(tail, 3);
- let right = cons(tail, 4);
- put_n(car(car(left))); put_c(32);
- put_n(car(left) == car(right)); put_c(10);
- return 0;
+ let tail = rt.cons(1, 2);
+ let left = rt.cons(tail, 3);
+ let right = rt.cons(tail, 4);
+ rt.put_n(rt.car(rt.car(left))); rt.put_c(32);
+ rt.put_n(rt.car(left) == rt.car(right)); rt.put_c(10);
}
diff --git a/examples/learn/10-owned.zc b/examples/learn/10-owned.zc
index 3aff9a4..2ee84c0 100644
--- a/examples/learn/10-owned.zc
+++ b/examples/learn/10-owned.zc
@@ -1,6 +1,7 @@
+namespace;
+include rt;
fn main() {
- int* p = new(int);
+ int* p = rt.new(int);
*p = 7;
- put_n(*p); put_c(10);
- return 0;
+ rt.put_n(*p); rt.put_c(10);
}
diff --git a/examples/learn/11-tags.zc b/examples/learn/11-tags.zc
index 08edb58..7e9f6c9 100644
--- a/examples/learn/11-tags.zc
+++ b/examples/learn/11-tags.zc
@@ -1,6 +1,7 @@
-int*.u box(int v) { int* b = new(int); *b = v; return u*b; }
+namespace;
+include rt;
+int*.u box(int v) { int* b = rt.new(int); *b = v; return b; }
fn main() {
int* p = box(4);
- put_n(*p); put_c(10);
- return 0;
+ rt.put_n(*p); rt.put_c(10);
}
diff --git a/examples/learn/12-aliases.zc b/examples/learn/12-aliases.zc
index abb39d5..341738d 100644
--- a/examples/learn/12-aliases.zc
+++ b/examples/learn/12-aliases.zc
@@ -1,8 +1,9 @@
+namespace;
+include rt;
struct node { int v; node* next; };
fn main() {
- node* a = new(node), b = new(node);
+ 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(10);
- return 0;
+ rt.put_n(c.v); rt.put_c(10);
}
diff --git a/examples/learn/13-memdebug.out b/examples/learn/13-memdebug.out
index c168a7b..f788938 100644
--- a/examples/learn/13-memdebug.out
+++ b/examples/learn/13-memdebug.out
@@ -1,2 +1,2 @@
-leak: line 4 3 words
+leak: line 6 3 words
1
diff --git a/examples/learn/13-memdebug.zc b/examples/learn/13-memdebug.zc
index 80ee0da..fd646a5 100644
--- a/examples/learn/13-memdebug.zc
+++ b/examples/learn/13-memdebug.zc
@@ -1,10 +1,11 @@
+namespace;
+include rt;
memdebug on;
int* g;
fn main() {
- int* p = new(int);
+ int* p = rt.new(int);
*p = 1;
g = d*p;
- put_n(memreport());
- put_c(10);
- return 0;
+ rt.put_n(rt.memreport());
+ rt.put_c(10);
}
diff --git a/examples/learn/14-include.zc b/examples/learn/14-include.zc
index c126389..f3be88c 100644
--- a/examples/learn/14-include.zc
+++ b/examples/learn/14-include.zc
@@ -1,7 +1,7 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
fn main() {
- let s = readfile("tests/data/hi.txt");
- put_n(len_w(s)); put_c(10);
- free(d*s);
- return 0;
+ let s = rt.readfile("tests/data/hi.txt");
+ rt.put_n(rt.len_w(s)); rt.put_c(10);
+ rt.free(s);
}
diff --git a/examples/learn/15-generics.zc b/examples/learn/15-generics.zc
index dfc4833..2da24e5 100644
--- a/examples/learn/15-generics.zc
+++ b/examples/learn/15-generics.zc
@@ -1,9 +1,10 @@
+namespace;
+include rt;
struct record<K, V> { K key; V val; };
struct point { int x; int y; };
K keyof<K, V>(record<K, V>* r) { return r.key; }
fn main() {
- record<int, point>* r = new(record<int, point>);
+ record<int, point>* r = rt.new(record<int, point>);
r.key = 9;
- put_n(keyof(r)); put_c(10);
- return 0;
+ rt.put_n(keyof(r)); rt.put_c(10);
}
diff --git a/examples/learn/16-tagged-enums.zc b/examples/learn/16-tagged-enums.zc
index ba430f4..27d23c3 100644
--- a/examples/learn/16-tagged-enums.zc
+++ b/examples/learn/16-tagged-enums.zc
@@ -1,3 +1,5 @@
+namespace;
+include rt;
enum shape { circle { int r; }, rect { int w; int h; }, dot };
int area(shape* s) {
switch (s) {
@@ -9,10 +11,9 @@ int area(shape* s) {
}
fn main() {
shape* s = shape.circle(3);
- put_n(area(s)); put_c(10);
- free(d*s);
+ rt.put_n(area(s)); rt.put_c(10);
+ rt.free(s);
shape* t = shape.rect(2, 5);
- put_n(area(t)); put_c(10);
- free(d*t);
- return 0;
+ rt.put_n(area(t)); rt.put_c(10);
+ rt.free(t);
}
diff --git a/examples/learn/17-switch.zc b/examples/learn/17-switch.zc
index f03aba9..06d5bb0 100644
--- a/examples/learn/17-switch.zc
+++ b/examples/learn/17-switch.zc
@@ -1,6 +1,7 @@
+namespace;
+include rt;
fn main() {
int k = 2;
- switch (k) { case 1: put_s("one"); break; case 2: put_s("two"); break; default: put_s("other"); }
- put_c(10);
- return 0;
+ switch (k) { case 1: rt.put_s("one"); break; case 2: rt.put_s("two"); break; default: rt.put_s("other"); }
+ rt.put_c(10);
}
diff --git a/examples/learn/18-o3.zc b/examples/learn/18-o3.zc
index cb2237a..9e591ed 100644
--- a/examples/learn/18-o3.zc
+++ b/examples/learn/18-o3.zc
@@ -1,10 +1,11 @@
-o3 int sum(fixed []int a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; }
+namespace;
+include rt;
+o3 int sum(fixed int[?] a) { int s = 0; for (int i = 0; i < len(a); i++) s += a[i]; return s; }
fn main() {
- fixed []int a = new(fixed []int, 5);
+ fixed int[?] a = rt.new(fixed int[?], 5);
for (int i = 0; i < 5; i++) a[i] = i * i;
- put_n(sum(a)); put_c(10);
+ rt.put_n(sum(a)); rt.put_c(10);
o3 int hits = 0;
o3 { for (int i = 0; i < 1000; i++) if (i % 7 == 3) hits++; }
- put_n(hits); put_c(10);
- return 0;
+ rt.put_n(hits); rt.put_c(10);
}
diff --git a/examples/learn/19-growable.out b/examples/learn/19-growable.out
index 4a9aeea..2b836a1 100644
--- a/examples/learn/19-growable.out
+++ b/examples/learn/19-growable.out
@@ -1,3 +1,5 @@
-2
+2 4
5
+4
+3 3
3
diff --git a/examples/learn/19-growable.zc b/examples/learn/19-growable.zc
index e5ed8de..39a484c 100644
--- a/examples/learn/19-growable.zc
+++ b/examples/learn/19-growable.zc
@@ -1,13 +1,18 @@
+namespace;
+include rt;
struct cnt {
int n;
static int make() { return 3; }
int get() { return this.n; }
};
fn main() {
- []int xs = new([]int);
- push(xs, 4); push(xs, 5);
- put_n(len(xs)); put_c(10);
- put_n(pop(xs)); put_c(10);
- put_n(cnt.make()); put_c(10);
- return 0;
+ int[?] xs = rt.new(int[?]);
+ xs.push(4); xs.push(5);
+ rt.put_n(xs.len()); rt.put_c(32); rt.put_n(xs.cap()); rt.put_c(10);
+ rt.put_n(xs.pop()); rt.put_c(10);
+ xs.resize(4);
+ rt.put_n(xs.len()); rt.put_c(10);
+ int[3] fixed = {1, 2, 3};
+ rt.put_n(fixed.len()); rt.put_c(32); rt.put_n(fixed.cap()); rt.put_c(10);
+ rt.put_n(cnt.make()); rt.put_c(10);
}
diff --git a/examples/learn/20-text-num.zc b/examples/learn/20-text-num.zc
index 027b721..2d2a118 100644
--- a/examples/learn/20-text-num.zc
+++ b/examples/learn/20-text-num.zc
@@ -1,6 +1,6 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
fn main() {
- put_n(Num.gcd(12, 18)); put_c(32); put_n(Num.pow(2, 10)); put_c(32); put_n(Num.isqrt(50)); put_c(10);
- put_n(Text.atoi("123") + 1); put_c(10);
- return 0;
+ rt.put_n(std.Num.gcd(12, 18)); rt.put_c(32); rt.put_n(std.Num.pow(2, 10)); rt.put_c(32); rt.put_n(std.Num.isqrt(50)); rt.put_c(10);
+ rt.put_n(std.Text.atoi("123") + 1); rt.put_c(10);
}
diff --git a/examples/learn/21-host.zc b/examples/learn/21-host.zc
index 550e747..ca77c41 100644
--- a/examples/learn/21-host.zc
+++ b/examples/learn/21-host.zc
@@ -1,5 +1,5 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
fn main() {
- put_n(Host.now() > 0); put_c(10);
- return 0;
+ rt.put_n(std.Host.now() > 0); rt.put_c(10);
}
diff --git a/examples/learn/22-raw-x86.zc b/examples/learn/22-raw-x86.zc
index e274aee..67c532a 100644
--- a/examples/learn/22-raw-x86.zc
+++ b/examples/learn/22-raw-x86.zc
@@ -1,5 +1,5 @@
-include "src/lib/std.zc";
+namespace;
+include rt, std;
fn main() {
- put_n(Host.raw(39, 0, 0, 0, 0, 0, 0) > 0); put_c(10);
- return 0;
+ rt.put_n(std.Host.raw(39, 0, 0, 0, 0, 0, 0) > 0); rt.put_c(10);
}
diff --git a/examples/learn/23-c-abi.zc b/examples/learn/23-c-abi.zc
index 3df4b75..134e926 100644
--- a/examples/learn/23-c-abi.zc
+++ b/examples/learn/23-c-abi.zc
@@ -1,12 +1,13 @@
-fn put_f(x) { asm { x @ #1220 } return 0; }
+namespace;
+include rt;
+void put_f(float x) { asm { x @ #1220 } }
extern double sqrt(double);
extern void qsort(word *base, long n, long size, void *cmp);
int cmp(int* a, int* b) { return *a - *b; }
fn main() {
let a[4];
a[0] = 5; a[1] = 3; a[2] = 9; a[3] = 1;
- put_f(sqrt(2.0)); put_c(10);
+ put_f(sqrt(2.0)); rt.put_c(10);
qsort(a, 4, 8, cfunc(cmp));
- put_n(a[0]); put_c(32); put_n(a[1]); put_c(32); put_n(a[2]); put_c(32); put_n(a[3]); put_c(10);
- return 0;
+ rt.put_n(a[0]); rt.put_c(32); rt.put_n(a[1]); rt.put_c(32); rt.put_n(a[2]); rt.put_c(32); rt.put_n(a[3]); rt.put_c(10);
}
diff --git a/examples/learn/24-backtick.zc b/examples/learn/24-backtick.zc
index 0317631..d9e014d 100644
--- a/examples/learn/24-backtick.zc
+++ b/examples/learn/24-backtick.zc
@@ -1,5 +1,6 @@
+namespace;
+include rt;
fn main() {
- put_c(get_c()); put_c(get_c()); put_c(10);
- return 0;
+ rt.put_c(rt.get_c()); rt.put_c(rt.get_c()); rt.put_c(10);
}
`abc
diff --git a/examples/learn/25-closures.zc b/examples/learn/25-closures.zc
index 72c236d..d7d6dd6 100644
--- a/examples/learn/25-closures.zc
+++ b/examples/learn/25-closures.zc
@@ -1,8 +1,9 @@
+namespace;
+include rt;
fn apply(f, x) { return f(x); }
fn main() {
let k = 10;
let add = fn(x) { return x + k; };
- put_n(add(1)); put_c(10);
- put_n(apply(add, 5)); put_c(10);
- return 0;
+ rt.put_n(add(1)); rt.put_c(10);
+ rt.put_n(apply(add, 5)); rt.put_c(10);
}
diff --git a/examples/learn/26-closure-state.out b/examples/learn/26-closure-state.out
index 33aea5d..1f1b4f4 100644
--- a/examples/learn/26-closure-state.out
+++ b/examples/learn/26-closure-state.out
@@ -1,3 +1,3 @@
109
1 5
-0
+5
diff --git a/examples/learn/26-closure-state.zc b/examples/learn/26-closure-state.zc
index f3ddf50..7d941af 100644
--- a/examples/learn/26-closure-state.zc
+++ b/examples/learn/26-closure-state.zc
@@ -1,13 +1,14 @@
+namespace;
+include rt;
fn main() {
let base = 2;
let outer = fn(x) {
let inner = fn(y) { return y + base + x; };
return inner(100);
};
- put_n(outer(7)); put_c(10);
+ rt.put_n(outer(7)); rt.put_c(10);
let count = 0;
let tick = fn(d) { count = count + d; return count; };
- put_n(tick(1)); put_c(32); put_n(tick(4)); put_c(10);
- put_n(count); put_c(10);
- return 0;
+ rt.put_n(tick(1)); rt.put_c(32); rt.put_n(tick(4)); rt.put_c(10);
+ rt.put_n(count); rt.put_c(10);
}
diff --git a/examples/learn/27-namespaces.out b/examples/learn/27-namespaces.out
new file mode 100644
index 0000000..d81cc07
--- /dev/null
+++ b/examples/learn/27-namespaces.out
@@ -0,0 +1 @@
+42
diff --git a/examples/learn/27-namespaces.zc b/examples/learn/27-namespaces.zc
new file mode 100644
index 0000000..2b2bf68
--- /dev/null
+++ b/examples/learn/27-namespaces.zc
@@ -0,0 +1,7 @@
+namespace app;
+include rt, std;
+int twice(int n) { return n * 2; }
+fn main() {
+ let text = "21";
+ rt.put_n(twice(std.Text.atoi(text))); rt.put_c(10);
+}
diff --git a/examples/learn/28-string-inference.out b/examples/learn/28-string-inference.out
new file mode 100644
index 0000000..c8f6b59
--- /dev/null
+++ b/examples/learn/28-string-inference.out
@@ -0,0 +1 @@
+11 12
diff --git a/examples/learn/28-string-inference.zc b/examples/learn/28-string-inference.zc
new file mode 100644
index 0000000..877a003
--- /dev/null
+++ b/examples/learn/28-string-inference.zc
@@ -0,0 +1,8 @@
+namespace;
+include rt, std;
+fn main() {
+ let word_text = "word string";
+ let packed_text = b"packed bytes";
+ rt.put_n(std.Text.len(word_text)); rt.put_c(32);
+ rt.put_n(std.Bytes.len(packed_text)); rt.put_c(10);
+}
diff --git a/examples/learn/29-block-comments.out b/examples/learn/29-block-comments.out
new file mode 100644
index 0000000..120cc7d
--- /dev/null
+++ b/examples/learn/29-block-comments.out
@@ -0,0 +1 @@
+16640
diff --git a/examples/learn/29-block-comments.zc b/examples/learn/29-block-comments.zc
new file mode 100644
index 0000000..a5088eb
--- /dev/null
+++ b/examples/learn/29-block-comments.zc
@@ -0,0 +1,11 @@
+namespace;
+include rt;
+
+/* adds a memory offset to an address. */
+int offset_address(int address) {
+ return address + /* offset in memory */ 0x40ff;
+}
+
+fn main() {
+ rt.put_n(offset_address(1)); rt.put_c(10);
+}
diff --git a/examples/learn/30-typed-closure.out b/examples/learn/30-typed-closure.out
new file mode 100644
index 0000000..d81cc07
--- /dev/null
+++ b/examples/learn/30-typed-closure.out
@@ -0,0 +1 @@
+42
diff --git a/examples/learn/30-typed-closure.zc b/examples/learn/30-typed-closure.zc
new file mode 100644
index 0000000..a2c090d
--- /dev/null
+++ b/examples/learn/30-typed-closure.zc
@@ -0,0 +1,12 @@
+namespace;
+include rt;
+
+word.u multiplier(int factor) {
+ let scale = fn:int(int n) { return n * factor; };
+ return u*scale;
+}
+
+fn main() {
+ let scale = multiplier(3);
+ rt.put_n(scale(14)); rt.put_c(10);
+}
diff --git a/examples/learn/31-array-algorithms.out b/examples/learn/31-array-algorithms.out
new file mode 100644
index 0000000..ec26cf8
--- /dev/null
+++ b/examples/learn/31-array-algorithms.out
@@ -0,0 +1 @@
+2 4 24
diff --git a/examples/learn/31-array-algorithms.zc b/examples/learn/31-array-algorithms.zc
new file mode 100644
index 0000000..d74bc74
--- /dev/null
+++ b/examples/learn/31-array-algorithms.zc
@@ -0,0 +1,11 @@
+namespace;
+include rt, std;
+
+fn main() {
+ int[?] values = {1, 2, 3, 4, 5};
+ let doubled = values.map(fn(e) { return e * 2; });
+ let large = doubled.filter(fn(e) { return e > 4; });
+ rt.put_n(values.find(3)); rt.put_c(32);
+ rt.put_n(values.find_if(fn(e) { return e > 4; })); rt.put_c(32);
+ rt.put_n(large.reduce(0, fn(total, e) { return total + e; })); rt.put_c(10);
+}
diff --git a/examples/learn/32-inferred-calls.out b/examples/learn/32-inferred-calls.out
new file mode 100644
index 0000000..fa9f1d8
--- /dev/null
+++ b/examples/learn/32-inferred-calls.out
@@ -0,0 +1 @@
+41 7
diff --git a/examples/learn/32-inferred-calls.zc b/examples/learn/32-inferred-calls.zc
new file mode 100644
index 0000000..295d007
--- /dev/null
+++ b/examples/learn/32-inferred-calls.zc
@@ -0,0 +1,25 @@
+namespace;
+include rt;
+
+fn layer0(n) { return seed(n); }
+fn layer1(n) { return layer0(n); }
+fn layer2(n) { return layer1(n); }
+int seed(int n) { return n; }
+fn countdown(n) {
+ if (n == 0) return seed(7);
+ return countdown(n - 1);
+}
+.u make_list(cap) {
+ let list = rt.new(cap + 1);
+ list[0] = cap;
+ return list;
+}
+.u pass_list(n) {
+ let list = make_list(n);
+ return list;
+}
+fn main() {
+ let list = pass_list(layer2(41));
+ rt.put_n(list[0]); rt.put_c(32);
+ rt.put_n(countdown(3)); rt.put_c(10);
+}
diff --git a/examples/learn/33-const-fixed.out b/examples/learn/33-const-fixed.out
new file mode 100644
index 0000000..e764420
--- /dev/null
+++ b/examples/learn/33-const-fixed.out
@@ -0,0 +1 @@
+7 2 5 8
diff --git a/examples/learn/33-const-fixed.zc b/examples/learn/33-const-fixed.zc
new file mode 100644
index 0000000..bbc85ec
--- /dev/null
+++ b/examples/learn/33-const-fixed.zc
@@ -0,0 +1,14 @@
+namespace;
+include rt;
+int first(const fixed int[2] values) { return values[0]; }
+fn main() {
+ const fixed int[2] a = {7, 8};
+ fixed const int[2] b = {2, 3};
+ fixed int[2] c = {5, 6};
+ int copy = a[0];
+ copy++;
+ rt.put_n(first(a)); rt.put_c(32);
+ rt.put_n(first(b)); rt.put_c(32);
+ rt.put_n(first(c)); rt.put_c(32);
+ rt.put_n(copy); rt.put_c(10);
+}
diff --git a/examples/life.zc b/examples/life.zc
index 6ac34e0..fdfef2b 100644
--- a/examples/life.zc
+++ b/examples/life.zc
@@ -1,10 +1,13 @@
+namespace;
+include rt;
+
// conway's life on a 10 x 20 torus, with typed 2d arrays in a struct.
// a glider walks diagonally and wraps around the edges.
const H = 10, W = 20;
-struct board { [10][20]int c; };
+struct board { int[10][20] c; };
int get(board* b, int y, int x) { return b.c[(y + H) % H][(x + W) % W]; }
-fn step(board* from, board* to) {
+void step(board* from, board* to) {
for (int y = 0; y < H; y++)
for (int x = 0; x < W; x++) {
int n = 0;
@@ -13,15 +16,15 @@ fn step(board* from, board* to) {
if (dy || dx) n += get(from, y + dy, x + dx);
to.c[y][x] = n == 3 || (n == 2 && from.c[y][x]);
}
- return 0;
+ return;
}
-fn show(board* b, int gen) {
- put_s("generation "); put_n(gen); put_c(10);
- for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) put_c(b.c[y][x] ? '#' : '.'); put_c(10); }
- return 0;
+void show(board* b, int gen) {
+ rt.put_s("generation "); rt.put_n(gen); rt.put_c(10);
+ for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) rt.put_c(b.c[y][x] ? '#' : '.'); rt.put_c(10); }
+ return;
}
-fn main() {
- board* a = new(board), b = new(board);
+void main() {
+ board* a = rt.new(board), b = rt.new(board);
a.c[0][1] = 1; a.c[1][2] = 1; a.c[2][0] = 1; a.c[2][1] = 1; a.c[2][2] = 1;
// two generations a pass, a -> b -> a: owned boards can't be swapped
// through a temporary, since the analyzer can't follow that
@@ -30,6 +33,6 @@ fn main() {
step(a, b);
step(b, a);
}
- free(d*a); free(d*b);
- return 0;
+ rt.free(a); rt.free(b);
+ return;
}
diff --git a/examples/lists.zc b/examples/lists.zc
index 02059f3..3fcad3b 100644
--- a/examples/lists.zc
+++ b/examples/lists.zc
@@ -1,32 +1,35 @@
+namespace;
+include rt;
+
// ownership in practice: a list owns its boxes. nothing here calls free;
// everything is released at the end of the block that owns it.
-.u box(v) { let b = new(1); b[0] = v; return u*b; }
-.u mklist(cap) { let l = new(cap + 1); l[0] = 0; return u*l; }
-// item m*arrives (it was given down), and goes d*on into the borrowed list
-fn push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return 0; }
-fn show(.m l) {
+.u box(v) { let b = rt.new(1); b[0] = v; return b; }
+.u mklist(cap) { let l = rt.new(cap + 1); l[0] = 0; return l; }
+// item arrives as an owned parameter and moves into the borrowed list
+void push(.m l, .d item) { l[l[0] + 1] = d*item; l[0] = l[0] + 1; return; }
+void show(.m l) {
let i = 1;
- put_c('[');
- while (i <= l[0]) { if (i > 1) put_c(' '); put_n(l[i][0]); i++; }
- put_c(']');
- return 0;
+ rt.put_c('[');
+ while (i <= l[0]) { if (i > 1) rt.put_c(' '); rt.put_n(l[i][0]); i++; }
+ rt.put_c(']');
+ return;
}
.u squares(n) {
let l = mklist(n), i = 0;
while (i < n) {
let b = box(i * i);
- push(l, d*b);
+ push(l, b);
i++;
}
- return u*l;
+ return l;
}
-fn main() {
- let before = live_objects();
+void main() {
+ let before = rt.live_objects();
{
let l = squares(6);
- show(l); put_c(10);
- put_s("live: "); put_n(live_objects() - before); put_c(10);
+ show(l); rt.put_c(10);
+ rt.put_s("live: "); rt.put_n(rt.live_objects() - before); rt.put_c(10);
}
- put_s("after the block: "); put_n(live_objects() - before); put_c(10);
- return 0;
+ rt.put_s("after the block: "); rt.put_n(rt.live_objects() - before); rt.put_c(10);
+ return;
}
diff --git a/examples/mandel.zc b/examples/mandel.zc
index 0a8f69e..b389d40 100644
--- a/examples/mandel.zc
+++ b/examples/mandel.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// the mandelbrot set in 16.16 fixed point. a word is 64 bits, so the product
// fits and the point sits 16 bits down. the jit inlines it as a multiply and a shift.
enhance fmul(a, b) micro "a = mul a b; a = sar a 16";
@@ -16,17 +19,17 @@ int escape(int cx, int cy) {
}
return MAXIT;
}
-fn main() {
+void main() {
int row = 0;
while (row < H) {
int col = 0, cy = (row * 2400 / (H - 1) - 1200) * ONE / 1000;
while (col < W) {
int cx = (col * 3200 / (W - 1) - 2200) * ONE / 1000, it = escape(cx, cy);
- put_c(it == MAXIT ? '@' : shades[it * 11 / MAXIT]);
+ rt.put_c(it == MAXIT ? '@' : shades[it * 11 / MAXIT]);
col++;
}
- put_c(10);
+ rt.put_c(10);
row++;
}
- return 0;
+ return;
}
diff --git a/examples/opt_test.zc b/examples/opt_test.zc
index c581283..e310690 100644
--- a/examples/opt_test.zc
+++ b/examples/opt_test.zc
@@ -1,8 +1,11 @@
+namespace;
+include rt;
+
// a tour of the compiler's optimization hints. the program is valid and runs;
// the hints only show up in the editor (or the lsp cli), never in a normal build.
// each function below triggers one of them.
-fn sink(.d p) { free(d*p); return 0; }
+void sink(.d p) { rt.free(p); return; }
// a variable that is written and never read
fn dead() {
@@ -26,9 +29,9 @@ fn magic(n) { return n + 1234; }
fn looping() {
let i = 0;
while (i < 3) {
- let buf = new(10);
+ let buf = rt.new(10);
buf[0] = i;
- sink(d*buf);
+ sink(buf);
i++;
}
return i;
@@ -36,19 +39,19 @@ fn looping() {
// a small buffer that never leaves the function can live on the stack
fn scratch() {
- let buf = new(8);
+ let buf = rt.new(8);
buf[0] = 7;
return buf[0];
}
// a consuming call takes the object after its allocation
-fn handoff() {
- let tmp = new(4);
- sink(d*tmp);
- return 0;
+void handoff() {
+ let tmp = rt.new(4);
+ sink(tmp);
+ return;
}
-fn main() {
- put_n(dead() + constant() + shifty(2) + magic(0) + looping() + scratch() + handoff()); put_c(10);
- return 0;
+void main() {
+ rt.put_n(dead() + constant() + shifty(2) + magic(0) + looping() + scratch()); handoff(); rt.put_c(10);
+ return;
}
diff --git a/examples/primes.zc b/examples/primes.zc
index 43ae2e8..dd595d7 100644
--- a/examples/primes.zc
+++ b/examples/primes.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// primes below 60000: an o3 sieve over a fixed array, the primes
// gathered into a growable one, then a few questions asked of them.
// with ZYTRACE=1 the o3 lines show each region being lifted and compiled.
// marks the composites; f[i] ends up 1 for every prime i
-o3 int sieve(fixed []int f) {
+o3 int sieve(fixed int[?] f) {
int n = len(f), c = 0;
for (int i = 2; i < n; i++) f[i] = 1;
for (int i = 2; i * i < n; i++)
@@ -12,24 +15,24 @@ o3 int sieve(fixed []int f) {
return c;
}
// the largest gap between neighbours, and where it starts
-o3 int gap(fixed []int f, int* at) {
+o3 int gap(fixed int[?] f, int* at) {
int n = len(f), last = 2, best = 0, where = 0;
for (int i = 3; i < n; i++)
if (f[i]) { if (i - last > best) { best = i - last; where = last; } last = i; }
*at = where;
return best;
}
-fn main() {
- fixed []int f = new(fixed []int, 60000);
- []int ps = new([]int);
+void main() {
+ fixed int[?] f = rt.new(fixed int[?], 60000);
+ int[?] ps = rt.new(int[?]);
int c = sieve(f), at = 0, twins = 0;
for (int i = 2; i < len(f); i++) if (f[i]) push(ps, i);
o3 { for (int k = 1; k < len(ps); k++) if (ps[k] - ps[k - 1] == 2) twins++; }
- put_s("primes below 60000: "); put_n(c); put_c(10);
- put_s("the last five:"); for (int k = len(ps) - 5; k < len(ps); k++) { put_c(' '); put_n(ps[k]); } put_c(10);
- put_s("twin pairs: "); put_n(twins); put_c(10);
+ rt.put_s("primes below 60000: "); rt.put_n(c); rt.put_c(10);
+ rt.put_s("the last five:"); for (int k = len(ps) - 5; k < len(ps); k++) { rt.put_c(' '); rt.put_n(ps[k]); } rt.put_c(10);
+ rt.put_s("twin pairs: "); rt.put_n(twins); rt.put_c(10);
int g = gap(f, &at);
- put_s("widest gap: "); put_n(g); put_s(", after "); put_n(at); put_c(10);
- free(d*f); free(d*ps);
- return 0;
+ rt.put_s("widest gap: "); rt.put_n(g); rt.put_s(", after "); rt.put_n(at); rt.put_c(10);
+ rt.free(f); rt.free(ps);
+ return;
}
diff --git a/examples/quine.zc b/examples/quine.zc
index 9c69e69..58a5351 100644
--- a/examples/quine.zc
+++ b/examples/quine.zc
@@ -1 +1,4 @@
-let s="let s=#;fn main(){let i=0;while(s[i]){if(s[i]==35){put_c(34);put_s(s);put_c(34);}else put_c(s[i]);i++;}put_c(10);return 0;}";fn main(){let i=0;while(s[i]){if(s[i]==35){put_c(34);put_s(s);put_c(34);}else put_c(s[i]);i++;}put_c(10);return 0;}
+namespace;
+include rt;
+
+let s="let s=#;void main(){let i=0;while(s[i]){if(s[i]==35){put_c(34);put_s(s);put_c(34);}else put_c(s[i]);i++;}put_c(10);return;}";void main(){let i=0;while(s[i]){if(s[i]==35){rt.put_c(34);rt.put_s(s);rt.put_c(34);}else rt.put_c(s[i]);i++;}rt.put_c(10);return;}
diff --git a/examples/repl.zc b/examples/repl.zc
index 235063f..bff96c3 100644
--- a/examples/repl.zc
+++ b/examples/repl.zc
@@ -1,25 +1,28 @@
+namespace;
+include rt, run;
+
// a repl on the resident compiler: each backtick-separated chunk of input is
// compiled as a function body and run. definitions (fn ...) can be loaded too:
// a chunk that starts with "fn" goes through load instead of eval.
let buf[4000];
fn readchunk() {
let n = 0, c;
- while (!eof()) {
- c = get_c();
+ while (!rt.eof()) {
+ c = rt.get_c();
if (c == 96) break;
if (n < 3999) { buf[n] = c; n++; }
}
buf[n] = 0;
return n;
}
-fn main() {
+void main() {
let q, i;
- while (!eof()) {
+ while (!rt.eof()) {
readchunk();
- q = tokens(buf);
- if (q[0] && q[1] == T_ID && q[2] == intern("fn")) load(q);
- else eval(q);
- free(d*q);
+ q = run.tokens(buf);
+ if (q[0] && q[1] == run.T_ID && q[2] == run.intern("fn")) run.load(q);
+ else run.eval(q);
+ rt.free(q);
}
- return 0;
+ return;
}
diff --git a/examples/selfpatch.zc b/examples/selfpatch.zc
index e3f821d..56d7767 100644
--- a/examples/selfpatch.zc
+++ b/examples/selfpatch.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt;
+
// code is data: find the literal 'A' inside f's compiled words and rewrite it.
// on the jit the store lands on translated code, which gets dropped and
// retranslated on the next call.
-fn f() { put_c('A'); return 0; }
+void f() { rt.put_c('A'); return; }
fn litw(v) { return v + v + 1; } // how the vm encodes a literal push
-fn main() {
+void main() {
let p = f;
f();
while (*p != litw('A')) p++;
@@ -11,6 +14,6 @@ fn main() {
f();
*p = litw('C');
f();
- put_c(10);
- return 0;
+ rt.put_c(10);
+ return;
}
diff --git a/examples/staged.zc b/examples/staged.zc
index a180ae3..23453f9 100644
--- a/examples/staged.zc
+++ b/examples/staged.zc
@@ -1,9 +1,12 @@
+namespace;
+include rt, run;
+
// staged code: a program writes a specialized function as source, compiles it
// while running, and calls it. here, polynomials with their coefficients baked
// in as constants, so there's no loop and no array left at runtime.
let buf[2000], n;
-fn put(s) { let i = 0; while (s[i]) { buf[n] = s[i]; n++; i++; } return 0; }
-fn putnum(int v) { if (v >= 10) putnum(v / 10); buf[n] = '0' + v % 10; n++; return 0; }
+void put(s) { let i = 0; while (s[i]) { buf[n] = s[i]; n++; i++; } return; }
+void putnum(int v) { if (v >= 10) putnum(v / 10); buf[n] = '0' + v % 10; n++; return; }
// coefficients c[0] + c[1] x + ... in horner form: ((c3 x + c2) x + c1) x + c0
fn specialize(int* c, int deg) {
@@ -19,15 +22,15 @@ fn specialize(int* c, int deg) {
buf[n] = 0;
return buf;
}
-fn main() {
- [4]int c;
+void main() {
+ int[4] c;
c[0] = 7; c[1] = 0 - 3; c[2] = 0; c[3] = 2; // 2x^3 - 3x + 7
- let src = specialize(c, 3), q = tokens(src);
- put_s(src); put_c(10);
- load(q); // compiled now, into the running program
- free(d*q);
- let f = sval[lookups("poly")]; // and found by name in the compiler's symbol table
- for (int x = 0 - 2; x <= 3; x++) { put_n(f(x)); put_c(' '); }
- put_c(10);
- return 0;
+ let src = specialize(c, 3), q = run.tokens(src);
+ rt.put_s(src); rt.put_c(10);
+ run.load(q); // compiled now, into the running program
+ rt.free(q);
+ let f = run.sval[run.lookups("poly")]; // and found by name in the compiler's symbol table
+ for (int x = 0 - 2; x <= 3; x++) { rt.put_n(f(x)); rt.put_c(' '); }
+ rt.put_c(10);
+ return;
}
diff --git a/examples/strings.zc b/examples/strings.zc
index 0959ceb..7101996 100644
--- a/examples/strings.zc
+++ b/examples/strings.zc
@@ -1,8 +1,11 @@
-fn main() {
+namespace;
+include rt;
+
+void main() {
let name = b"zc";
let hi = b"hello, " + name;
- put_s(hi); put_c(10);
- put_n(len(hi)); put_c(32);
- put_n(s_to_n(b"40") + 2); put_c(10);
- return 0;
+ rt.put_s(hi); rt.put_c(10);
+ rt.put_n(len(hi)); rt.put_c(32);
+ rt.put_n(rt.s_to_n(b"40") + 2); rt.put_c(10);
+ return;
}
diff --git a/examples/struct_closure_opt.zc b/examples/struct_closure_opt.zc
index 67315bf..254ff07 100644
--- a/examples/struct_closure_opt.zc
+++ b/examples/struct_closure_opt.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// struct methods, closures and ownership in one file, written so the
// compiler's hints have something to say about it. it runs as it is.
@@ -12,36 +15,36 @@ struct point {
}
}
-fn sink(.d p) { free(d*p); return 0; }
+void sink(.d p) { rt.free(p); return; }
fn features() {
- // a closure copies the variables it uses when it is made
+ // a closure shares the variables it captures
let base = 100;
let add = fn(a, b) { return a + b + base; };
let total = add(10, 20);
- let p1 = new(point);
+ let p1 = rt.new(point);
p1.x = 5; p1.y = 12;
- let p2 = new(point);
+ let p2 = rt.new(point);
p2.x = 0; p2.y = 0;
// made and given away on the next line, so it never needed a name
- let tmp = new(2);
- sink(d*tmp);
+ let tmp = rt.new(2);
+ sink(tmp);
// allocated again on every pass of the loop
let i = 0;
while (i < 3) {
- let scratch = new(10);
+ let scratch = rt.new(10);
scratch[0] = i;
- sink(d*scratch);
+ sink(scratch);
i++;
}
return total + p1.dist(p2);
}
-fn main() {
- put_n(features()); put_c(10);
- return 0;
+void main() {
+ rt.put_n(features()); rt.put_c(10);
+ return;
}
diff --git a/examples/tree.zc b/examples/tree.zc
index 9ef515e..4f304de 100644
--- a/examples/tree.zc
+++ b/examples/tree.zc
@@ -1,26 +1,29 @@
+namespace;
+include rt;
+
// a binary search tree where every node owns its children. there's no free
// anywhere: when the root's block ends, the whole tree goes with it.
struct node { int v; node* left, right; };
-node*.u leaf(int v) { node* n = new(node); n.v = v; return u*n; }
+node*.u leaf(int v) { node* n = rt.new(node); n.v = v; return n; }
// n is borrowed; storing a new leaf into it makes n the leaf's owner
-fn insert(node*.m n, int v) {
+void insert(node*.m n, int v) {
if (v < n.v) { if (n.left) insert(n.left, v); else n.left = leaf(v); }
else { if (n.right) insert(n.right, v); else n.right = leaf(v); }
- return 0;
+ return;
}
-fn walk(node* n) { if (!n) return 0; walk(n.left); put_n(n.v); put_c(' '); walk(n.right); return 0; }
+void walk(node* n) { if (!n) return; walk(n.left); rt.put_n(n.v); rt.put_c(' '); walk(n.right); return; }
int height(node* n) { if (!n) return 0; int l = height(n.left), r = height(n.right); return 1 + (l > r ? l : r); }
-fn main() {
- let before = live_objects();
+void main() {
+ let before = rt.live_objects();
{
node* root = leaf(50);
int x = 7;
for (int i = 0; i < 30; i++) { x = (x * 37 + 11) % 100; insert(root, x); }
- walk(root); put_c(10);
- put_s("height "); put_n(height(root)); put_s(", live objects "); put_n(live_objects() - before); put_c(10);
+ walk(root); rt.put_c(10);
+ rt.put_s("height "); rt.put_n(height(root)); rt.put_s(", live objects "); rt.put_n(rt.live_objects() - before); rt.put_c(10);
}
- put_s("after the block: "); put_n(live_objects() - before); put_c(10);
- return 0;
+ rt.put_s("after the block: "); rt.put_n(rt.live_objects() - before); rt.put_c(10);
+ return;
}
diff --git a/examples/typed.zc b/examples/typed.zc
index 44aff88..340b6d2 100644
--- a/examples/typed.zc
+++ b/examples/typed.zc
@@ -1,51 +1,54 @@
+namespace;
+include rt, run;
+
// types: structs, a generic container, and looking at it all through reflection.
-// a pointer type put_s its star after the type, like c: int*, point*, vec<T>*.
+// a pointer type has its star after the type, like c: int*, point*, vec<T>*.
typecheck on;
struct point { int x, y; };
struct vec<T> { int len, cap; T* items; };
vec<T>*.u mkvec<T>(int cap) {
- vec<T>* v = new(vec<T>);
+ vec<T>* v = rt.new(vec<T>);
v.cap = cap;
- v.items = new(T, cap);
- return u*v;
+ v.items = rt.new(T, cap);
+ return v;
}
// x is given away (.d): the vector's memory holds it from now on, and the
// collector looks after it
bool push<T>(vec<T>* v, T.d x) {
- if (v.len == v.cap) { free(d*x); return 0; }
+ if (v.len == v.cap) { rt.free(x); return 0; }
v.items[v.len] = d*x;
v.len++;
return 1;
}
-fn show(word t) {
+void show(word t) {
let i = 0;
- tprint(t); put_s(" is "); put_n(tsize(t)); put_s(" words: ");
- while (i < tnfields(t)) {
- if (i) put_s(", ");
- put_s(tfname(t, i)); put_s(" "); tprint(tftype(t, i));
+ run.tprint(t); rt.put_s(" is "); rt.put_n(run.tsize(t)); rt.put_s(" words: ");
+ while (i < run.tnfields(t)) {
+ if (i) rt.put_s(", ");
+ rt.put_s(run.tfname(t, i)); rt.put_s(" "); run.tprint(run.tftype(t, i));
i++;
}
- put_c(10);
- return 0;
+ rt.put_c(10);
+ return;
}
int main() {
vec<point*>* v = mkvec<point*>(4);
int i = 0;
while (i < 3) {
- point* p = new(point);
+ point* p = rt.new(point);
p.x = i; p.y = i * i;
- push(v, d*p);
+ push(v, p);
i++;
}
- put_s("last: "); put_n(v.items[2].y); put_c(10);
+ rt.put_s("last: "); rt.put_n(v.items[2].y); rt.put_c(10);
show(typeof(point));
show(typeof(*v));
- put_s("push is "); tprint(sigof(push)); put_c(10);
+ rt.put_s("push is "); run.tprint(run.sigof(push)); rt.put_c(10);
// each set of type arguments gets its own copy of mkvec, so what it stamped is vec<point*>
- put_s("the heap says v is a "); tprint(typeof_obj(v)); put_s(", and v.items[0] is a "); tprint(typeof_obj(v.items[0])); put_c(10);
+ rt.put_s("the heap says v is a "); run.tprint(rt.typeof_obj(v)); rt.put_s(", and v.items[0] is a "); run.tprint(rt.typeof_obj(v.items[0])); rt.put_c(10);
return 0;
}
diff --git a/examples/wiring.zc b/examples/wiring.zc
index d10ecf5..329659b 100644
--- a/examples/wiring.zc
+++ b/examples/wiring.zc
@@ -1,3 +1,6 @@
+namespace;
+include rt;
+
// virtual enhancements: custom opcodes wired into the cpu while compiling.
// the recipes run through the core's optimizer; the jit inlines the result.
enhance popcount(x) micro
@@ -8,11 +11,11 @@ enhance div10(x) micro "x = udiv x 10"; // becomes a multiply-high, no divide
enhance hypot2(a, b) vm { 0 $ * ~ 0 $ * + }; // lifted from vm code
enhance 2 minmax(a, b) micro "r2 = min a b; r1 = max a b; r0 = r2";
let lo, hi;
-fn main() {
- put_n(popcount(0xff00ff)); put_c(' ');
- put_n(div10(12345)); put_c(' ');
- put_n(hypot2(3, 4)); put_c(' ');
+void main() {
+ rt.put_n(popcount(0xff00ff)); rt.put_c(' ');
+ rt.put_n(div10(12345)); rt.put_c(' ');
+ rt.put_n(hypot2(3, 4)); rt.put_c(' ');
asm { 9 4 minmax hi ! lo ! }
- put_n(lo); put_c('/'); put_n(hi); put_c(10);
- return 0;
-} \ No newline at end of file
+ rt.put_n(lo); rt.put_c('/'); rt.put_n(hi); rt.put_c(10);
+ return;
+}