commit 5966ab2ca2632c5bed9815def1add4859beececa
parent d18aac739636fd9ae1f84fef8347f46216fb8d9c
Author: Toby Goodwin <toby@paccrat.org>
Date: Fri, 9 Feb 2018 06:34:34 +0000
wip
Diffstat:
6 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/develop.c b/develop.c
@@ -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;
diff --git a/footobar.c b/footobar.c
@@ -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;
diff --git a/lex.c b/lex.c
@@ -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;
diff --git a/parse.y b/parse.y
@@ -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"; }
diff --git a/rc.h b/rc.h
@@ -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;
diff --git a/tree.c b/tree.c
@@ -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;
}