From 425ef692da7e74112f88f0b368f3286dba84f846 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 18 Jun 2020 19:45:40 -0700 Subject: feat: working parser for rc shell language --- sys/cmd/rc/tree.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 sys/cmd/rc/tree.c (limited to 'sys/cmd/rc/tree.c') diff --git a/sys/cmd/rc/tree.c b/sys/cmd/rc/tree.c new file mode 100644 index 0000000..8dca67f --- /dev/null +++ b/sys/cmd/rc/tree.c @@ -0,0 +1,144 @@ +#include "rc.h" + +// ----------------------------------------------------------------------- +// globals + +static Tree *nodes; + +// ----------------------------------------------------------------------- +// exported funcs + +Tree* +newtree(void) +{ + Tree *t; + + alloc(t); + t->str = nil; + t->child[0] = t->child[1] = t->child[2] = nil; + t->redir.fd[0] = t->redir.fd[1] = t->redir.type = 0; + + t->link = nodes, nodes = t; + return t; +} + +void +freetree(Tree *t) +{ + if (!t) + return; + + freetree(t->child[0]); + freetree(t->child[1]); + freetree(t->child[2]); + + if (t->str) + efree(t->str); + efree(t); +} + +void +freenodes(void) +{ + Tree *t, *u; + + for (t = nodes;t;t = u) { + u = t->link; + if (t->str) + efree(t->str); + efree(t); + } + nodes = nil; +} + +/* tree creation */ +Tree* +tree3(int type, Tree *c0, Tree *c1, Tree *c2) +{ + Tree *t; + + t = newtree(); + t->type = type; + t->child[0] = c0; + t->child[1] = c1; + t->child[2] = c2; + + return t; +} + +Tree* +tree2(int type, Tree *c0, Tree *c1) +{ + return tree3(type, c0, c1, nil); +} + +Tree* +tree1(int type, Tree *c0) +{ + return tree3(type, c0, nil, nil); +} + +/* tree hang */ +Tree* +hang1(Tree *p, Tree *c0) +{ + p->child[0] = c0; + return p; +} + +Tree* +hang2(Tree *p, Tree *c0, Tree *c1) +{ + p->child[0] = c0; + p->child[1] = c1; + return p; +} + +Tree* +hang3(Tree *p, Tree *c0, Tree *c1, Tree *c2) +{ + p->child[0] = c0; + p->child[1] = c1; + p->child[2] = c2; + return p; +} + +/* hangs the cmd underneath the epilogue */ +Tree* +epihang(Tree *c, Tree *epi) +{ + Tree *p; + if(!epi) + return c; + for(p=epi;p->child[1];p = p->child[1]) + ; + p->child[1] = c; + return epi; +} + +/* hangs tree t from a new simple node. percolates redirections to root */ +Tree* +simplehang(Tree *t) +{ + Tree *u; + t = tree1(Asimple, t); + for(u = t->child[0];u->type==Aargs;u=u->child[0]) { + if (u->child[1]->type==Adup + || u->child[1]->type==Aredir){ + u->child[1]->child[1] = t; + t = u->child[1]; + u->child[1] = nil; + } + } + return t; +} + +Tree* +wordnode(char *w) +{ + Tree *t = newtree(); + t->type = Aword; + t->str = strdup(w); + + return t; +} -- cgit v1.2.1