#pragma once #include #include // ----------------------------------------------------------------------- // types typedef struct Io Io; typedef struct Var Var; typedef struct Word Word; typedef struct List List; typedef struct Tree Tree; typedef struct Redir Redir; typedef union Code Code; typedef struct Thread Thread; typedef struct WaitMsg WaitMsg; struct Io { int fd, cap; char *s; char *b, *e, buf[]; }; struct Tree { int type; char *str; Tree *child[3]; Tree *link; }; struct Word { char *str; Word *link; }; struct List { Word *word; List *link; }; /* * the first word of any code vector is a reference count * always create a new reference to a code vector by calling copycode() * always call freecode() when deleting a reference */ union Code { int i; void (*f)(void); char *s; }; struct Var { char *name; Word *val; short new : 1; short newfunc : 1; Code *func; void (*update)(Var *); Var *link; }; enum { Rclose, Rdup, Ropen, }; struct Redir { char type; /* what to do */ short from, to; /* what to do it to */ struct Redir *link; /* what else to do (reverse order) */ }; struct Thread { struct { int i; Code *exe; } code; // execution stack struct { Io *io; char *path; } cmd; // command input List *args; // argument stack Var *local; // local variables Redir *redir; // list of redirections struct { ushort i : 1; ushort eof : 1; } flag; // flags for process int pid; long line; Tree *nodes; // memory allocation Thread *link; // process we return to }; struct WaitMsg { int pid; // of loved one ulong time[3]; // of loved one & descendants char *msg; }; // ----------------------------------------------------------------------- // globals extern int rcpid; extern Thread *shell; extern Io *errio; extern Code *compiled; // ----------------------------------------------------------------------- // functions /* util.c */ void itoa(char*, long i); void fatal(char *, ...); void *emalloc(uintptr); void *erealloc(void*, uintptr); void efree(void*); /* read.c */ int readline(char *); void enablevi(void); /* prompt.c */ int prompt(ushort *); /* io.c */ Io *openfd(int fd); Io *openstr(void); void terminate(Io *io); int get(Io *); int put(Io **, char); void flush(Io *io); void print(Io *, char *, ...); /* lex.c */ int iswordchar(int c); int yylex(void); /* tree.c */ Tree *maketree(void); Tree *maketree1(int, Tree*); Tree *maketree2(int, Tree*, Tree*); Tree *maketree3(int, Tree*, Tree*, Tree*); Tree *token(int, char *); Tree *hangchild1(Tree *, Tree *, int at); void freeparsetree(void); /* sys.c */ void initenv(void); void addwait(int); void clearwait(void); int waitfor(int); void execute(Word *, Word*); /* exec.c */ // XXX: odd place for this int count(Word *); Word *makeword(char *str, Word *link); void freeword(Word *w); void initpath(void); /* var.c */ Var *var(char*); Var *definevar(char*, Var *); Var *globalvar(char*); Var *makevar(char *name, Var *link); void setvar(char *, Word *); char **mkenv(void); /* code.c */ int compile(Tree *); Code *copycode(Code *c); void freecode(Code *c);