aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/compiler.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/compiler.zc')
-rw-r--r--src/compiler/compiler.zc76
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) {