summaryrefslogtreecommitdiff
path: root/appl/cmd/mash/mash.m
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/mash/mash.m')
-rw-r--r--appl/cmd/mash/mash.m372
1 files changed, 372 insertions, 0 deletions
diff --git a/appl/cmd/mash/mash.m b/appl/cmd/mash/mash.m
new file mode 100644
index 00000000..ae16fee6
--- /dev/null
+++ b/appl/cmd/mash/mash.m
@@ -0,0 +1,372 @@
+include "sys.m";
+include "bufio.m";
+include "draw.m";
+include "hash.m";
+include "filepat.m";
+include "regex.m";
+include "sh.m";
+include "string.m";
+include "tk.m";
+
+#
+# mash - Inferno make/shell
+#
+# Bruce Ellis - 1Q 98
+#
+
+ Rin,
+ Rout,
+ Rappend,
+ Rinout,
+ Rcount
+ : con iota; # Redirections
+
+ Icaret,
+ Iicaret,
+ Idollar,
+ Idollarq,
+ Imatch,
+ Iword,
+ Iexpr,
+ Ibackq,
+ Iquote,
+ Iinpipe,
+ Ioutpipe,
+ Iredir
+ : con iota; # Items
+
+ Csimple,
+ Cseq,
+ Cfor,
+ Cif,
+ Celse,
+ Cwhile,
+ Ccase,
+ Ccases,
+ Cmatched,
+ Cdefeq,
+ Ceq,
+ Cfn,
+ Crescue,
+ Casync,
+ Cgroup,
+ Clistgroup,
+ Csubgroup,
+ Cnop,
+ Cword,
+ Clist,
+ Ccaret,
+ Chd,
+ Clen,
+ Cnot,
+ Ctl,
+ Ccons,
+ Ceqeq,
+ Cnoteq,
+ Cmatch,
+ Cpipe,
+ Cdepend,
+ Crule,
+ Cprivate
+ : con iota; # Commands
+
+ Svalue,
+ Sfunc,
+ Sbuiltin
+ : con iota; # Symbol types
+
+Mashlib: module
+{
+ PATH: con "/dis/lib/mashlib.dis";
+
+ File: adt
+ {
+ in: ref Bufio->Iobuf;
+ name: string;
+ line: int;
+ eof: int;
+ };
+
+ Src: adt
+ {
+ line: int;
+ file: string;
+ };
+
+ Wquoted,
+ Wexpand
+ : con 1 << iota;
+
+ Word: adt
+ {
+ text: string;
+ flags: int;
+ where: Src;
+
+ word: fn(w: self ref Word, d: string): string;
+ };
+
+ Item: adt
+ {
+ op: int;
+ word: ref Word;
+ left, right: ref Item;
+ cmd: ref Cmd;
+ redir: ref Redir;
+
+ item1: fn(op: int, l: ref Item): ref Item;
+ item2: fn(op: int, l, r: ref Item): ref Item;
+ itemc: fn(op: int, c: ref Cmd): ref Item;
+ iteml: fn(l: list of string): ref Item;
+ itemr: fn(op: int, i: ref Item): ref Item;
+ itemw: fn(s: string): ref Item;
+
+ caret: fn(i: self ref Item, e: ref Env): (string, list of string, int);
+ ieval: fn(i: self ref Item, e: ref Env): (string, list of string, int);
+ ieval1: fn(i: self ref Item, e: ref Env): ref Item;
+ ieval2: fn(i: self ref Item, e: ref Env): (string, list of string, int);
+ reval: fn(i: self ref Item, e: ref Env): (int, string);
+ sword: fn(i: self ref Item, e: ref Env): ref Item;
+ text: fn(i: self ref Item): string;
+ };
+
+ Redir: adt
+ {
+ op: int;
+ word: ref Item;
+ };
+
+ Cmd: adt
+ {
+ op: int;
+ words: cyclic list of ref Item;
+ left, right: cyclic ref Cmd;
+ item: cyclic ref Item;
+ redirs: cyclic list of ref Redir;
+ value: list of string;
+ error: int;
+
+ cmd1: fn(op: int, l: ref Cmd): ref Cmd;
+ cmd2: fn(op: int, l, r: ref Cmd): ref Cmd;
+ cmd1i: fn(op: int, l: ref Cmd, i: ref Item): ref Cmd;
+ cmd1w: fn(op: int, l: ref Cmd, w: list of ref Item): ref Cmd;
+ cmde: fn(c: self ref Cmd, op: int, l, r: ref Cmd): ref Cmd;
+ cmdiw: fn(op: int, i: ref Item, w: list of ref Item): ref Cmd;
+
+ assign: fn(c: self ref Cmd, e: ref Env, def: int);
+ checkpipe: fn(c: self ref Cmd, e: ref Env, f: int): int;
+ cmdio: fn(c: self ref Cmd, e: ref Env, i: ref Item);
+ depend: fn(c: self ref Cmd, e: ref Env);
+ eeval: fn(c: self ref Cmd, e: ref Env): (string, list of string);
+ eeval1: fn(c: self ref Cmd, e: ref Env): ref Cmd;
+ eeval2: fn(c: self ref Cmd, e: ref Env): (string, list of string, int);
+ evaleq: fn(c: self ref Cmd, e: ref Env): int;
+ evalmatch: fn(c: self ref Cmd, e: ref Env): int;
+ mkcmd: fn(c: self ref Cmd, e: ref Env, async: int): ref Cmd;
+ quote: fn(c: self ref Cmd, e: ref Env, back: int): ref Item;
+ rotcases: fn(c: self ref Cmd): ref Cmd;
+ rule: fn(c: self ref Cmd, e: ref Env);
+ serve: fn(c: self ref Cmd, e: ref Env, write: int): ref Item;
+ simple: fn(c: self ref Cmd, e: ref Env, wait: int);
+ text: fn(c: self ref Cmd): string;
+ truth: fn(c: self ref Cmd, e: ref Env): int;
+ xeq: fn(c: self ref Cmd, e: ref Env);
+ xeqit: fn(c: self ref Cmd, e: ref Env, wait: int);
+ };
+
+ Depend: adt
+ {
+ targets: list of string;
+ depends: list of string;
+ op: int;
+ cmd: ref Cmd;
+ mark: int;
+ };
+
+ Target: adt
+ {
+ target: string;
+ depends: list of ref Depend;
+
+ find: fn(s: string): ref Target;
+ };
+
+ Lhs: adt
+ {
+ text: string;
+ elems: list of string;
+ count: int;
+ };
+
+ Rule: adt
+ {
+ lhs: ref Lhs;
+ rhs: ref Item;
+ op: int;
+ cmd: ref Cmd;
+
+ match: fn(r: self ref Rule, a, n: int, t: list of string): int;
+ matches: fn(r: self ref Rule, t: list of string): array of string;
+ };
+
+ SHASH: con 31; # Symbol table hash size
+ SMASK: con 16r7FFFFFFF; # Mask for SHASH bits
+
+ Symb: adt
+ {
+ name: string;
+ value: list of string;
+ func: ref Cmd;
+ builtin: Mashbuiltin;
+ tag: int;
+ };
+
+ Stab: adt
+ {
+ tab: array of list of ref Symb;
+ wmask: int;
+ copy: int;
+
+ new: fn(): ref Stab;
+ clone: fn(t: self ref Stab): ref Stab;
+ all: fn(t: self ref Stab): list of ref Symb;
+ assign: fn(t: self ref Stab, s: string, v: list of string);
+ defbuiltin: fn(t: self ref Stab, s: string, b: Mashbuiltin);
+ define: fn(t: self ref Stab, s: string, f: ref Cmd);
+ find: fn(t: self ref Stab, s: string): ref Symb;
+ func: fn(t: self ref Stab, s: string): ref Cmd;
+ update: fn(t: self ref Stab, s: string, tag: int, v: list of string, f: ref Cmd, b: Mashbuiltin): ref Symb;
+ };
+
+ ETop, EInter, EEcho, ERaise, EDumping, ENoxeq:
+ con 1 << iota;
+
+ Env: adt
+ {
+ global: ref Stab;
+ local: ref Stab;
+ flags: int;
+ in, out: ref Sys->FD;
+ stderr: ref Sys->FD;
+ wait: ref Sys->FD;
+ file: ref File;
+ args: array of string;
+ level: int;
+
+ new: fn(): ref Env;
+ clone: fn(e: self ref Env): ref Env;
+ copy: fn(e: self ref Env): ref Env;
+
+ interactive: fn(e: self ref Env, fd: ref Sys->FD);
+
+ arg: fn(e: self ref Env, s: string): string;
+ builtin: fn(e: self ref Env, s: string): Mashbuiltin;
+ defbuiltin: fn(e: self ref Env, s: string, b: Mashbuiltin);
+ define: fn(e: self ref Env, s: string, f: ref Cmd);
+ dollar: fn(e: self ref Env, s: string): ref Symb;
+ func: fn(e: self ref Env, s: string): ref Cmd;
+ let: fn(e: self ref Env, s: string, v: list of string);
+ set: fn(e: self ref Env, s: string, v: list of string);
+
+ couldnot: fn(e: self ref Env, what, who: string);
+ diag: fn(e: self ref Env, s: string): string;
+ error: fn(e: self ref Env, s: string);
+ report: fn(e: self ref Env, s: string);
+ sopen: fn(e: self ref Env, s: string);
+ suck: fn(e: self ref Env);
+ undefined: fn(e: self ref Env, s: string);
+ usage: fn(e: self ref Env, s: string);
+
+ devnull: fn(e: self ref Env): ref Sys->FD;
+ fopen: fn(e: self ref Env, fd: ref Sys->FD, s: string);
+ outfile: fn(e: self ref Env): ref Bufio->Iobuf;
+ output: fn(e: self ref Env, s: string);
+ pipe: fn(e: self ref Env): array of ref Sys->FD;
+ runit: fn(e: self ref Env, s: list of string, in, out: ref Sys->FD, wait: int);
+ serve: fn(e: self ref Env);
+ servefd: fn(e: self ref Env, fd: ref Sys->FD, write: int): string;
+ servefile: fn(e: self ref Env, n: string): (string, ref Sys->FileIO);
+
+ doload: fn(e: self ref Env, s: string);
+ lex: fn(e: self ref Env, y: ref Mashparse->YYSTYPE): int;
+ mklist: fn(e: self ref Env, l: list of ref Item): list of ref Item;
+ mksimple: fn(e: self ref Env, l: list of ref Item): ref Cmd;
+ };
+
+ initmash: fn(ctxt: ref Draw->Context, top: ref Tk->Toplevel, s: Sys, e: ref Env, l: Mashlib, p: Mashparse);
+ nonexistent: fn(s: string): int;
+
+ errstr: fn(): string;
+ exits: fn(s: string);
+ ident: fn(s: string): int;
+ initdep: fn();
+ prepareio: fn(in, out: ref sys->FD): (int, ref Sys->FD);
+ prprompt: fn(n: int);
+ quote: fn(s: string): string;
+ reap: fn();
+ revitems: fn(l: list of ref Item): list of ref Item;
+ revstrs: fn(l: list of string): list of string;
+ rulematch: fn(s: string): list of ref Rule;
+
+ ARGS: con "args";
+ BUILTINS: con "builtins.dis";
+ CHAN: con "/chan";
+ CONSOLE: con "/dev/cons";
+ DEVNULL: con "/dev/null";
+ EEXISTS: con "file exists";
+ EPIPE: con "write on closed pipe";
+ EXIT: con "exit";
+ FAILPAT: con "fail:*";
+ FAIL: con "fail:";
+ FAILLEN: con len FAIL;
+ HISTF: con "history";
+ LIB: con "/dis/lib/mash/";
+ MASHF: con "mash";
+ MASHINIT: con "mashinit";
+ PROFILE: con "/lib/mashinit";
+ TRUE: con "true";
+ MAXELEV: con 256;
+
+ sys: Sys;
+ bufio: Bufio;
+ filepat: Filepat;
+ hash: Hash;
+ regex: Regex;
+ str: String;
+ tk: Tk;
+
+ gctxt: ref Draw->Context;
+ gtop: ref Tk->Toplevel;
+
+ prompt: string;
+ contin: string;
+
+ empty: list of string;
+
+ PIDEXIT: con 0;
+
+ histchan: chan of array of byte;
+ inchan: chan of array of byte;
+ pidchan: chan of int;
+ servechan: chan of array of byte;
+ startserve: int;
+
+ rules: list of ref Rule;
+ dephash: array of list of ref Target;
+
+ parse: Mashparse;
+};
+
+#
+# Interface to loadable builtin modules. mashinit is called when a module
+# is loaded. mashcmd is called for a builtin as defined by Env.defbuiltin().
+# init() is in the interface to catch the use of builtin modules as commands.
+# name() is used by whatis.
+#
+Mashbuiltin: module
+{
+ mashinit: fn(l: list of string, lib: Mashlib, this: Mashbuiltin, e: ref Mashlib->Env);
+ mashcmd: fn(e: ref Mashlib->Env, l: list of string);
+ init: fn(ctxt: ref Draw->Context, args: list of string);
+ name: fn(): string;
+};