#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, }; // ----------------------------------------------------------------------- // main types typedef union Code Code; typedef struct Word Word; typedef struct List List; typedef struct Var Var; 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 Var { string name; Word *val; Code *func; 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; Var *local; 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 * -> moves value */ extern void Xmark(void); /* Xmark: delimit stack with new list */ extern void Xword(void); /* Xword[val] -> (val) */ extern void Xassign(void); /* Xassign(name, val): assign name to val */ extern void Xdol(void); /* Xdol(name): get variable value */ extern void Xsimple(void); /* Xsimple(args): run command */ extern void Xexit(void); /* Xexit: exit with status */ extern void Xerror(char *s); /* Xerror: report an error */ extern void Xparse(void); // ----------------------------------------------------------------------- // 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); 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);