summaryrefslogtreecommitdiff
path: root/appl/alphabet/abc/declares.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/alphabet/abc/declares.b')
-rw-r--r--appl/alphabet/abc/declares.b124
1 files changed, 124 insertions, 0 deletions
diff --git a/appl/alphabet/abc/declares.b b/appl/alphabet/abc/declares.b
new file mode 100644
index 00000000..f4e58467
--- /dev/null
+++ b/appl/alphabet/abc/declares.b
@@ -0,0 +1,124 @@
+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;
+}