diff options
| author | Toby Goodwin <toby@paccrat.org> | 2018-02-09 06:34:34 +0000 |
|---|---|---|
| committer | Toby Goodwin <toby@paccrat.org> | 2018-02-09 06:34:34 +0000 |
| commit | 5966ab2ca2632c5bed9815def1add4859beececa (patch) | |
| tree | b4624389f9cca13cd30e6f95c60e70fad87871a8 | |
| parent | d18aac739636fd9ae1f84fef8347f46216fb8d9c (diff) | |
wip
| -rw-r--r-- | develop.c | 3 | ||||
| -rw-r--r-- | footobar.c | 1 | ||||
| -rw-r--r-- | lex.c | 1 | ||||
| -rw-r--r-- | parse.y | 4 | ||||
| -rw-r--r-- | rc.h | 2 | ||||
| -rw-r--r-- | tree.c | 12 |
6 files changed, 19 insertions, 4 deletions
@@ -118,6 +118,9 @@ void dump(Node *n, int indent) { case nIf: dump_2("nIf", n, indent); break; + case nIfnot: + dump_1("nIfnot", n, indent); + break; case nLappend: dump_2("nLappend", n, indent); break; @@ -67,6 +67,7 @@ static bool Tconv(Format *f, int ignore) { case nElse: fmtprint(f, "{%T}else %T", n->u[0].p, n->u[1].p); break; case nNewfn: fmtprint(f, "fn %T {%T}", n->u[0].p, n->u[1].p); break; case nIf: fmtprint(f, "if(%T)%T", n->u[0].p, n->u[1].p); break; + case nIfnot: fmtprint(f, "if not %T", n->u[0].p); break; case nOrelse: fmtprint(f, "%T||%T", n->u[0].p, n->u[1].p); break; case nArgs: fmtprint(f, "%T %T", n->u[0].p, n->u[1].p); break; case nSwitch: fmtprint(f, "switch(%T){%T}", n->u[0].p, n->u[1].p); break; @@ -159,6 +159,7 @@ top: while ((c = gchar()) == ' ' || c == '\t') if (*buf == 'f' && buf[1] == 'n') return FN; if (*buf == 'i' && buf[1] == 'n') return IN; } + if (streq(buf, "not")) return NOT; if (streq(buf, "for")) return FOR; if (streq(buf, "else")) return ELSE; if (streq(buf, "switch")) return SWITCH; @@ -13,7 +13,7 @@ static Node *star, *nolist; Node *parsetree; /* not using yylval because bison declares it as an auto */ %} -%token ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN +%token ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN NOT %token OROR PIPE REDIR SREDIR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD HUH %left '^' '=' @@ -103,6 +103,7 @@ cmd : /* empty */ %prec WHILE { $$ = NULL; } | simple | brace epilog { $$ = mk(nBrace,$1,$2); } | IF paren optnl iftail { $$ = mk(nIf,$2,$4); } + | IF NOT optnl cmd { $$ = mk(nIfnot,$4); } | FOR '(' word IN words ')' optnl cmd { $$ = mk(nForin,$3,$5,$8); } | FOR '(' word ')' optnl cmd { $$ = mk(nForin,$3,star,$6); } | WHILE paren optnl cmd { $$ = mk(nWhile,$2,$4); } @@ -155,6 +156,7 @@ keyword : FOR { $$ = "for"; } | IN { $$ = "in"; } | WHILE { $$ = "while"; } | IF { $$ = "if"; } + | NOT { $$ = "not"; } | SWITCH { $$ = "switch"; } | FN { $$ = "fn"; } | ELSE { $$ = "else"; } @@ -36,7 +36,7 @@ typedef union Edata Edata; typedef enum nodetype { nAndalso, nAssign, nBackq, nBang, nBody, nCbody, nNowait, nBrace, nConcat, nCount, nElse, nFlat, nDup, nEpilog, nNewfn, nForin, nIf, - nOrelse, nPipe, nPre, nRedir, nRmfn, nArgs, nSubshell, nCase, + nIfnot, nOrelse, nPipe, nPre, nRedir, nRmfn, nArgs, nSubshell, nCase, nSwitch, nMatch, nVar, nVarsub, nWhile, nWord, nLappend, nNmpipe } nodetype; @@ -26,11 +26,11 @@ extern Node *mk(int /*nodetype*/ t,...) { break; case nBang: case nNowait: case nCount: case nFlat: case nRmfn: case nSubshell: - case nVar: case nCase: + case nVar: case nCase: case nIfnot: n = nalloc(offsetof(Node, u[1])); n->u[0].p = va_arg(ap, Node *); break; - case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: + case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat: case nElse: case nEpilog: case nIf: case nNewfn: case nCbody: case nOrelse: case nPre: case nArgs: case nSwitch: case nMatch: case nVarsub: case nWhile: case nLappend: @@ -60,6 +60,14 @@ extern Node *mk(int /*nodetype*/ t,...) { break; } n->type = t; + if (t == nBody && + n->u[1].p->type == nIfnot) { + if (n->u[0].p->type == nIf) { + fprint(2, "here i am!\n"); + } else + rc_error("`if not' must follow `if'"); + + } va_end(ap); return n; } |