ref: 866d74c0c4bb50e85e9e8bb95140c10d409e53be
dir: /appl/alphabet/abc/declares.b/
implement Declares, Abcmodule;
include "sys.m";
sys: Sys;
include "draw.m";
include "sh.m";
n_BLOCK, n_ADJ, n_VAR, n_WORD: import Sh;
include "alphabet/reports.m";
reports: Reports;
report, Report: import reports;
include "alphabet.m";
alphabet: Alphabet;
include "alphabet/abc.m";
abc: Abc;
Value: import abc;
include "alphabet/abctypes.m";
abctypes: Abctypes;
Abccvt: import abctypes;
cvt: ref Abccvt;
types(): string
{
return "AAc";
}
init()
{
sys = load Sys Sys->PATH;
reports = checkload(load Reports Reports->PATH, Reports->PATH);
abc = checkload(load Abc Abc->PATH, Abc->PATH);
abc->init();
alphabet = checkload(load Alphabet Alphabet->PATH, Alphabet->PATH);
alphabet->init();
abctypes = checkload(load Abctypes Abctypes->PATH, Abctypes->PATH);
(c, nil, abccvt) := abctypes->proxy0();
cvt = abccvt;
alphabet->loadtypeset("/abc", c, nil);
alphabet->importtype("/abc/abc");
alphabet->importtype("/string");
alphabet->importtype("/cmd");
c = nil;
# note: it's faster if we provide the signatures, as we don't
# have to load the module to find out its signature just to throw
# it away again. pity about the maintenance.
# Edit x s:(/abc/[a-z]+) (.*):declimport("\1", "\2");
declimport("/abc/autoconvert", "abc string string cmd -> abc");
declimport("/abc/autodeclare", "abc string -> abc");
declimport("/abc/declare", "[-qc] abc string [string...] -> abc");
declimport("/abc/define", "abc string cmd -> abc");
declimport("/abc/import", "abc string [string...] -> abc");
declimport("/abc/type", "abc string [string...] -> abc");
declimport("/abc/typeset", "abc string -> abc");
declimport("/abc/undeclare", "abc string [string...] -> abc");
}
quit()
{
alphabet->quit();
}
run(errorc: chan of string, r: ref Reports->Report,
nil: list of (int, list of ref Value),
args: list of ref Value
): ref Value
{
(av, err) := alphabet->importvalue(cvt.int2ext((hd args).dup()), "/abc/abc");
if(av == nil){
report(errorc, sys->sprint("declares: cannot import abc value: %s", err));
return nil;
}
vc := chan of ref Alphabet->Value;
spawn alphabet->eval0((hd tl args).c().i, "/abc/abc", nil, r, r.start("evaldecl"), av :: nil, vc);
av = <-vc;
if(av == nil)
return nil;
v := cvt.ext2int(av).dup();
alphabet->av.free(1);
return v;
}
declimport(m: string, sig: string)
{
if((e := alphabet->declare(m, sig, Alphabet->ONDEMAND)) != nil)
raise sys->sprint("fail:cannot declare %s: %s", m, e);
alphabet->importmodule(m);
}
checkload[T](m: T, path: string): T
{
if(m != nil)
return m;
raise sys->sprint("fail:cannot load %s: %r", path);
}
declares(a: Alphabet, decls: ref Sh->Cmd, errorc: chan of string, stopc: chan of int): string
{
spawn reports->reportproc(reportc := chan of string, stopc, reply := chan of ref Report);
r := <-reply;
reply = nil;
spawn declaresproc(a, decls, r.start("declares"), r, vc := chan of ref Value);
r.enable();
v: ref Value;
wait:
for(;;)alt{
v = <-vc =>
;
msg := <-reportc =>
if(msg == nil)
break wait;
errorc <-= sys->sprint("declares: %s", msg);
}
if(v == nil)
return "declarations failed";
return nil;
}
declaresproc(a: Alphabet, decls: ref Sh->Cmd, errorc: chan of string, r: ref Report, vc: chan of ref Value)
{
novals: list of ref Value;
vc <-= run(errorc, r, nil, abc->mkabc(a).dup() :: ref Value.Vc(decls) :: novals);
errorc <-= nil;
}