aboutsummaryrefslogtreecommitdiff
path: root/tests/spec/compiler_contracts.json
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/spec/compiler_contracts.json
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/spec/compiler_contracts.json')
-rw-r--r--tests/spec/compiler_contracts.json542
1 files changed, 542 insertions, 0 deletions
diff --git a/tests/spec/compiler_contracts.json b/tests/spec/compiler_contracts.json
new file mode 100644
index 0000000..69b2781
--- /dev/null
+++ b/tests/spec/compiler_contracts.json
@@ -0,0 +1,542 @@
+[
+ {
+ "group": "modules",
+ "name": "explicit runtime export",
+ "accept": true,
+ "source": "include rt; fn main() { rt.put_n(7); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "no implicit runtime",
+ "accept": false,
+ "source": "fn main() { put_n(7); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "runtime needs include",
+ "accept": false,
+ "source": "fn main() { rt.put_n(7); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "import does not unqualify runtime",
+ "accept": false,
+ "source": "include rt; fn main() { put_n(7); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "explicit compiler export",
+ "accept": true,
+ "source": "include run; fn main() { run.evals(\"return 0;\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "compiler needs include",
+ "accept": false,
+ "source": "fn main() { run.evals(\"return 0;\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "no bare compiler exports",
+ "accept": false,
+ "source": "include run; fn main() { evals(\"return 0;\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "core reserved for vm",
+ "accept": false,
+ "source": "include core; fn main() { core.evals(\"return 0;\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "explicit vm export",
+ "accept": true,
+ "source": "include core; fn main() { return core.syscall(9, 0, 0, 0) > 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "server needs include",
+ "accept": false,
+ "source": "fn main() { return lsp.hid('a'); }"
+ },
+ {
+ "group": "modules",
+ "name": "unknown module",
+ "accept": false,
+ "source": "include imaginary; fn main() { return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "unknown export",
+ "accept": false,
+ "source": "include rt; fn main() { return rt.imaginary(); }"
+ },
+ {
+ "group": "modules",
+ "name": "no import bypass with unchecked",
+ "accept": false,
+ "source": "unchecked fn main() { put_s(\"hi\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "runtime allocator remains typed",
+ "accept": true,
+ "source": "include rt; fn main() { let p = rt.new(int, 3); p[0] = 7; rt.put_n(p[0]); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "explicit standard library",
+ "accept": true,
+ "source": "include std; include rt; fn main() { rt.put_n(std.Text.atoi(\"4\")); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "dependency imports do not leak",
+ "accept": false,
+ "source": "include std; fn main() { rt.put_n(std.Text.atoi(\"4\")); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "namespace alias does not shadow local",
+ "accept": true,
+ "source": "fn main() { int rt = 7; return rt; }"
+ },
+ {
+ "group": "strings",
+ "name": "word string parameter",
+ "accept": true,
+ "source": "char* echo(char* s) { return s; } fn main() { let s = echo(\"hi\"); return s[0]; }"
+ },
+ {
+ "group": "strings",
+ "name": "packed string parameter",
+ "accept": true,
+ "source": "bstr echo(bstr s) { return s; } fn main() { let s = echo(b\"hi\"); return s[0]; }"
+ },
+ {
+ "group": "strings",
+ "name": "packed and word strings are distinct",
+ "accept": false,
+ "source": "typecheck on; char* echo(char* s) { return s; } fn main() { return echo(b\"hi\")[0]; }"
+ },
+ {
+ "group": "strings",
+ "name": "word and packed strings are distinct",
+ "accept": false,
+ "source": "typecheck on; bstr echo(bstr s) { return s; } fn main() { return echo(\"hi\")[0]; }"
+ },
+ {
+ "group": "strings",
+ "name": "string is not raw word",
+ "accept": false,
+ "source": "typecheck on; word identity(word n) { return n; } fn main() { return identity(b\"hi\"); }"
+ },
+ {
+ "group": "strings",
+ "name": "grouped string inference",
+ "accept": true,
+ "source": "fn main() { let a = \"hi\", b = b\"hi\"; return a[0] + b[0]; }"
+ },
+ {
+ "group": "strings",
+ "name": "inferred word string remains assignable",
+ "accept": true,
+ "source": "include rt; typecheck on; fn main() { let s = \"hi\"; s = \"ok\"; rt.put_n(s[1]); return 0; }",
+ "output": "107"
+ },
+ {
+ "group": "strings",
+ "name": "inferred packed string remains assignable",
+ "accept": true,
+ "source": "include rt; typecheck on; fn main() { let s = b\"hi\"; s = b\"ok\"; rt.put_n(s[1]); return 0; }",
+ "output": "107"
+ },
+ {
+ "group": "strings",
+ "name": "inferred string types reject cross-assignment",
+ "accept": false,
+ "source": "typecheck on; fn main() { let s = \"hi\"; s = b\"ok\"; return 0; }"
+ },
+ {
+ "group": "ownership",
+ "name": "global receives local owner",
+ "accept": true,
+ "source": "include rt; int* saved; fn main() { let p = rt.new(int); p[0] = 7; saved = p; return saved[0]; }"
+ },
+ {
+ "group": "ownership",
+ "name": "global source is consumed",
+ "accept": false,
+ "source": "include rt; int* saved; fn main() { let p = rt.new(int); saved = p; return p[0]; }"
+ },
+ {
+ "group": "ownership",
+ "name": "borrowed source cannot transfer",
+ "accept": false,
+ "source": "int* saved; fn store(int*.m p) { saved = p; } fn main() { return 0; }"
+ },
+ {
+ "group": "ownership",
+ "name": "consumed source cannot transfer twice",
+ "accept": false,
+ "source": "include rt; int* a, b; fn main() { let p = rt.new(int); a = p; b = p; return 0; }"
+ },
+ {
+ "group": "ownership",
+ "name": "temporary borrowed result cleanup",
+ "accept": true,
+ "source": "include rt; char*.u make() { let p = rt.new(char, 2); p[0] = 120; p[1] = 0; return p; } fn main() { rt.put_s(make()); return 0; }"
+ },
+ {
+ "group": "closure",
+ "name": "explicit integer result",
+ "accept": true,
+ "source": "fn main() { let double = fn:int(int a) { return a * 2; }; return double(4); }"
+ },
+ {
+ "group": "closure",
+ "name": "incompatible explicit result",
+ "accept": false,
+ "source": "typecheck on; fn main() { let f = fn:int() { return \"hi\"; }; return f(); }"
+ },
+ {
+ "group": "closure",
+ "name": "captured state is shared",
+ "accept": true,
+ "source": "include rt; fn main() { int n = 0; let f = fn:int() { n++; return n; }; rt.put_n(f()); rt.put_n(f()); rt.put_n(n); return 0; }",
+ "output": "122"
+ },
+ {
+ "group": "stdlib",
+ "name": "word string search",
+ "accept": true,
+ "source": "include std; fn main() { return std.Text.ends(\"abcd\", \"cd\"); }"
+ },
+ {
+ "group": "stdlib",
+ "name": "packed string search",
+ "accept": true,
+ "source": "include std; fn main() { return std.Bytes.ends(b\"abcd\", b\"cd\"); }"
+ },
+ {
+ "group": "stdlib",
+ "name": "word string trimming",
+ "accept": true,
+ "source": "include std; include rt; fn main() { rt.put_s(std.Text.trim(\" hi \")); return 0; }",
+ "output": "hi"
+ },
+ {
+ "group": "stdlib",
+ "name": "word string substring",
+ "accept": true,
+ "source": "include std; include rt; fn main() { rt.put_s(std.Text.substr(\"abcd\", 1, 2)); return 0; }",
+ "output": "bc"
+ },
+ {
+ "group": "stdlib",
+ "name": "negative substring bounds",
+ "accept": true,
+ "source": "include std; fn main() { return std.Text.substr(\"abcd\", -1, 2) == 0; }"
+ },
+ {
+ "group": "runtime",
+ "name": "word copying borrowed buffers",
+ "accept": true,
+ "source": "include rt; fn main() { int a[2] = {1, 2}, b[2]; rt.copy_w(b, a, 2); return b[1]; }"
+ },
+ {
+ "group": "runtime",
+ "name": "explicit free consumes owner",
+ "accept": false,
+ "source": "include rt; fn main() { let p = rt.new(int); rt.free(p); return p[0]; }"
+ },
+ {
+ "group": "runtime",
+ "name": "borrow cannot free owner",
+ "accept": false,
+ "source": "include rt; fn f(int*.m p) { rt.free(p); } fn main() { return 0; }"
+ },
+ {
+ "group": "runtime",
+ "name": "growable array owns transferred child",
+ "accept": true,
+ "source": "include rt; fn main() { let a = rt.new(int*[?]); let p = rt.new(int); p[0] = 7; push(a, p); return a[0][0]; }"
+ },
+ {
+ "group": "runtime",
+ "name": "transferred child cannot outlive array",
+ "accept": false,
+ "source": "include rt; int* saved; fn main() { let a = rt.new(int*[?]); let p = rt.new(int); push(a, p); saved = p; return 0; }"
+ },
+ {
+ "group": "runtime",
+ "name": "collection retains reachable objects",
+ "accept": true,
+ "source": "include rt; fn main() { let p = rt.new(int); p[0] = 7; rt.gc(); return p[0]; }"
+ },
+ {
+ "group": "runtime",
+ "name": "zero-sized copy is safe",
+ "accept": true,
+ "source": "include rt; fn main() { return rt.copy_w(0, 0, 0); }"
+ },
+ {
+ "group": "arguments",
+ "name": "explicit discard owns cleanup",
+ "accept": true,
+ "source": "include rt; fn ignore(int*.d _) { return 0; } fn main() { let before = rt.live_objects(); ignore(rt.new(int)); rt.put_n(rt.live_objects() - before); return 0; }",
+ "output": "0"
+ },
+ {
+ "group": "arguments",
+ "name": "discard does not disable arity checking",
+ "accept": false,
+ "source": "fn ignore(int _, int _) { return 0; } fn main() { return ignore(1); }"
+ },
+ {
+ "group": "arguments",
+ "name": "duplicate discard names are permitted",
+ "accept": true,
+ "source": "fn ignore(int _, int _) { return 0; } fn main() { return ignore(1, 2); }"
+ },
+ {
+ "group": "modules",
+ "name": "multiple explicit imports",
+ "accept": true,
+ "source": "include rt, run, core; fn main() { rt.put_n(core.syscall(9, 0, 0, 0) > 0); run.evals(\"return 0;\"); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "repeated imports are idempotent",
+ "accept": true,
+ "source": "include rt, rt, run; include rt; fn main() { rt.put_n(1); return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "unknown import within list",
+ "accept": false,
+ "source": "include rt, imaginary, run; fn main() { return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "missing entry within list",
+ "accept": false,
+ "source": "include rt,,run; fn main() { return 0; }"
+ },
+ {
+ "group": "callbacks",
+ "name": "explicit borrowed callback parameter",
+ "accept": true,
+ "source": "include rt; int first(int*.m p) { return p[0]; } fn main() { int(int*.m) f = first; return f(rt.new(1)); }"
+ },
+ {
+ "group": "callbacks",
+ "name": "borrowed callback cannot consume source",
+ "accept": false,
+ "source": "include rt; fn bad(int*.m p) { rt.free(p); } fn main() { int(int*.m) f = bad; return 0; }"
+ },
+ {
+ "group": "modules",
+ "name": "local struct shadows module name",
+ "accept": true,
+ "source": "struct point { int x; }; fn main() { point rt; rt.x = 7; return rt.x; }"
+ },
+ {
+ "group": "strings",
+ "name": "capture returns a char string",
+ "accept": true,
+ "source": "include rt, std; typecheck on; fn main() { char* s = std.capture.start(); rt.put_s(\"hi\"); s = std.capture.end(s); rt.put_s(s); return 0; }",
+ "output": "hi"
+ },
+ {
+ "group": "modules",
+ "name": "boot export needs its namespace",
+ "accept": false,
+ "source": "fn main() { return start; }"
+ },
+ {
+ "group": "strings",
+ "name": "inferred packed result stays indexable",
+ "accept": true,
+ "source": "include rt; fn text() { return b\"hi\"; } fn main() { let s = text(); rt.put_n(s[0]); return 0; }",
+ "output": "104"
+ },
+ {
+ "group": "strings",
+ "name": "typed argument with inferred packed return",
+ "accept": true,
+ "source": "include rt; typecheck on; fn echo(bstr s) { return s; } fn main() { let s = echo(b\"hi\"); rt.put_n(s[1]); return 0; }",
+ "output": "105"
+ },
+ {
+ "group": "strings",
+ "name": "inferred word string result stays indexable",
+ "accept": true,
+ "source": "include rt; fn text() { return \"hi\"; } fn main() { let s = text(); rt.put_n(s[0]); return 0; }",
+ "output": "104"
+ },
+ {
+ "group": "enums",
+ "name": "tagged enum constructors and repeated discard fields",
+ "accept": true,
+ "source": "include rt; enum pair { item { int x; int y; }, other }; fn main() { let p = pair.item(1, 2); switch(p) { case item(_, _): rt.put_n(p.item_x + p.item_y); case _: rt.put_n(0); } rt.free(d*p); return 0; }",
+ "output": "3"
+ },
+ {
+ "group": "modules",
+ "name": "icon exports are loaded by explicit include",
+ "accept": true,
+ "source": "include rt, run, icon; fn main() { let q = run.tokens(\"return 7;\"); let frame = icon.begin(q); icon.resume(frame, 4); int result = icon.result(frame); rt.put_n(result); icon.close(d*frame); return 0; }",
+ "output": "7"
+ },
+ {
+ "group": "modules",
+ "name": "icon access requires include",
+ "accept": false,
+ "source": "include rt, run; fn main() { return icon.error(); }"
+ },
+ {
+ "group": "modules",
+ "name": "icon implementation names remain private",
+ "accept": false,
+ "source": "include rt, run, icon; fn main() { return icon_value(0, 0); }"
+ },
+ {
+ "group": "modules",
+ "name": "repeated icon include is idempotent",
+ "accept": true,
+ "source": "include rt, run, icon, icon; fn main() { let q = run.tokens(\"return 1;\"); rt.put_n(icon.validate(q)); return 0; }",
+ "output": "1"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed const array",
+ "accept": true,
+ "source": "include rt; fn main() { fixed const int[3] a = {2,3,4}; rt.put_n(a[1]); }",
+ "output": "3"
+ },
+ {
+ "group": "qualifiers",
+ "name": "const fixed array",
+ "accept": true,
+ "source": "include rt; fn main() { const fixed int[3] a = {2,3,4}; rt.put_n(a[1]); }",
+ "output": "3"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed const global array",
+ "accept": true,
+ "source": "include rt; fixed const int[2] data = {8,9}; fn main() { rt.put_n(data[1]); }",
+ "output": "9"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed const array rejects element write",
+ "accept": false,
+ "source": "fn main() { fixed const int[2] a = {1,2}; a[0] = 3; }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "const fixed rejects resize",
+ "accept": false,
+ "source": "include rt; fn main() { const fixed int[?] a = rt.new(fixed int[?],2); a.resize(3); }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "const fixed cannot be rebound",
+ "accept": false,
+ "source": "include rt; fn main() { const fixed int[?] a = rt.new(fixed int[?],2); a = rt.new(fixed int[?],3); }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed mutable remains writable",
+ "accept": true,
+ "source": "include rt; fn main() { fixed int[2] a = {1,2}; a[0] = 3; rt.put_n(a[0]); }",
+ "output": "3"
+ },
+ {
+ "group": "qualifiers",
+ "name": "const fixed borrow cannot mutate storage",
+ "accept": false,
+ "source": "fn mutate(int* p) { p[0] = 9; } fn main() { const fixed int[2] a = {1,2}; mutate(a); }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "readonly parameter accepts const fixed",
+ "accept": true,
+ "source": "include rt; int first(const fixed int[2] a) { return a[0]; } fn main() { const fixed int[2] a = {7,8}; rt.put_n(first(a)); }",
+ "output": "7"
+ },
+ {
+ "group": "inference",
+ "name": "typed callee constrains untyped caller",
+ "accept": true,
+ "source": "include rt; int seed(int n) { return n + 1; } fn caller(n) { let result = seed(n); return result; } fn main() { rt.put_n(caller(4)); }",
+ "output": "5"
+ },
+ {
+ "group": "inference",
+ "name": "recursive anchored return",
+ "accept": true,
+ "source": "include rt; int seed(int n) { return n; } fn recursive(n) { if (n <= 0) return seed(n); return recursive(n - 1); } fn main() { rt.put_n(recursive(3)); }",
+ "output": "0"
+ },
+ {
+ "group": "qualifiers",
+ "name": "readonly array alias cannot remove qualifier",
+ "accept": false,
+ "source": "fn main() { fixed const int[2] a = {1,2}; int* alias = a; alias[0] = 8; }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "readonly array alias preserves qualifier",
+ "accept": true,
+ "source": "include rt; fn main() { fixed const int[2] a = {1,2}; let alias = a; rt.put_n(alias[0]); }",
+ "output": "1"
+ },
+ {
+ "group": "qualifiers",
+ "name": "readonly inferred alias cannot write",
+ "accept": false,
+ "source": "fn main() { fixed const int[2] a = {1,2}; let alias = a; alias[0] = 8; }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed const compound write rejected without typecheck",
+ "accept": false,
+ "source": "typecheck off; fn main() { fixed const int[2] a = {1,2}; a[0] += 2; }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "fixed const increment rejected",
+ "accept": false,
+ "source": "fn main() { fixed const int[2] a = {1,2}; a[0]++; }"
+ },
+ {
+ "group": "qualifiers",
+ "name": "readonly packed fixed array",
+ "accept": true,
+ "source": "include rt; fn main() { fixed const u8[] a = {2,3}; rt.put_n(a[1]); }",
+ "output": "3"
+ },
+ {
+ "group": "runtime",
+ "name": "owned readfile grows and returns exact character data",
+ "accept": true,
+ "source": "include rt; fn main() { char* text = rt.readfile(\"tests/data/readfile_growth.txt\"); rt.put_n(rt.len_w(text)); rt.put_c(32); rt.put_n(text[1029]); rt.put_c(32); rt.put_n(text[1030]); }",
+ "output": "1031 57 10"
+ },
+ {
+ "group": "runtime",
+ "name": "readfile missing path returns null",
+ "accept": true,
+ "source": "include rt; fn main() { char* text = rt.readfile(\"tests/data/missing-readfile-contract.txt\"); rt.put_n(text == 0); }",
+ "output": "1"
+ },
+ {
+ "group": "runtime",
+ "name": "owned file contents cannot be used after release",
+ "accept": false,
+ "source": "include rt; fn main() { char* text = rt.readfile(\"tests/data/readfile_growth.txt\"); rt.free(text); return text[0]; }"
+ }
+]