From fd622c51be670bba2acf4b50c548acedbc8bb263 Mon Sep 17 00:00:00 2001 From: zinc Date: Wed, 14 Oct 2026 09:07:12 +0000 Subject: todo: one sorted list of open work; library suggestions without naming libraries TODO.md ticks the items verified done (namespaces, actor and icon libraries and their coverage, the genome embed, the bootstrap ownership limits, the docs and fixtures sweep) and lists everything still open, including the newly requested language features, sorted easiest first. the compiler no longer names actor: file libraries for suggestions come from src/lib/modules.txt, and lib.name before its include reports the missing include. icon gains fixtures for reading globals while stepping and for begin_function on a non-function, and the suite checks that nothing the compiler reads by default mentions actors. bf.zc, the web sample and std's capture example use qualified runtime names; LEARN.md uses build/bin paths. --- src/compiler/compiler.zc | 76 +++++++++++++++++++++++++++++++++++++----------- src/lib/modules.txt | 5 ++++ src/lib/std.zc | 4 +-- src/lsp/server.zc | 4 ++- src/web/index.html | 5 ++-- 5 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 src/lib/modules.txt (limited to 'src') diff --git a/src/compiler/compiler.zc b/src/compiler/compiler.zc index 9c24af9..86e00c5 100644 --- a/src/compiler/compiler.zc +++ b/src/compiler/compiler.zc @@ -6742,7 +6742,7 @@ int brace_primary() { // variable the value is. int primary() { effect_value = 0; xprojection = 0; if_value = 0; - int n, i, s, c, k; word[8] bs0; int ft, mn, ms; + int n, i, s, c, k, npos, sv; word[8] bs0; int ft, mn, ms; lv = 0; lvk = LV_NONE; xzero = 0; xbor = -1; xconst = 0; xfloat = 0; xstr = 0; xlenloc = -1; xstamp = 0; xaf = 0; xvk = 0; if (tk == T_FLT) { op(OP_FLIT); emit(tv); xvk = 2; xvv = tv; xfloat = 1; xty = tfloat; next(); return C_PLAIN; } @@ -6839,6 +6839,7 @@ int primary() { xty = tword; return C_PLAIN; } + npos = tpack(); next(); xty = tword; if (s >= 0 && skind[s] == K_CONST) { @@ -6863,9 +6864,17 @@ int primary() { if (s >= 0 && skind[s] == K_GARR) { lit(sval[s]); if (stype[s]) xty = stype[s]; return C_PLAIN; } if (s >= 0 && skind[s] == K_ENH) return enhcall(s); if (s < 0 && is_op(s_dot)) { - // Text.itoa with no std: a library's static function, reported as one missing name peekat(0); - if (pk_tk == T_ID && export_owner(methname(n, pk_tv))) { next(); n = methname(n, tv); next(); } + if (pk_tk == T_ID && lib_file(n)) { + // lib.name before include lib, for a library read from a file: the lexer only joins names of loaded modules + sv = tpack(); tunpack(npos); + errat(); rt.put_s("module access requires `include "); rt.put_s(n); rt.put_s(";`"); errend(); + tunpack(sv); + word link = chk_resize(0, 0, 2); link[0] = missing_imports; link[1] = n; missing_imports = link; + next(); n = methname(n, tv); next(); + } + // Text.itoa with no std: a library's static function, reported as one missing name + else if (pk_tk == T_ID && export_owner(methname(n, pk_tv))) { next(); n = methname(n, tv); next(); } } if (s < 0) s = fwdfn_at(n, callpos); if (is_op(s_lt) && (sflag[s] & F_GEN)) { // f(...) @@ -9629,21 +9638,53 @@ word lib_scan(char* s) { while (list) { entry = list[0]; list[0] = back; back = list; list = entry; } return back; } -// the libraries under src/lib, scanned once: std and icon are embedded, actor is read like its include -word std_names, icon_names, actor_names; int names_read; +// the embedded libraries, scanned once +word std_names, icon_names; int names_read; word lib_names(char* module) { - char* save = incres; - if (!names_read) { - names_read = 1; - std_names = lib_scan(std_text()); icon_names = lib_scan(icon_text()); - char* text = inc_open("src/lib/actor.zc"); - if (text) actor_names = lib_scan(text); - rt.free(text); - incres = save; - } + if (!names_read) { names_read = 1; std_names = lib_scan(std_text()); icon_names = lib_scan(icon_text()); } if (rt.eq_w(module, "std")) return std_names; - if (rt.eq_w(module, "icon")) return icon_names; - return actor_names; + return icon_names; +} +// the libraries read from files, named in src/lib/modules.txt (one per line, # starts a +// comment), as a list of [next, name, declarations, scanned]. the compiler names none of them. +word file_libs; int file_libs_read; +word lib_files() { + int i = 0, a; word entry, tail = 0; char* save = incres; + if (file_libs_read) return file_libs; + file_libs_read = 1; + char* text = inc_open("src/lib/modules.txt"); + incres = save; + if (!text) return 0; + while (text[i]) { + while (text[i] == 32 || text[i] == 9 || text[i] == 10 || text[i] == 13) i++; + if (text[i] == '#') { while (text[i] && text[i] != 10) i++; continue; } + a = i; while (isidc(text[i])) i++; + if (i == a) { if (text[i]) i++; continue; } + entry = chk_resize(0, 0, 4); entry[1] = lib_copy(text, a, i); + if (tail) tail[0] = entry; else file_libs = entry; + tail = entry; + } + rt.free(text); + return file_libs; +} +// the entry of a file library, or 0 +word lib_file(char* name) { + word p = lib_files(); + while (p) { if (rt.eq_w(p[1], name)) return p; p = p[0]; } + return 0; +} +// a file library's declarations, read and scanned the first time they are needed +word lib_file_names(word entry) { + char* save = incres; + if (entry[3]) return entry[2]; + entry[3] = 1; + char* filename = inc_cat("src/lib", entry[1]); int length = rt.len_w(filename); + char* full = chk_resize(0, 0, length + 4); rt.copy_w(full, filename, length); rt.copy_w(full + length, ".zc", 4); + char* text = inc_open(full); + if (text) entry[2] = lib_scan(text); + rt.free(text); + incres = save; + return entry[2]; } // where name is in a library's list: Text.itoa is itself, a bare itoa is a top-level // declaration first, then a static method of some group. 0 when it is not there. @@ -9678,7 +9719,8 @@ word export_owners(char* name) { while (p) { export_add(p[1], export_in(p[1], name)); p = p[0]; } export_add("std", lib_path(lib_names("std"), name)); export_add("icon", lib_path(lib_names("icon"), name)); - export_add("actor", lib_path(lib_names("actor"), name)); + p = lib_files(); + while (p) { export_add(p[1], lib_path(lib_file_names(p), name)); p = p[0]; } return export_list; } char* export_owner(char* name) { diff --git a/src/lib/modules.txt b/src/lib/modules.txt new file mode 100644 index 0000000..7e157fd --- /dev/null +++ b/src/lib/modules.txt @@ -0,0 +1,5 @@ +# libraries under src/lib that are read from their file by `include name;`. +# std and icon are embedded in the compiler and are not listed. the compiler +# reads this list only to suggest a library for a name it can't find, so a +# library missing here still includes; it just isn't suggested. +actor diff --git a/src/lib/std.zc b/src/lib/std.zc index dfa9841..f0bc390 100644 --- a/src/lib/std.zc +++ b/src/lib/std.zc @@ -65,9 +65,9 @@ int libinit() { // returns it. writes go to the buffer instead of the terminal until end() // stops it, so the buffer is a string once end() has run: // let buf = capture.start(); -// put_s("hello world!"); // nothing on the terminal +// rt.put_s("hello world!"); // nothing on the terminal // capture.end(buf); -// put_s(buf); // hello world +// rt.put_s(buf); // hello world // one capture at a time, and the buffer belongs to whoever holds it. struct capture { diff --git a/src/lsp/server.zc b/src/lsp/server.zc index 2587c3b..1608c4c 100644 --- a/src/lsp/server.zc +++ b/src/lsp/server.zc @@ -3407,11 +3407,13 @@ int do_code_actions(int i) { start = ca_start; while (start > 0 && (hid(dc(base, start - 1)) || dc(base, start - 1) == '.')) start--; dot = start; while (dot < ca_end && dc(base, dot) != '.') dot++; + // the error can sit on the qualifier alone: actor in actor.vector + if (dot == ca_end && dot < dsize[i] && dc(base, dot) == '.' && run.lib_file(hname) && !run.module_imported(hname)) { ca_add(hname, 0, 0); send(gen_code_actions); return 0; } if (dot < ca_end) { // rt.put_c without include rt needs only the include; Text.itoa without std is std.Text.itoa char* owner = rt.new(dot - start + 1); k = start; n = 0; while (k < dot) { owner[n] = dc(base, k); n++; k++; } owner[n] = 0; - if (run.module_known(owner) || run.module_loaded(owner)) { if (!run.module_imported(owner)) ca_add(owner, 0, 0); } + if (run.module_known(owner) || run.module_loaded(owner) || run.lib_file(owner)) { if (!run.module_imported(owner)) ca_add(owner, 0, 0); } else { char* dotted = rt.new(ca_end - start + 1); k = start; n = 0; while (k < ca_end) { dotted[n] = dc(base, k); n++; k++; } dotted[n] = 0; diff --git a/src/web/index.html b/src/web/index.html index fbc203d..8480d43 100644 --- a/src/web/index.html +++ b/src/web/index.html @@ -27,8 +27,9 @@ loading - -- cgit v1.2.3