summaryrefslogtreecommitdiff
path: root/appl/alphabet/abc
diff options
context:
space:
mode:
Diffstat (limited to 'appl/alphabet/abc')
-rw-r--r--appl/alphabet/abc/abc.b53
-rw-r--r--appl/alphabet/abc/autoconvert.b80
-rw-r--r--appl/alphabet/abc/autodeclare.b42
-rw-r--r--appl/alphabet/abc/declare.b70
-rw-r--r--appl/alphabet/abc/declares.b124
-rw-r--r--appl/alphabet/abc/define.b52
-rw-r--r--appl/alphabet/abc/eval.b66
-rw-r--r--appl/alphabet/abc/import.b53
-rw-r--r--appl/alphabet/abc/mkfile29
-rw-r--r--appl/alphabet/abc/newtypeset.b147
-rw-r--r--appl/alphabet/abc/rewrite.b71
-rw-r--r--appl/alphabet/abc/type.b53
-rw-r--r--appl/alphabet/abc/typeset.b51
-rw-r--r--appl/alphabet/abc/undeclare.b48
14 files changed, 939 insertions, 0 deletions
diff --git a/appl/alphabet/abc/abc.b b/appl/alphabet/abc/abc.b
new file mode 100644
index 00000000..b8d25342
--- /dev/null
+++ b/appl/alphabet/abc/abc.b
@@ -0,0 +1,53 @@
+implement Mkabc, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Mkabc: module {};
+types(): string
+{
+ return "A";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ nil: list of ref Value
+ ): ref Value
+{
+ alphabet := load Alphabet Alphabet->PATH;
+ if(alphabet == nil){
+ report(errorc, sys->sprint("abc: cannot load %q: %r", Alphabet->PATH));
+ return nil;
+ }
+ alphabet->init();
+ c := chan[1] of int;
+ c <-= 1;
+ return ref Value.VA((c, alphabet));
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/autoconvert.b b/appl/alphabet/abc/autoconvert.b
new file mode 100644
index 00000000..5e542c80
--- /dev/null
+++ b/appl/alphabet/abc/autoconvert.b
@@ -0,0 +1,80 @@
+implement Autoconvert, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+ Cmd,
+ n_BLOCK, n_WORD, n_SEQ, n_LIST, n_ADJ, n_VAR: import Sh;
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Autoconvert: module {};
+types(): string
+{
+ return "AAssc";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ src := (hd tl args).s().i;
+ dst := (hd tl tl args).s().i;
+ c := (hd tl tl tl args).c().i;
+
+ # {word} -> {(src); word $1}
+ if(c.ntype == n_BLOCK && c.left.ntype == n_WORD){
+ c = mk(n_BLOCK,
+ mk(n_SEQ,
+ mk(n_LIST, mkw(src), nil),
+ mk(n_ADJ,
+ c.left,
+ mk(n_VAR, mkw("1"), nil)
+ )
+ ),
+ nil
+ );
+ }
+
+ err := a->autoconvert(src, dst, c, errorc);
+ if(err != nil){
+ report(errorc, "abcautoconvert: "+err);
+ return nil;
+ }
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
+
+mk(ntype: int, left, right: ref Cmd): ref Cmd
+{
+ return ref Cmd(ntype, left, right, nil, nil);
+}
+mkw(w: string): ref Cmd
+{
+ return ref Cmd(n_WORD, nil, nil, w, nil);
+}
diff --git a/appl/alphabet/abc/autodeclare.b b/appl/alphabet/abc/autodeclare.b
new file mode 100644
index 00000000..b79009ed
--- /dev/null
+++ b/appl/alphabet/abc/autodeclare.b
@@ -0,0 +1,42 @@
+implement Autoconvert, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Autoconvert: module {};
+types(): string
+{
+ return "AAs";
+}
+
+init()
+{
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(nil: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ (hd args).A().i.alphabet->setautodeclare(int (hd tl args).s().i);
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/declare.b b/appl/alphabet/abc/declare.b
new file mode 100644
index 00000000..4c7bc020
--- /dev/null
+++ b/appl/alphabet/abc/declare.b
@@ -0,0 +1,70 @@
+implement Declare, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Declare: module {};
+types(): string
+{
+ return "AAss*-q-c";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ opts: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ flags := 0;
+ for(; opts != nil; opts = tl opts){
+ case (hd opts).t0 {
+ 'q' =>
+ flags |= Alphabet->ONDEMAND;
+ 'c' =>
+ flags |= Alphabet->CHECK;
+ }
+ }
+
+ n := len args;
+ if(n > 3){
+ report(errorc, "declare: maximum of two arguments allowed");
+ return nil;
+ }
+ a := (hd args).A().i.alphabet;
+ m := (hd tl args).s().i;
+ sig := "";
+ if(n > 2)
+ sig = (hd tl tl args).s().i;
+ e := a->declare(m, sig, flags);
+ if(e != nil){
+ report(errorc, "declare: "+e);
+ return nil;
+ }
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
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;
+}
diff --git a/appl/alphabet/abc/define.b b/appl/alphabet/abc/define.b
new file mode 100644
index 00000000..d6929b5d
--- /dev/null
+++ b/appl/alphabet/abc/define.b
@@ -0,0 +1,52 @@
+implement Define, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Define: module {};
+types(): string
+{
+ return "AAsc";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ m := (hd tl args).s().i;
+ c := (hd tl tl args).c().i;
+ if((e := a->define(m, c, errorc)) != nil){
+ report(errorc, "define: error: "+e);
+ return nil;
+ }
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/eval.b b/appl/alphabet/abc/eval.b
new file mode 100644
index 00000000..184aa0fd
--- /dev/null
+++ b/appl/alphabet/abc/eval.b
@@ -0,0 +1,66 @@
+implement Evalabc, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report, Report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Evalabc: module {};
+types(): string
+{
+ return "rAcs*";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(nil: chan of string, r: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ c := (hd tl args).c().i;
+ vl, rvl: list of ref Alphabet->Value;
+ for(args = tl tl args; args != nil; args = tl args)
+ vl = ref (Alphabet->Value).Vs((hd args).s().i) :: vl;
+ for(; vl != nil; vl = tl vl)
+ rvl = hd vl :: rvl;
+ vc := chan of ref Alphabet->Value;
+ spawn a->eval0(c, "/status", nil, r, r.start("abceval"), rvl, vc);
+ v := <-vc;
+ if(v == nil)
+ return nil;
+ return ref Value.Vr(vr(v).i);
+}
+
+vr(v: ref Alphabet->Value): ref (Alphabet->Value).Vr
+{
+ pick xv := v {
+ Vr =>
+ return xv;
+ }
+ return nil;
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/import.b b/appl/alphabet/abc/import.b
new file mode 100644
index 00000000..ea6c4214
--- /dev/null
+++ b/appl/alphabet/abc/import.b
@@ -0,0 +1,53 @@
+implement Import, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Import: module {};
+types(): string
+{
+ return "AAss*";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ av := (hd args);
+ a := av.A().i.alphabet;
+ for(args = tl args; args != nil; args = tl args){
+ if((e := a->importmodule((hd args).s().i)) != nil){
+ report(errorc, "import: "+(hd args).s().i+": "+e);
+ return nil;
+ }
+ }
+ return av.dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/mkfile b/appl/alphabet/abc/mkfile
new file mode 100644
index 00000000..02a918e7
--- /dev/null
+++ b/appl/alphabet/abc/mkfile
@@ -0,0 +1,29 @@
+<../../../mkconfig
+
+TARG=\
+ abc.dis\
+ autoconvert.dis\
+ autodeclare.dis\
+ declare.dis\
+ declares.dis\
+ define.dis\
+ eval.dis\
+ import.dis\
+ rewrite.dis\
+ type.dis\
+ typeset.dis\
+ undeclare.dis\
+
+SYSMODULES=\
+ alphabet.m\
+ draw.m\
+ alphabet/abc.m\
+ alphabet/reports.m\
+ sh.m\
+ string.m\
+ sys.m\
+
+DISBIN=$ROOT/dis/alphabet/abc
+
+<$ROOT/mkfiles/mkdis
+LIMBOFLAGS=-F $LIMBOFLAGS
diff --git a/appl/alphabet/abc/newtypeset.b b/appl/alphabet/abc/newtypeset.b
new file mode 100644
index 00000000..843eb116
--- /dev/null
+++ b/appl/alphabet/abc/newtypeset.b
@@ -0,0 +1,147 @@
+implement Newtypeset, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "bufio.m";
+ bufio: Bufio;
+ Iobuf: import bufio;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value, Vtype: import abc;
+
+# types abc -> types
+# returns a set of types defined in terms of the types and modules in $1
+# stdtypes types -> types
+# adds the standard root types to $1
+# newtype [-u] types string string cmd -> types
+# adds a new type named $2 to $1; the underlying type will be $3, and the destructor $4.
+# -u flag implies values of this type cannot be duplicated.
+# modules types -> modules
+# returns a value suitable for defining modules in terms of types defined in $1,
+# containing no module definitions.
+# module modules string string cmd -> modules
+# newtypeset abc string modules -> abc
+
+# declares adds some autoconversions:
+#
+# autoconvert abc types "{| types}
+# autoconvert types modules "{| modules}
+#
+# declares "{(abc)
+# autodeclare 1 |
+# newtypeset $1 /images {
+# abc |
+# autoconvert 1 |
+# newtype image /fd "{} |
+# newmodule read '/fd -> image' "{
+# | /filter "{canonimage}
+# } |
+# newmodule rotate 'image -> image' "{
+# | /filter "{rotate}
+# } |
+# newmodule display 'image -> /status' "{
+# | /filter "{showimage} | /create /dev/null
+# }
+# } |
+# type /images/image |
+# import /images/rotate |
+# autoconvert /string /fd "{|/read} |
+# autoconvert /fd image "{|/images/read} |
+# autoconvert image /status "{|/images/display}
+# }
+#
+# -{rotate x.bit}
+
+Newtypeset: module {};
+types(): string
+{
+ return "AAsm";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ d := (hd tl args).s().i;
+ path := "/dis/alphabet/" + d + "/alphabet"
+ iob := bufio->open(, Sys->OREAD);
+ if(iob == nil){
+ report(errorc, sys->sprint("scripttypeset: cannot open %q: %r", path));
+ return nil;
+ }
+ {
+ (types, decls) := parse(iob);
+ alphabet := load Alphabet Alphabet->PATH;
+ if(alphabet == nil){
+ report(errorc, sys->sprint("scripttypeset: cannot load %q: %r", Alphabet->PATH));
+ return nil;
+ }
+ declares := load Declares Declares->PATH;
+ if(declares == nil){
+ report(errorc, sys->sprint("scripttypeset: cannot load %q: %r", Alphabet->PATH));
+ return nil;
+ }
+ if((err := declares->declares(alphabet, decls, errorc)) != nil){
+ report(errorc, "scripttypeset: error on declarations: "+err);
+ return nil;
+ }
+ declares->quit();
+ declares = nil;
+ if(checktypes(alphabet, types, errorc) == -1)
+ return nil;
+ spawn scripttypesetproc(alphabet, types, c := chan of ref Proxy->Typescmd[ref Alphabet->Value]);
+ if((err := a->loadtypeset(d, c, errorc)) != nil){
+ c <-= nil;
+ return nil;
+ }
+ return (hd args).dup();
+ } exception e {
+ "parse:*" =>
+ report(errorc, sys->sprint("scripttypeset: error parsing %q: %s", path, e[6:]));
+ return nil;
+ }
+}
+
+checktypes(alphabet: Alphabet, types: list of ref Type, errorc: chan of string): int
+{
+ for(; types != nil; types = tl types){
+ t := hd types;
+ if(t.destructor != nil){
+ report(errorc, "destructors not supported yet");
+ }
+ }
+}
+
+scripttypesetproc(alphabet: Alphabet, types: list of ref Type, c: chan of Proxy->Typescmd[ref Alphabet->Value])
+{
+ while((gr := <-c) != nil){
+ pick r := gr {
+ Alphabet =>
+ Load =>
+
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/rewrite.b b/appl/alphabet/abc/rewrite.b
new file mode 100644
index 00000000..a9749258
--- /dev/null
+++ b/appl/alphabet/abc/rewrite.b
@@ -0,0 +1,71 @@
+implement Rewrite, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Rewrite: module {};
+types(): string
+{
+ return "cAc-ss-rs";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ opts: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ rtype, sig: string;
+ for(; opts != nil; opts = tl opts){
+ case (hd opts).t0 {
+ 's' =>
+ sig = (hd (hd opts).t1).s().i;
+ 'r' =>
+ rtype = (hd (hd opts).t1).s().i;
+ }
+ }
+ a := (hd args).A().i.alphabet;
+ c := (hd tl args).c().i;
+ actsig: string;
+ (c, actsig) = a->rewrite(c, rtype, errorc);
+ if(c == nil)
+ return nil;
+ if(sig != nil){
+ (ok, err) := a->typecompat(sig, actsig);
+ if(err != nil){
+ report(errorc, "rewrite: "+err);
+ return nil;
+ }
+ if(ok == 0){
+ report(errorc, sys->sprint("rewrite: %q is not compatible with %q", sig, actsig));
+ return nil;
+ }
+ }
+ return ref Value.Vc(c);
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/type.b b/appl/alphabet/abc/type.b
new file mode 100644
index 00000000..c36ceb61
--- /dev/null
+++ b/appl/alphabet/abc/type.b
@@ -0,0 +1,53 @@
+implement Type, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Type: module {};
+types(): string
+{
+ return "AAss*";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ av := (hd args);
+ a := av.A().i.alphabet;
+ for(args = tl args; args != nil; args = tl args){
+ if((e := a->importtype((hd args).s().i)) != nil){
+ report(errorc, "type: "+(hd args).s().i+": "+e);
+ return nil;
+ }
+ }
+ return av.dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/typeset.b b/appl/alphabet/abc/typeset.b
new file mode 100644
index 00000000..4b9152ea
--- /dev/null
+++ b/appl/alphabet/abc/typeset.b
@@ -0,0 +1,51 @@
+implement Typeset, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Typeset: module {};
+types(): string
+{
+ return "AAs";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(errorc: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ e := a->loadtypeset((hd tl args).s().i, nil, errorc);
+ if(e != nil){
+ report(errorc, "typeset: "+(hd tl args).s().i+": "+e);
+ return nil;
+ }
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}
diff --git a/appl/alphabet/abc/undeclare.b b/appl/alphabet/abc/undeclare.b
new file mode 100644
index 00000000..c4f266b8
--- /dev/null
+++ b/appl/alphabet/abc/undeclare.b
@@ -0,0 +1,48 @@
+implement Undeclare, Abcmodule;
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+include "sh.m";
+include "alphabet/reports.m";
+ reports: Reports;
+ report: import reports;
+include "alphabet.m";
+include "alphabet/abc.m";
+ abc: Abc;
+ Value: import abc;
+
+Undeclare: module {};
+types(): string
+{
+ return "AAss*";
+}
+
+init()
+{
+ sys = load Sys Sys->PATH;
+ reports = checkload(load Reports Reports->PATH, Reports->PATH);
+ abc = checkload(load Abc Abc->PATH, Abc->PATH);
+ abc->init();
+}
+
+quit()
+{
+}
+
+run(nil: chan of string, nil: ref Reports->Report,
+ nil: list of (int, list of ref Value),
+ args: list of ref Value
+ ): ref Value
+{
+ a := (hd args).A().i.alphabet;
+ for(al := tl args; al != nil; al = tl al)
+ a->undeclare((hd al).s().i);
+ return (hd args).dup();
+}
+
+checkload[T](m: T, path: string): T
+{
+ if(m != nil)
+ return m;
+ raise sys->sprint("fail:cannot load %s: %r", path);
+}