ww: implement package initialization
This commit is contained in:
@@ -24,14 +24,26 @@ import os;
|
||||
import syntax;
|
||||
import strconv;
|
||||
|
||||
let wwiwritefailed: i32 = 0;
|
||||
|
||||
fn wwrite(fd: i32, p: *u8, n: u64) void = {
|
||||
if (wwiwritefailed != 0) { return; };
|
||||
match (os.writeall(fd, p, n)) {
|
||||
case let wrote: i64 => {
|
||||
if (wrote < 0 || (wrote: u64) != n) { wwiwritefailed = 1; };
|
||||
};
|
||||
case let e: os.oserror => wwiwritefailed = 1;
|
||||
};
|
||||
};
|
||||
|
||||
fn wputs(fd: i32, s: str) void = {
|
||||
os.write(fd, s.ptr, s.len: u64);
|
||||
wwrite(fd, s.ptr, s.len: u64);
|
||||
};
|
||||
|
||||
fn wputb(fd: i32, b: u8) void = {
|
||||
let buf: [1]u8;
|
||||
buf[0] = b;
|
||||
os.write(fd, buf.ptr, 1u64);
|
||||
wwrite(fd, buf.ptr, 1u64);
|
||||
};
|
||||
|
||||
fn wquote(fd: i32, s: str) void = {
|
||||
@@ -59,7 +71,7 @@ fn wquote(fd: i32, s: str) void = {
|
||||
buf[1] = 120u8;
|
||||
buf[2] = h;
|
||||
buf[3] = l;
|
||||
os.write(fd, buf.ptr, 4u64);
|
||||
wwrite(fd, buf.ptr, 4u64);
|
||||
} else {
|
||||
wputb(fd, c);
|
||||
};};};};};
|
||||
@@ -85,7 +97,8 @@ fn wwimodeq(a: str, b: str) bool = {
|
||||
fn wwiusepath(c: *checker, owner: str, source: i32, alias: str) str = {
|
||||
let u: *syntax.node = c.file.list;
|
||||
for (u != nil) {
|
||||
if (u.kind == syntax.nkind.N_USE && u.sourceid == source
|
||||
if (u.kind == syntax.nkind.N_USE && u.useblank == 0
|
||||
&& u.sourceid == source
|
||||
&& syntax.streq(u.str, alias)) {
|
||||
let same: bool = false;
|
||||
if (owner.len == 0) {
|
||||
@@ -301,7 +314,7 @@ fn wwirune(fd: i32, cp: u64) void = {
|
||||
buf[1] = 120u8;
|
||||
buf[2] = h;
|
||||
buf[3] = l;
|
||||
os.write(fd, buf.ptr, 4u64);
|
||||
wwrite(fd, buf.ptr, 4u64);
|
||||
} else {
|
||||
wputb(fd, c);
|
||||
};};};};};
|
||||
@@ -591,6 +604,7 @@ fn wwiprimary(n: *syntax.node) bool = {
|
||||
};
|
||||
|
||||
fn wwiisdecl(d: *syntax.node) bool = {
|
||||
if (d.initfn != 0 || d.initsynthetic != 0) { return false; };
|
||||
return d.kind == syntax.nkind.N_FNDECL || d.kind == syntax.nkind.N_TYPEDECL ||
|
||||
d.kind == syntax.nkind.N_DEF || d.kind == syntax.nkind.N_LET;
|
||||
};
|
||||
@@ -887,7 +901,7 @@ fn wwisortfacts(fs: *wwifactset) void = {
|
||||
};
|
||||
|
||||
fn wwiowneduse(u: *syntax.node, owner: str, source: i32) bool = {
|
||||
return u.kind == syntax.nkind.N_USE && u.imported != 0
|
||||
return u.kind == syntax.nkind.N_USE && u.useblank == 0 && u.imported != 0
|
||||
&& u.sourceid == source && wwimodeq(u.nmod, owner);
|
||||
};
|
||||
|
||||
@@ -900,7 +914,8 @@ fn wwiemitimports(fd: i32, file: *syntax.node, owner: str, source: i32,
|
||||
if (imported) {
|
||||
owned = wwiowneduse(u, owner, source);
|
||||
} else {
|
||||
owned = u.kind == syntax.nkind.N_USE && u.imported == 0
|
||||
owned = u.kind == syntax.nkind.N_USE && u.useblank == 0
|
||||
&& u.imported == 0
|
||||
&& u.sourceid == source;
|
||||
};
|
||||
if (owned) { nuse += 1; };
|
||||
@@ -916,7 +931,8 @@ fn wwiemitimports(fd: i32, file: *syntax.node, owner: str, source: i32,
|
||||
if (imported) {
|
||||
owned = wwiowneduse(u, owner, source);
|
||||
} else {
|
||||
owned = u.kind == syntax.nkind.N_USE && u.imported == 0
|
||||
owned = u.kind == syntax.nkind.N_USE && u.useblank == 0
|
||||
&& u.imported == 0
|
||||
&& u.sourceid == source;
|
||||
};
|
||||
if (owned) {
|
||||
@@ -944,7 +960,7 @@ fn wwiprimarysectionhas(c: *checker, file: *syntax.node,
|
||||
source: i32) bool = {
|
||||
let u: *syntax.node = file.list;
|
||||
for (u != nil) {
|
||||
if (u.kind == syntax.nkind.N_USE && u.imported == 0
|
||||
if (u.kind == syntax.nkind.N_USE && u.useblank == 0 && u.imported == 0
|
||||
&& u.sourceid == source) { return true; };
|
||||
u = u.next;
|
||||
};
|
||||
@@ -1025,7 +1041,8 @@ fn wwiemitprimarysection(c: *checker, fd: i32, file: *syntax.node,
|
||||
};
|
||||
};
|
||||
|
||||
fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = {
|
||||
fn wwiemitfd(c: *checker, file: *syntax.node, fd: i32) i32 = {
|
||||
wwiwritefailed = 0;
|
||||
// §5: check_exported_type FIRST, before any byte — a producer
|
||||
// without it can emit a dangling `.wwi`.
|
||||
let bad: i32 = 0;
|
||||
@@ -1101,15 +1118,6 @@ fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = {
|
||||
wwisortdecls(dkeys, dnodes, ndecl);
|
||||
};
|
||||
|
||||
let fd: i32 = os.open(path,
|
||||
os.flag.WRONLY | os.flag.CREATE | os.flag.TRUNC, 420i32); // 0o644
|
||||
if (fd < 0) {
|
||||
wputs(2, "w6c: cannot open ");
|
||||
wputs(2, path);
|
||||
wputs(2, "\n");
|
||||
return 1i32;
|
||||
};
|
||||
|
||||
// Canonical ownership, declared name, and lexical source scope are
|
||||
// independent export facts. Repeated owner sections preserve the file
|
||||
// that owns each binding while every symbol/action remains keyed by owner.
|
||||
@@ -1154,6 +1162,5 @@ fn wwiemit(c: *checker, file: *syntax.node, path: str) i32 = {
|
||||
fi += 1;
|
||||
};
|
||||
|
||||
os.close(fd);
|
||||
return 0i32;
|
||||
return wwiwritefailed;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user