diff options
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/compiler.zc | 76 |
1 files changed, 59 insertions, 17 deletions
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<int, char*>(...) @@ -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) { |
