From 6f2cac23a7e759c464ef52103fac929e1eeb6b10 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 9 Oct 2021 10:30:50 -0700 Subject: feat(rc): added shell --- sys/cmd/rc/rc.h | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 sys/cmd/rc/rc.h (limited to 'sys/cmd/rc/rc.h') diff --git a/sys/cmd/rc/rc.h b/sys/cmd/rc/rc.h new file mode 100644 index 0000000..f32a737 --- /dev/null +++ b/sys/cmd/rc/rc.h @@ -0,0 +1,312 @@ +#pragma once + +#include +#include + +#include +#include + +#define alloc(ptr) ptr = emalloc(sizeof(*ptr)) + +// ----------------------------------------------------------------------- +// main enums + +#define GLOB 0x01 + +enum +{ + /* keywords */ + Kstart = 11, + Tfor, Tin, Twhile, Tif, Telse, + Tswitch, Tcase, Tfunc, Ttwiddle, + Tbang, Tsubshell, + Kend, + + /* tokens */ + Tword='w', Tredir='r', Tdup='d', Tsimple='s', + Targs='A', Twords='W', Tbrace='b', Tparen='p', Tsub='S', + Tpcmd='c', Tpipefd='-', Tandand='%', Toror='@', Tcount='#', + + Ttick='`', Tpipe = '|', Tdol='$', Tquote='"', Tand='&', + Tlparen = '(', Trparen = ')', Tlbrace='{', Trbrace='}', + Tsemi=';', Tcarot='^', Teq='=', +}; + +enum +{ + Rappend = 1, + Rwrite = 2, + Rread = 3, + Rhere = 4, + Rdupfd = 5, + Rclose = 6, + Rrdwr = 7, +}; + +enum +{ + Fopen = 1, + Fdup = 2, + Fclose = 3, +}; + +// ----------------------------------------------------------------------- +// main types + +typedef union Code Code; +typedef struct Word Word; +typedef struct List List; +typedef struct Var Var; +typedef struct Redir Redir; +typedef struct Tree Tree; +typedef struct Builtin Builtin; +typedef struct Thread Thread; +typedef struct Io Io; + +union Code +{ + int i; + char *s; + void (*f)(void); +}; + +struct Word +{ + char *word; + Word *link; +}; + +struct List +{ + Word *words; + List *link; +}; + +struct Redir +{ + uchar type; + short from, to; + Redir *link; +}; + +struct Var +{ + string name; + Word *val; + struct { + Code *func, *ip; + uint funcnew : 1; + }; + struct { + uint new : 1; + void (*update)(Var*); + }; + Var *link; +}; + +struct Tree +{ + ushort type; + uchar quoted : 1; + union { + char *str; + struct { + ushort type; + int fd[2]; + } redir; + }; + + Tree *child[3], *link; +}; + +struct Builtin +{ + char *cmd; + void (*func)(void); +}; + +struct Thread +{ + Code *code, *ip; + List *stack; + Redir *redir, *root; + Var *local; + uchar interactive : 1; + struct { + uchar eof : 1; + int line; + char *name; + Io *io; + } cmd; + + int pid; + Tree *nodes; + Thread *link; /* continuation */ +}; + +struct Io +{ + int fd; + uchar *b, *e, buf[]; +}; + +// ----------------------------------------------------------------------- +// global interpreter variables + +extern Thread *shell; +extern int ntrap; +extern int status; + +extern Io *errio; + +extern Builtin builtins[]; +extern Var *globals[1021]; /* for now must be prime */ + +// ----------------------------------------------------------------------- +// interpreter functions (defined in exec.c) + +/* + * notation: + * (var1, var2, ...) : items from stack + * [var1, var2, ...] : items from code stream + * {var1, var2, ...} : jump block from code stream + * -> moves value (stack) [code stream] + */ +extern void Xappend(void); /* Xappend(file)[fd]: open file to append */ +extern void Xassign(void); /* Xassign(name, val): assign name to val */ +extern void Xasync(void); /* Xasync(cmd): run command asynchronously */ +extern void Xcat(void); /* Xcat(list1, list2): concatenate strings */ +extern void Xclose(void); /* Xclose[fd]: close file descriptor */ +extern void Xcmdsub(void); /* Xcmdsub(cmd): use output of command as input to other */ +extern void Xcount(void); /* Xcount(name) -> (number): count items in list*/ +extern void Xdol(void); /* Xdol(name): get variable value */ +extern void Xdup(void); /* Xdup[i, j]: duplicate file descriptor */ +extern void Xexit(void); /* Xexit: exit with status */ +extern void Xfalse(void); /* Xfalse{...}: run only if $status=1 */ +extern void Xflatten(void); /* Xflatten(list) -> (string): flatten list */ +extern void Xfor(void); /* Xfor(list): flatten list */ +extern void Xfunc(void); /* Xfunc(name){... Xreturn}: define function */ +extern void Xglob(void); /* Xglob(list): globs value */ +extern void Xif(void); /* Xif: execute if $status */ +extern void Xjump(void); /* Xjump[addr]: jump to address */ +extern void Xkill(void); /* Xkill kill thread */ +extern void Xlocal(void); /* Xlocal(name, val): define local variable */ +extern void Xmark(void); /* Xmark: delimit stack with new list */ +extern void Xmatch(void); /* Xmatch(pat, str): sets status with result */ +extern void Xnegate(void); /* Xnegate: negate condition */ +extern void Xpipe(void); /* Xpipe[i j]{... Xkill}{... Xkill}: construct a pipe between 2 threads*/ +extern void Xpipefd(void); /* Xpipe[type]{... Xkill}: connect {} to a pipe */ +extern void Xpipewait(void); /* Xpipewait: wait on a pipe */ +extern void Xpop(void); /* Xpop(value): pops value from stack */ +extern void Xpopredir(void); /* Xpopredir(value): pops redir from redir stack */ +extern void Xrdwr(void); /* Xrdwr(file)[fd]: open file for reads/writes */ +extern void Xread(void); /* Xread(file)[fd]: open file for reads */ +extern void Xsub(void); /* Xsub(list, index): subscript list */ +extern void Xsimple(void); /* Xsimple(args): run command */ +extern void Xsubshell(void); /* Xsubshell(args): run command in a subshell */ +extern void Xtrue(void); /* Xtrue{...}: run only if $status=0 */ +extern void Xunfunc(void); /* Xunfunc(name) undefine function */ +extern void Xunlocal(void); /* Xunlocal(name) undefine local */ +extern void Xword(void); /* Xword[val] -> (val) */ +extern void Xwrite(void); /* Xwrite(file)[fd]: open file to write */ + +extern void Xerror(char *s); /* Xerror report an error */ + +// ----------------------------------------------------------------------- +// shell functions + +/* + * util.c + */ +void *emalloc(uintptr size); +void *erealloc(void *ptr, uintptr size); +void efree(void *); +void panic(char *msg, int n); + +/* + * io.c + */ +Io *openfd(int fd); +Io *openstr(void); +Io *opencore(int len, char *s); +void rewindio(Io *f); +void closeio(Io *f); +void flush(Io **fp); + +/* reads */ +int rchr(Io *f); + +/* writes */ +int pchr(Io *f, int c); +void pquo(Io *f, char *s); +void pwrd(Io *f, char *s); +void pptr(Io *f, void *v); +void pstr(Io *f, char *s); +void pdec(Io *f, int n); +void poct(Io *f, uint n); +void pval(Io *f, Word *a); +void pcmd(Io *f, Tree *t); +void pfmt(Io *f, char *fmt, ...); +void vpfmt(Io *f, char *fmt, va_list args); + +/* + * word.c + */ +void pushlist(void); +void freelist(Word *w); +void poplist(void); + +int count(Word *w); +Word *newword(char *w, Word *link); +void pushword(char *w); + +/* + * tree.c + */ + +Tree *newtree(void); +void freetree(Tree *t); +Tree *tree3(int type, Tree *c0, Tree *c1, Tree *c2); +Tree *tree2(int type, Tree *c0, Tree *c1); +Tree *tree1(int type, Tree *c0); + +Tree *hang1(Tree *p, Tree *c0); +Tree *hang2(Tree *p, Tree *c0, Tree *c1); +Tree *hang3(Tree *p, Tree *c0, Tree *c1, Tree *c2); +Tree *epihang(Tree *c, Tree *epi); +Tree *simplehang(Tree *t); +Tree *wordnode(char *w); + +/* + * var.c + */ + +Var *newvar(char *name, Var *link); +Var *gvlookup(char *name); +Var *vlookup(char *name); +void setvar(char *name, Word *val); + +int kwlookup(char *name); +void initkw(void); + +/* + * lex.c + */ + +void skipnl(void); +int wordchr(int c); + +void rcerror(char *msg, ...); +int lex(Tree **node); + +/* + * parse.c + */ + +int parse(void); + +/* + * main.c + */ + +void dotrap(void); -- cgit v1.2.1