aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas <nbnoll@eml.cc>2021-11-15 19:48:42 -0800
committerNicholas <nbnoll@eml.cc>2021-11-15 19:48:42 -0800
commite4f9b993e97b6e6e790810b6d261dc5bf61b0513 (patch)
treedb386a2dd2b58e207deb1e3f44a84e76827c2621
parenta93cc453bd8072e7d79ebe8f00614e1b99eb5852 (diff)
Feat: added functions
-rw-r--r--src/cmd/rc/code.c36
-rw-r--r--src/cmd/rc/exec.c42
-rw-r--r--src/cmd/rc/exec.h2
-rw-r--r--src/cmd/rc/io.c66
-rw-r--r--src/cmd/rc/parse.c499
-rw-r--r--src/cmd/rc/rc.h5
-rw-r--r--src/cmd/rc/syntax.y3
-rw-r--r--src/cmd/rc/var.c15
8 files changed, 396 insertions, 272 deletions
diff --git a/src/cmd/rc/code.c b/src/cmd/rc/code.c
index 7077a0e..201ecc2 100644
--- a/src/cmd/rc/code.c
+++ b/src/cmd/rc/code.c
@@ -38,10 +38,22 @@ storepc(int a)
interpreter.code[a].i = interpreter.i;
}
+static char *
+funcstr(Tree *node)
+{
+ char *v;
+ Io *io = openstr();
+
+ print(io, "%t", node);
+ v = io->s, io->s = nil;
+ terminate(io);
+
+ return v;
+}
+
void yyerror(const char *msg);
-static
-void
+static void
walk(Tree *node)
{
Tree *n, *c;
@@ -68,6 +80,18 @@ walk(Tree *node)
emitf(Xcount);
break;
+ case Tfunc:
+ emitf(Xmark);
+ walk(node->child[0]);
+ emitf(Xfunc);
+ addr1 = emiti(0);
+ emits(funcstr(node->child[1])); // XXX: why?
+ walk(node->child[1]);
+ emitf(Xunlocal); /* clean $* */
+ emitf(Xreturn);
+ storepc(addr1);
+ break;
+
case Tjoin:
emitf(Xmark);
walk(node->child[0]);
@@ -228,6 +252,14 @@ walk(Tree *node)
storepc(addr3);
break;
+ case Ttwiddle:
+ emitf(Xmark);
+ walk(c->child[1]);
+ emitf(Xmark);
+ walk(c->child[0]);
+ emitf(Xmatch);
+ break;
+
case Twhile:
addr1 = interpreter.i; // head of loop
walk(node->child[0]);
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index 2bdaebd..71f5359 100644
--- a/src/cmd/rc/exec.c
+++ b/src/cmd/rc/exec.c
@@ -336,9 +336,26 @@ run(Code *c, int pc, Var *local, int inherit)
runner = new;
}
+
// -----------------------------------------------------------------------
// exported builtins
+void
+xfunc(Var *v)
+{
+ Word *star;
+ popword(); // "func"
+ star = runner->args->word;
+ runner->args->word = nil;
+ poplist(); // args
+
+ run(v->func.code, v->func.start, runner->local, 1);
+
+ runner->local = makevar(strdup("*"), runner->local);
+ runner->local->val = star;
+ runner->local->new = 1;
+}
+
// XXX: find a better place for these
Word*
makeword(char *str, Word *link)
@@ -1062,6 +1079,26 @@ Xunlocal(void)
}
void
+Xfunc(void)
+{
+ Var *v;
+ Word *arg;
+ int end;
+
+ end = runner->code.exe[runner->code.i].i;
+ for(arg=runner->args->word; arg; arg=arg->link){
+ v = var(arg->str);
+ if(v->func.code)
+ freecode(v->func.code);
+ v->func.code = copycode(runner->code.exe);
+ v->func.start = runner->code.i+2;
+ v->newfunc = 1;
+ }
+ runner->code.i = end;
+ poplist();
+}
+
+void
Xasync(void)
{
int pid;
@@ -1193,9 +1230,8 @@ Xbasic(void)
}
v = var(arg->str);
- if(v->func){
- return;
- }
+ if(v->func.code)
+ return xfunc(v);
// see if it matches a builtin
for(b = builtin; b->name; b++){
diff --git a/src/cmd/rc/exec.h b/src/cmd/rc/exec.h
index d14c0f6..1a81644 100644
--- a/src/cmd/rc/exec.h
+++ b/src/cmd/rc/exec.h
@@ -8,6 +8,7 @@
*/
void Xcase(void);
+void Xfunc(void);
void Xmatch(void);
void Xmark(void); // Xmark marks stack location for word
void Xindex(void); // Xindex
@@ -46,5 +47,6 @@ void xecho(void);
void xexit(void);
void xfg(void);
void xjob(void);
+void xfunc(Var *v);
void xboot(int argc, char *argv[]);
diff --git a/src/cmd/rc/io.c b/src/cmd/rc/io.c
index dc81c2e..5152627 100644
--- a/src/cmd/rc/io.c
+++ b/src/cmd/rc/io.c
@@ -74,8 +74,7 @@ terminate(Io *io)
efree((char *)io);
}
-static
-int
+static int
refill(Io *io)
{
int n;
@@ -224,28 +223,55 @@ static
void
printtree(Io *io, Tree *t)
{
+ Tree *c, *nc;
if(!t)
return;
switch(t->type){
- default: print(io, "bad(%d)[%p %p %p]", t->type, C0, C1, C2); break;
- case '$': print(io,"$%t",C0); break;
- case '&': print(io,"%t&",C0); break;
- case '^': print(io,"%t^%t",C0,C1); break;
- case '`': print(io,"`%t",C0); break;
-
- case Tbasic: print(io, "%t", C0); break;
- case Tbang: print(io, "!%t", C0); break;
- case Tblock: print(io, "{%t}", C0); break;
- case Tcount: print(io, "$#%t", C0); break;
- case Tparen: print(io, "(%t)", C0); break;
- case Tjoin: print(io,"$\"%t",C0); break;
- case Tindex: print(io, "%t(%t)",C0); break;
- case Tsubshell: print(io, "@ %t",C0); break;
- //case Ttwiddle: print(io, "~ %t %t", C0, C1); break;
-
- case Toror:
- case Tandand:
+ default:
+ print(io, "bad(%d)[%p %p %p]", t->type, C0, C1, C2);
+ break;
+
+ case '$': print(io,"$%t",C0); break;
+ case '&': print(io,"%t&",C0); break;
+ case '^': print(io,"%t^%t",C0,C1); break;
+ case '`': print(io,"`%t",C0); break;
+ case Tbasic: print(io, "%t", C0); break;
+ case Tbang: print(io, "!%t", C0); break;
+ case Tblock: print(io, "{%t}", C0); break;
+ case Tcount: print(io, "$#%t", C0); break;
+ case Tparen: print(io, "(%t)", C0); break;
+ case Tjoin: print(io,"$\"%t",C0); break;
+ case Tindex: print(io, "%t(%t)",C0); break;
+ case Tsubshell: print(io, "@ %t",C0); break;
+ case Ttwiddle: print(io, "~ %t %t", C0, C1); break;
+ case Toror: print(io, "%t || %t", C0, C1); break;
+ case Tandand: print(io, "%t && %t", C0, C1); break;
+ case Twhile: print(io, "while %t%t", C0, C1); break;
+ case Tcase: print(io, "case %t;%t",C0, C1); break;
+ case Tfunc: print(io, "func %t %t",C0, C1); break;
+ case Tswitch:
+ print(io, "switch %t {", C0);
+ c = C1;
+ cases:
+ if(c->type == ';'){
+ nc = c->child[1], c = c->child[0];
+ print(io,"%t",c);
+ c = nc;
+ assert(c);
+ goto cases;
+ }else{
+ print(io,"%t",c);
+ }
+ print(io, "}");
+ break;
+
+ case Tfor:
+ print(io, "for(%t", C0);
+ if(C1)
+ print(io, "in %t", C1);
+ print(io, ")%t", C2);
+ break;
case Targs:
if(!C0)
diff --git a/src/cmd/rc/parse.c b/src/cmd/rc/parse.c
index c16a578..e57bf2e 100644
--- a/src/cmd/rc/parse.c
+++ b/src/cmd/rc/parse.c
@@ -485,18 +485,18 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 56
+#define YYFINAL 61
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 442
+#define YYLAST 486
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 40
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 24
/* YYNRULES -- Number of rules. */
-#define YYNRULES 71
+#define YYNRULES 74
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 129
+#define YYNSTATES 136
/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK 283
@@ -551,11 +551,11 @@ static const yytype_uint8 yyrline[] =
0, 38, 38, 39, 42, 43, 46, 47, 50, 53,
56, 57, 60, 61, 64, 65, 68, 71, 72, 75,
78, 79, 82, 83, 86, 87, 88, 89, 90, 91,
- 92, 93, 94, 95, 96, 97, 98, 99, 100, 103,
- 104, 105, 108, 109, 112, 113, 116, 117, 120, 121,
- 122, 123, 124, 125, 126, 130, 130, 130, 130, 130,
- 130, 130, 130, 130, 130, 133, 134, 137, 138, 139,
- 141, 143
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 105, 106, 107, 110, 111, 114, 115, 118, 119,
+ 122, 123, 124, 125, 126, 127, 128, 132, 132, 132,
+ 132, 132, 132, 132, 132, 132, 132, 132, 135, 136,
+ 139, 140, 141, 143, 145
};
#endif
@@ -601,7 +601,7 @@ static const yytype_int16 yytoknum[] =
};
#endif
-#define YYPACT_NINF (-91)
+#define YYPACT_NINF (-44)
#define yypact_value_is_default(Yyn) \
((Yyn) == YYPACT_NINF)
@@ -615,19 +615,20 @@ static const yytype_int16 yytoknum[] =
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 117, -22, -10, -10, 22, 403, 403, 339, -91, -91,
- 339, 339, 339, -91, 403, -24, 39, 40, 43, 403,
- 403, 403, 72, 154, -5, -91, 339, 403, -91, -91,
- 339, 45, 45, -91, -91, -91, -91, -91, -91, -91,
- -91, -91, -91, -91, 38, -91, -91, 51, -91, -91,
- 191, 35, -91, 403, 9, -91, -91, -91, 43, -91,
- -91, 45, 45, -91, -91, -91, -91, -91, -91, 38,
- 339, 339, 18, 46, 371, 371, 19, 339, -91, -91,
- -91, 38, -91, -91, -91, -91, 371, 371, 371, -91,
- 38, -91, -91, -91, -91, 14, 49, -91, 14, -91,
- -91, 228, -91, 45, 45, 265, 371, -91, 32, -91,
- 38, -91, 14, 371, -91, 371, 14, -1, 14, -91,
- 68, 47, 302, -91, -91, -91, 371, -91, 9
+ 124, -18, -16, -16, 19, 415, 447, 447, -44, 415,
+ -44, -44, 415, 415, 415, -44, 447, -9, 55, 36,
+ 56, 447, 447, 447, 73, 161, 15, -44, 415, 447,
+ -44, -44, 415, -44, -44, -44, -44, -44, -44, -44,
+ -44, -44, -44, -44, -44, 39, -44, -44, 59, 59,
+ 235, 39, 60, -44, -44, 198, 38, -44, 447, -8,
+ -44, -44, -44, 56, -44, -44, 59, 59, -44, -44,
+ -44, -44, -44, -44, 39, 415, 415, 12, 61, 267,
+ 267, 32, 415, 415, -44, 39, -44, -44, -44, 39,
+ -44, -44, -44, -44, 267, 267, 267, -44, 39, -44,
+ -44, -44, -44, 33, 51, -44, 33, -44, -44, 304,
+ -44, 59, 59, 341, 267, -44, 17, -44, -44, 33,
+ 267, -44, 267, 33, 5, 33, -44, 75, 52, 378,
+ -44, -44, -44, 267, -44, -8
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -635,35 +636,36 @@ static const yytype_int16 yypact[] =
means the default is an error. */
static const yytype_int8 yydefact[] =
{
- 24, 0, 0, 0, 0, 24, 24, 0, 20, 48,
- 0, 0, 0, 67, 24, 0, 0, 0, 22, 24,
- 24, 24, 4, 25, 39, 46, 0, 24, 70, 70,
- 0, 32, 33, 55, 56, 57, 58, 59, 60, 61,
- 62, 63, 64, 44, 21, 42, 43, 49, 52, 53,
- 0, 0, 12, 24, 6, 54, 1, 3, 22, 26,
- 5, 31, 30, 70, 70, 70, 10, 11, 41, 40,
- 0, 0, 0, 0, 24, 24, 0, 0, 65, 51,
- 68, 69, 9, 7, 13, 23, 24, 24, 24, 47,
- 19, 65, 70, 8, 71, 36, 22, 37, 14, 70,
- 45, 0, 27, 28, 29, 0, 24, 70, 0, 50,
- 66, 70, 34, 24, 70, 24, 15, 17, 35, 65,
- 17, 0, 0, 18, 38, 70, 24, 16, 0
+ 24, 0, 0, 0, 0, 0, 24, 24, 68, 0,
+ 20, 50, 0, 0, 0, 70, 24, 0, 0, 0,
+ 22, 24, 24, 24, 4, 25, 41, 48, 0, 24,
+ 73, 73, 0, 57, 58, 59, 60, 61, 62, 63,
+ 66, 64, 65, 67, 46, 68, 44, 45, 32, 33,
+ 0, 21, 51, 54, 55, 0, 0, 12, 24, 6,
+ 56, 1, 3, 22, 26, 5, 31, 30, 73, 73,
+ 73, 10, 11, 43, 42, 0, 0, 0, 0, 24,
+ 24, 0, 0, 34, 40, 69, 68, 53, 71, 72,
+ 9, 7, 13, 23, 24, 24, 24, 49, 19, 68,
+ 73, 8, 74, 37, 22, 38, 14, 73, 47, 0,
+ 27, 28, 29, 0, 24, 73, 0, 52, 73, 35,
+ 24, 73, 24, 15, 17, 36, 68, 17, 0, 0,
+ 18, 39, 73, 24, 16, 0
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -91, -91, 65, -23, 87, -12, 34, -35, -91, -91,
- -28, -91, -16, 36, 0, -91, 6, 31, -91, 2,
- -91, -90, -91, -14
+ -44, -44, 77, -26, 98, 13, 26, -28, -44, -44,
+ -24, -44, -15, 43, 0, -44, 22, 37, -44, -1,
+ -44, -43, -44, -30
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const yytype_int8 yydefgoto[] =
+static const yytype_uint8 yydefgoto[] =
{
- 0, 16, 17, 51, 28, 18, 52, 53, 97, 120,
- 121, 20, 21, 59, 54, 23, 43, 110, 24, 25,
- 46, 101, 50, 74
+ 0, 18, 19, 56, 30, 20, 57, 58, 105, 127,
+ 128, 22, 23, 64, 59, 25, 44, 85, 26, 27,
+ 47, 50, 55, 79
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -671,119 +673,128 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int16 yytable[] =
{
- 22, 105, 58, 55, 73, 31, 32, 68, 119, 45,
- 14, 26, 45, 45, 45, 75, 47, 48, 49, 22,
- 61, 62, 91, 27, 70, 45, 63, 94, 45, 122,
- 83, 63, 45, 71, 19, 64, 65, 84, 44, 56,
- 64, 65, 58, 92, 99, 66, 67, 77, 77, 86,
- 87, 88, 45, 19, 69, 30, 107, 72, 7, 8,
- 94, 76, 63, 96, 7, 8, 114, 77, 57, 78,
- 82, 93, 45, 45, 95, 98, 89, 119, 106, 45,
- 58, 81, 124, 100, 60, 108, 102, 103, 104, 63,
- 29, 127, 123, 113, 85, 0, 0, 115, 64, 65,
- 117, 0, 90, 45, 0, 0, 112, 45, 66, 67,
- 0, 126, 0, 116, 0, 118, 0, -2, 0, 0,
- 1, 0, 2, 3, 45, 4, 128, 0, 0, 5,
- 6, 0, 7, 8, 0, 0, 0, 0, 9, 0,
- 0, 0, 0, 0, 0, 0, 0, 10, 11, 12,
- 13, 14, 0, 0, 0, 0, 15, 33, 34, 35,
- 36, 37, 38, 39, 0, 0, 40, 41, 42, 7,
- 8, 0, 0, 0, 0, 9, 0, 0, 0, 0,
- 0, 0, 0, 0, 10, 11, 12, 13, 0, 0,
- 0, 0, 0, 15, 33, 34, 35, 36, 37, 38,
- 39, 0, 0, 40, 41, 42, 0, 0, 0, 0,
- 0, 0, 9, 0, 0, 0, 79, 0, 0, 80,
- 0, 10, 11, 12, 13, 0, 0, 0, 0, 0,
- 15, 33, 34, 35, 36, 37, 38, 39, 0, 0,
- 40, 41, 42, 0, 0, 0, 0, 0, 0, 9,
- 0, 0, 0, 109, 0, 0, 0, 0, 10, 11,
- 12, 13, 0, 0, 0, 0, 0, 15, 33, 34,
- 35, 36, 37, 38, 39, 0, 0, 40, 41, 42,
- 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,
- 111, 0, 0, 0, 0, 10, 11, 12, 13, 0,
- 0, 0, 0, 0, 15, 33, 34, 35, 36, 37,
- 38, 39, 0, 0, 40, 41, 42, 0, 0, 0,
- 0, 0, 0, 9, 0, 0, 0, 0, 0, 0,
- 0, 0, 10, 11, 12, 13, 0, 0, 125, 0,
- 0, 15, 33, 34, 35, 36, 37, 38, 39, 0,
- 0, 40, 41, 42, 0, 0, 0, 0, 0, 0,
- 9, 0, 0, 0, 0, 0, 0, 0, 0, 10,
- 11, 12, 13, 0, 1, 0, 2, 3, 15, 4,
- 0, 0, 0, 5, 6, 0, 7, 8, 0, 0,
- 0, 0, 9, 0, 0, 0, 0, 0, 0, 94,
- 0, 10, 11, 12, 13, 14, 1, 0, 2, 3,
- 15, 4, 0, 0, 0, 5, 6, 0, 7, 8,
- 0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
- 0, 0, 0, 10, 11, 12, 13, 14, 0, 0,
- 0, 0, 15
+ 24, 80, 83, 78, 46, 63, 48, 49, 46, 68,
+ 73, 46, 46, 46, 126, 28, 99, 29, 69, 70,
+ 92, 24, 66, 67, 46, 16, 21, 46, 71, 72,
+ 60, 46, 91, 102, 52, 53, 54, 100, 94, 95,
+ 96, 82, 45, 109, 75, 102, 51, 21, 63, 46,
+ 68, 121, 32, 76, 46, 61, 113, 107, 115, 69,
+ 70, 82, 74, 84, 62, 77, 9, 10, 82, 81,
+ 114, 9, 10, 90, 46, 46, 68, 116, 86, 103,
+ 106, 46, 46, 129, 126, 120, 101, 131, 122, 63,
+ 68, 124, 89, 104, 110, 111, 112, 97, 65, 69,
+ 70, 31, 133, 130, 108, 134, 93, 0, 46, 71,
+ 72, 0, 46, 98, 119, 0, 0, 0, 0, 0,
+ 123, 0, 125, 0, -2, 0, 0, 1, 46, 2,
+ 3, 0, 4, 135, 0, 5, 6, 7, 8, 9,
+ 10, 0, 0, 0, 0, 11, 0, 0, 0, 0,
+ 0, 0, 0, 0, 12, 13, 14, 15, 16, 0,
+ 0, 0, 0, 17, 33, 34, 35, 36, 37, 38,
+ 39, 0, 40, 41, 42, 43, 9, 10, 0, 0,
+ 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 12, 13, 14, 15, 0, 0, 0, 0, 0,
+ 17, 33, 34, 35, 36, 37, 38, 39, 0, 40,
+ 41, 42, 43, 0, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 87, 0, 0, 88, 0, 12, 13,
+ 14, 15, 0, 0, 0, 0, 0, 17, 33, 34,
+ 35, 36, 37, 38, 39, 0, 40, 41, 42, 43,
+ 0, 0, 0, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 12, 13, 14, 15, 16,
+ 1, 0, 2, 3, 17, 4, 0, 0, 5, 6,
+ 7, 8, 9, 10, 0, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 102, 0, 12, 13, 14,
+ 15, 16, 0, 0, 0, 0, 17, 33, 34, 35,
+ 36, 37, 38, 39, 0, 40, 41, 42, 43, 0,
+ 0, 0, 0, 0, 0, 11, 0, 0, 0, 117,
+ 0, 0, 0, 0, 12, 13, 14, 15, 0, 0,
+ 0, 0, 0, 17, 33, 34, 35, 36, 37, 38,
+ 39, 0, 40, 41, 42, 43, 0, 0, 0, 0,
+ 0, 0, 11, 0, 0, 0, 118, 0, 0, 0,
+ 0, 12, 13, 14, 15, 0, 0, 0, 0, 0,
+ 17, 33, 34, 35, 36, 37, 38, 39, 0, 40,
+ 41, 42, 43, 0, 0, 0, 0, 0, 0, 11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
+ 14, 15, 0, 0, 132, 0, 0, 17, 33, 34,
+ 35, 36, 37, 38, 39, 0, 40, 41, 42, 43,
+ 0, 0, 0, 0, 0, 0, 11, 0, 0, 0,
+ 0, 0, 0, 0, 0, 12, 13, 14, 15, 0,
+ 1, 0, 2, 3, 17, 4, 0, 0, 5, 6,
+ 7, 8, 9, 10, 0, 0, 0, 0, 11, 0,
+ 0, 0, 0, 0, 0, 0, 0, 12, 13, 14,
+ 15, 16, 0, 0, 0, 0, 17
};
-static const yytype_int8 yycheck[] =
+static const yytype_int16 yycheck[] =
{
- 0, 91, 18, 15, 27, 5, 6, 23, 9, 7,
- 34, 33, 10, 11, 12, 29, 10, 11, 12, 19,
- 20, 21, 4, 33, 29, 23, 17, 28, 26, 119,
- 53, 17, 30, 38, 0, 26, 27, 28, 7, 0,
- 26, 27, 58, 25, 25, 36, 37, 29, 29, 63,
- 64, 65, 50, 19, 23, 33, 7, 26, 15, 16,
- 28, 30, 17, 75, 15, 16, 34, 29, 28, 18,
- 35, 25, 70, 71, 74, 75, 70, 9, 92, 77,
- 96, 50, 35, 77, 19, 99, 86, 87, 88, 17,
- 3, 126, 120, 107, 58, -1, -1, 111, 26, 27,
- 114, -1, 71, 101, -1, -1, 106, 105, 36, 37,
- -1, 125, -1, 113, -1, 115, -1, 0, -1, -1,
- 3, -1, 5, 6, 122, 8, 126, -1, -1, 12,
- 13, -1, 15, 16, -1, -1, -1, -1, 21, -1,
- -1, -1, -1, -1, -1, -1, -1, 30, 31, 32,
- 33, 34, -1, -1, -1, -1, 39, 3, 4, 5,
- 6, 7, 8, 9, -1, -1, 12, 13, 14, 15,
+ 0, 31, 45, 29, 5, 20, 6, 7, 9, 17,
+ 25, 12, 13, 14, 9, 33, 4, 33, 26, 27,
+ 28, 21, 22, 23, 25, 34, 0, 28, 36, 37,
+ 17, 32, 58, 28, 12, 13, 14, 25, 68, 69,
+ 70, 29, 5, 86, 29, 28, 9, 21, 63, 50,
+ 17, 34, 33, 38, 55, 0, 99, 25, 7, 26,
+ 27, 29, 25, 50, 28, 28, 15, 16, 29, 32,
+ 100, 15, 16, 35, 75, 76, 17, 107, 18, 79,
+ 80, 82, 83, 126, 9, 115, 25, 35, 118, 104,
+ 17, 121, 55, 80, 94, 95, 96, 75, 21, 26,
+ 27, 3, 132, 127, 82, 133, 63, -1, 109, 36,
+ 37, -1, 113, 76, 114, -1, -1, -1, -1, -1,
+ 120, -1, 122, -1, 0, -1, -1, 3, 129, 5,
+ 6, -1, 8, 133, -1, 11, 12, 13, 14, 15,
16, -1, -1, -1, -1, 21, -1, -1, -1, -1,
- -1, -1, -1, -1, 30, 31, 32, 33, -1, -1,
+ -1, -1, -1, -1, 30, 31, 32, 33, 34, -1,
-1, -1, -1, 39, 3, 4, 5, 6, 7, 8,
- 9, -1, -1, 12, 13, 14, -1, -1, -1, -1,
- -1, -1, 21, -1, -1, -1, 25, -1, -1, 28,
+ 9, -1, 11, 12, 13, 14, 15, 16, -1, -1,
+ -1, -1, 21, -1, -1, -1, -1, -1, -1, -1,
-1, 30, 31, 32, 33, -1, -1, -1, -1, -1,
- 39, 3, 4, 5, 6, 7, 8, 9, -1, -1,
+ 39, 3, 4, 5, 6, 7, 8, 9, -1, 11,
12, 13, 14, -1, -1, -1, -1, -1, -1, 21,
- -1, -1, -1, 25, -1, -1, -1, -1, 30, 31,
+ -1, -1, -1, 25, -1, -1, 28, -1, 30, 31,
32, 33, -1, -1, -1, -1, -1, 39, 3, 4,
- 5, 6, 7, 8, 9, -1, -1, 12, 13, 14,
+ 5, 6, 7, 8, 9, -1, 11, 12, 13, 14,
+ -1, -1, -1, -1, -1, -1, 21, -1, -1, -1,
+ -1, -1, -1, -1, -1, 30, 31, 32, 33, 34,
+ 3, -1, 5, 6, 39, 8, -1, -1, 11, 12,
+ 13, 14, 15, 16, -1, -1, -1, -1, 21, -1,
+ -1, -1, -1, -1, -1, 28, -1, 30, 31, 32,
+ 33, 34, -1, -1, -1, -1, 39, 3, 4, 5,
+ 6, 7, 8, 9, -1, 11, 12, 13, 14, -1,
+ -1, -1, -1, -1, -1, 21, -1, -1, -1, 25,
+ -1, -1, -1, -1, 30, 31, 32, 33, -1, -1,
+ -1, -1, -1, 39, 3, 4, 5, 6, 7, 8,
+ 9, -1, 11, 12, 13, 14, -1, -1, -1, -1,
+ -1, -1, 21, -1, -1, -1, 25, -1, -1, -1,
+ -1, 30, 31, 32, 33, -1, -1, -1, -1, -1,
+ 39, 3, 4, 5, 6, 7, 8, 9, -1, 11,
+ 12, 13, 14, -1, -1, -1, -1, -1, -1, 21,
+ -1, -1, -1, -1, -1, -1, -1, -1, 30, 31,
+ 32, 33, -1, -1, 36, -1, -1, 39, 3, 4,
+ 5, 6, 7, 8, 9, -1, 11, 12, 13, 14,
-1, -1, -1, -1, -1, -1, 21, -1, -1, -1,
- 25, -1, -1, -1, -1, 30, 31, 32, 33, -1,
- -1, -1, -1, -1, 39, 3, 4, 5, 6, 7,
- 8, 9, -1, -1, 12, 13, 14, -1, -1, -1,
- -1, -1, -1, 21, -1, -1, -1, -1, -1, -1,
- -1, -1, 30, 31, 32, 33, -1, -1, 36, -1,
- -1, 39, 3, 4, 5, 6, 7, 8, 9, -1,
- -1, 12, 13, 14, -1, -1, -1, -1, -1, -1,
- 21, -1, -1, -1, -1, -1, -1, -1, -1, 30,
- 31, 32, 33, -1, 3, -1, 5, 6, 39, 8,
- -1, -1, -1, 12, 13, -1, 15, 16, -1, -1,
- -1, -1, 21, -1, -1, -1, -1, -1, -1, 28,
- -1, 30, 31, 32, 33, 34, 3, -1, 5, 6,
- 39, 8, -1, -1, -1, 12, 13, -1, 15, 16,
- -1, -1, -1, -1, 21, -1, -1, -1, -1, -1,
- -1, -1, -1, 30, 31, 32, 33, 34, -1, -1,
- -1, -1, 39
+ -1, -1, -1, -1, -1, 30, 31, 32, 33, -1,
+ 3, -1, 5, 6, 39, 8, -1, -1, 11, 12,
+ 13, 14, 15, 16, -1, -1, -1, -1, 21, -1,
+ -1, -1, -1, -1, -1, -1, -1, 30, 31, 32,
+ 33, 34, -1, -1, -1, -1, 39
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const yytype_int8 yystos[] =
{
- 0, 3, 5, 6, 8, 12, 13, 15, 16, 21,
- 30, 31, 32, 33, 34, 39, 41, 42, 45, 46,
- 51, 52, 54, 55, 58, 59, 33, 33, 44, 44,
- 33, 54, 54, 3, 4, 5, 6, 7, 8, 9,
- 12, 13, 14, 56, 57, 59, 60, 56, 56, 56,
- 62, 43, 46, 47, 54, 45, 0, 28, 52, 53,
- 42, 54, 54, 17, 26, 27, 36, 37, 52, 57,
- 29, 38, 57, 43, 63, 63, 57, 29, 18, 25,
- 28, 57, 35, 43, 28, 53, 63, 63, 63, 56,
- 57, 4, 25, 25, 28, 54, 45, 48, 54, 25,
- 56, 61, 54, 54, 54, 61, 63, 7, 63, 25,
- 57, 25, 54, 63, 34, 63, 54, 63, 54, 9,
- 49, 50, 61, 50, 35, 36, 63, 47, 54
+ 0, 3, 5, 6, 8, 11, 12, 13, 14, 15,
+ 16, 21, 30, 31, 32, 33, 34, 39, 41, 42,
+ 45, 46, 51, 52, 54, 55, 58, 59, 33, 33,
+ 44, 44, 33, 3, 4, 5, 6, 7, 8, 9,
+ 11, 12, 13, 14, 56, 57, 59, 60, 54, 54,
+ 61, 57, 56, 56, 56, 62, 43, 46, 47, 54,
+ 45, 0, 28, 52, 53, 42, 54, 54, 17, 26,
+ 27, 36, 37, 52, 57, 29, 38, 57, 43, 63,
+ 63, 57, 29, 61, 45, 57, 18, 25, 28, 57,
+ 35, 43, 28, 53, 63, 63, 63, 56, 57, 4,
+ 25, 25, 28, 54, 45, 48, 54, 25, 56, 61,
+ 54, 54, 54, 61, 63, 7, 63, 25, 25, 54,
+ 63, 34, 63, 54, 63, 54, 9, 49, 50, 61,
+ 50, 35, 36, 63, 47, 54
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -792,11 +803,11 @@ static const yytype_int8 yyr1[] =
0, 40, 41, 41, 42, 42, 43, 43, 44, 45,
46, 46, 47, 47, 48, 48, 49, 50, 50, 51,
52, 52, 53, 53, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54, 54, 54, 54, 54, 54, 55,
- 55, 55, 56, 56, 57, 57, 58, 58, 59, 59,
- 59, 59, 59, 59, 59, 60, 60, 60, 60, 60,
- 60, 60, 60, 60, 60, 61, 61, 62, 62, 62,
- 63, 63
+ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+ 54, 55, 55, 55, 56, 56, 57, 57, 58, 58,
+ 59, 59, 59, 59, 59, 59, 59, 60, 60, 60,
+ 60, 60, 60, 60, 60, 60, 60, 60, 61, 61,
+ 62, 62, 62, 63, 63
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -805,11 +816,11 @@ static const yytype_int8 yyr2[] =
0, 2, 0, 2, 1, 2, 1, 2, 3, 3,
2, 2, 1, 2, 1, 4, 5, 0, 2, 3,
1, 2, 0, 2, 0, 1, 2, 4, 4, 4,
- 2, 2, 2, 2, 6, 8, 4, 4, 9, 1,
- 2, 2, 1, 1, 1, 3, 1, 3, 1, 2,
- 5, 3, 2, 2, 2, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 2, 0, 2, 2,
- 0, 2
+ 2, 2, 2, 2, 3, 6, 8, 4, 4, 9,
+ 3, 1, 2, 2, 1, 1, 1, 3, 1, 3,
+ 1, 2, 5, 3, 2, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2,
+ 0, 2, 2, 0, 2
};
@@ -1549,281 +1560,293 @@ yyreduce:
case 2: /* rc: %empty */
#line 38 "src/cmd/rc/syntax.y"
{ return 0; }
-#line 1553 "src/cmd/rc/parse.c"
+#line 1564 "src/cmd/rc/parse.c"
break;
case 3: /* rc: line '\n' */
#line 39 "src/cmd/rc/syntax.y"
{ return compile((yyvsp[-1].tree)); }
-#line 1559 "src/cmd/rc/parse.c"
+#line 1570 "src/cmd/rc/parse.c"
break;
case 5: /* line: cmds line */
#line 43 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1565 "src/cmd/rc/parse.c"
+#line 1576 "src/cmd/rc/parse.c"
break;
case 7: /* body: cmdsln body */
#line 47 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1571 "src/cmd/rc/parse.c"
+#line 1582 "src/cmd/rc/parse.c"
break;
case 8: /* paren: '(' body ')' */
#line 50 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tparen, (yyvsp[-1].tree)); }
-#line 1577 "src/cmd/rc/parse.c"
+#line 1588 "src/cmd/rc/parse.c"
break;
case 9: /* block: '{' body '}' */
#line 53 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tblock, (yyvsp[-1].tree)); }
-#line 1583 "src/cmd/rc/parse.c"
+#line 1594 "src/cmd/rc/parse.c"
break;
case 11: /* cmds: cmd '&' */
#line 57 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('&', (yyvsp[-1].tree)); }
-#line 1589 "src/cmd/rc/parse.c"
+#line 1600 "src/cmd/rc/parse.c"
break;
case 14: /* ifbody: cmd */
#line 64 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tif, nil, (yyvsp[0].tree)); }
-#line 1595 "src/cmd/rc/parse.c"
+#line 1606 "src/cmd/rc/parse.c"
break;
case 15: /* ifbody: block Telse nl cmd */
#line 65 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree3(Tif, nil, (yyvsp[-3].tree), (yyvsp[-2].tree)); }
-#line 1601 "src/cmd/rc/parse.c"
+#line 1612 "src/cmd/rc/parse.c"
break;
case 16: /* case: Tcase words ';' nl cmdsln */
#line 68 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild2((yyvsp[-4].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1);}
-#line 1607 "src/cmd/rc/parse.c"
+#line 1618 "src/cmd/rc/parse.c"
break;
case 17: /* casebody: %empty */
#line 71 "src/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1613 "src/cmd/rc/parse.c"
+#line 1624 "src/cmd/rc/parse.c"
break;
case 18: /* casebody: case casebody */
#line 72 "src/cmd/rc/syntax.y"
{ (yyval.tree) = (!(yyvsp[0].tree)) ? (yyvsp[-1].tree) : maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1619 "src/cmd/rc/parse.c"
+#line 1630 "src/cmd/rc/parse.c"
break;
case 19: /* assign: executable '=' word */
#line 75 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('=', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1625 "src/cmd/rc/parse.c"
+#line 1636 "src/cmd/rc/parse.c"
break;
case 21: /* redir: Tredir word */
#line 79 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 0); }
-#line 1631 "src/cmd/rc/parse.c"
+#line 1642 "src/cmd/rc/parse.c"
break;
case 22: /* epilog: %empty */
#line 82 "src/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1637 "src/cmd/rc/parse.c"
+#line 1648 "src/cmd/rc/parse.c"
break;
case 23: /* epilog: redir epilog */
#line 83 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
-#line 1643 "src/cmd/rc/parse.c"
+#line 1654 "src/cmd/rc/parse.c"
break;
case 24: /* cmd: %empty */
#line 86 "src/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1649 "src/cmd/rc/parse.c"
+#line 1660 "src/cmd/rc/parse.c"
break;
case 25: /* cmd: basic */
#line 87 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbasic, (yyvsp[0].tree)); }
-#line 1655 "src/cmd/rc/parse.c"
+#line 1666 "src/cmd/rc/parse.c"
break;
case 26: /* cmd: block epilog */
#line 88 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangepilog((yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1661 "src/cmd/rc/parse.c"
+#line 1672 "src/cmd/rc/parse.c"
break;
case 27: /* cmd: cmd Tpipe nl cmd */
#line 89 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1); }
-#line 1667 "src/cmd/rc/parse.c"
+#line 1678 "src/cmd/rc/parse.c"
break;
case 28: /* cmd: cmd Tandand nl cmd */
#line 90 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tandand, (yyvsp[-3].tree), (yyvsp[0].tree)); }
-#line 1673 "src/cmd/rc/parse.c"
+#line 1684 "src/cmd/rc/parse.c"
break;
case 29: /* cmd: cmd Toror nl cmd */
#line 91 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Toror, (yyvsp[-3].tree), (yyvsp[0].tree)); }
-#line 1679 "src/cmd/rc/parse.c"
+#line 1690 "src/cmd/rc/parse.c"
break;
case 30: /* cmd: redir cmd */
#line 92 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
-#line 1685 "src/cmd/rc/parse.c"
+#line 1696 "src/cmd/rc/parse.c"
break;
case 31: /* cmd: assign cmd */
#line 93 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 2); }
-#line 1691 "src/cmd/rc/parse.c"
+#line 1702 "src/cmd/rc/parse.c"
break;
case 32: /* cmd: Tbang cmd */
#line 94 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbang, (yyvsp[0].tree)); }
-#line 1697 "src/cmd/rc/parse.c"
+#line 1708 "src/cmd/rc/parse.c"
break;
case 33: /* cmd: Tsubshell cmd */
#line 95 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tsubshell, (yyvsp[0].tree)); }
-#line 1703 "src/cmd/rc/parse.c"
+#line 1714 "src/cmd/rc/parse.c"
break;
- case 34: /* cmd: Tfor '(' word ')' nl cmd */
+ case 34: /* cmd: Ttwiddle word words */
#line 96 "src/cmd/rc/syntax.y"
- { (yyval.tree) = hangchild3((yyvsp[-5].tree), (yyvsp[-3].tree), nil, (yyvsp[0].tree)); }
-#line 1709 "src/cmd/rc/parse.c"
+ { (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-1].tree), 0, (yyvsp[0].tree), 1); }
+#line 1720 "src/cmd/rc/parse.c"
break;
- case 35: /* cmd: Tfor '(' word Tin words ')' nl cmd */
+ case 35: /* cmd: Tfor '(' word ')' nl cmd */
#line 97 "src/cmd/rc/syntax.y"
- { (yyval.tree) = hangchild3((yyvsp[-7].tree), (yyvsp[-5].tree), (yyvsp[-3].tree), (yyvsp[0].tree)); }
-#line 1715 "src/cmd/rc/parse.c"
+ { (yyval.tree) = hangchild3((yyvsp[-5].tree), (yyvsp[-3].tree), nil, (yyvsp[0].tree)); }
+#line 1726 "src/cmd/rc/parse.c"
break;
- case 36: /* cmd: Twhile paren nl cmd */
+ case 36: /* cmd: Tfor '(' word Tin words ')' nl cmd */
#line 98 "src/cmd/rc/syntax.y"
- { (yyval.tree) = hangchild2((yyvsp[-3].tree), (yyvsp[-2].tree), 0, (yyvsp[0].tree), 1); }
-#line 1721 "src/cmd/rc/parse.c"
+ { (yyval.tree) = hangchild3((yyvsp[-7].tree), (yyvsp[-5].tree), (yyvsp[-3].tree), (yyvsp[0].tree)); }
+#line 1732 "src/cmd/rc/parse.c"
break;
- case 37: /* cmd: Tif paren nl ifbody */
+ case 37: /* cmd: Twhile paren nl cmd */
#line 99 "src/cmd/rc/syntax.y"
- { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-2].tree), 0); }
-#line 1727 "src/cmd/rc/parse.c"
+ { (yyval.tree) = hangchild2((yyvsp[-3].tree), (yyvsp[-2].tree), 0, (yyvsp[0].tree), 1); }
+#line 1738 "src/cmd/rc/parse.c"
break;
- case 38: /* cmd: Tswitch '(' word ')' nl '{' nl casebody '}' */
+ case 38: /* cmd: Tif paren nl ifbody */
#line 100 "src/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-2].tree), 0); }
+#line 1744 "src/cmd/rc/parse.c"
+ break;
+
+ case 39: /* cmd: Tswitch '(' word ')' nl '{' nl casebody '}' */
+#line 101 "src/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild2((yyvsp[-8].tree), (yyvsp[-6].tree), 0, (yyvsp[-1].tree), 1); }
-#line 1733 "src/cmd/rc/parse.c"
+#line 1750 "src/cmd/rc/parse.c"
break;
- case 40: /* basic: basic word */
-#line 104 "src/cmd/rc/syntax.y"
+ case 40: /* cmd: Tfunc words block */
+#line 102 "src/cmd/rc/syntax.y"
+ { (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-1].tree), 0, (yyvsp[0].tree), 1); }
+#line 1756 "src/cmd/rc/parse.c"
+ break;
+
+ case 42: /* basic: basic word */
+#line 106 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1739 "src/cmd/rc/parse.c"
+#line 1762 "src/cmd/rc/parse.c"
break;
- case 41: /* basic: basic redir */
-#line 105 "src/cmd/rc/syntax.y"
+ case 43: /* basic: basic redir */
+#line 107 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1745 "src/cmd/rc/parse.c"
+#line 1768 "src/cmd/rc/parse.c"
break;
- case 43: /* atom: keyword */
-#line 109 "src/cmd/rc/syntax.y"
+ case 45: /* atom: keyword */
+#line 111 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tword, (yyvsp[0].tree)); }
-#line 1751 "src/cmd/rc/parse.c"
+#line 1774 "src/cmd/rc/parse.c"
break;
- case 45: /* word: word '^' atom */
-#line 113 "src/cmd/rc/syntax.y"
+ case 47: /* word: word '^' atom */
+#line 115 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1757 "src/cmd/rc/parse.c"
+#line 1780 "src/cmd/rc/parse.c"
break;
- case 47: /* executable: executable '^' atom */
-#line 117 "src/cmd/rc/syntax.y"
+ case 49: /* executable: executable '^' atom */
+#line 119 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1763 "src/cmd/rc/parse.c"
+#line 1786 "src/cmd/rc/parse.c"
break;
- case 49: /* nonkeyword: '$' atom */
-#line 121 "src/cmd/rc/syntax.y"
+ case 51: /* nonkeyword: '$' atom */
+#line 123 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('$', (yyvsp[0].tree)); }
-#line 1769 "src/cmd/rc/parse.c"
+#line 1792 "src/cmd/rc/parse.c"
break;
- case 50: /* nonkeyword: '$' atom Tindex words ')' */
-#line 122 "src/cmd/rc/syntax.y"
+ case 52: /* nonkeyword: '$' atom Tindex words ')' */
+#line 124 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tindex, (yyvsp[-3].tree), (yyvsp[-1].tree)); }
-#line 1775 "src/cmd/rc/parse.c"
+#line 1798 "src/cmd/rc/parse.c"
break;
- case 51: /* nonkeyword: '(' wordsnl ')' */
-#line 123 "src/cmd/rc/syntax.y"
+ case 53: /* nonkeyword: '(' wordsnl ')' */
+#line 125 "src/cmd/rc/syntax.y"
{ (yyval.tree) = (yyvsp[-1].tree); }
-#line 1781 "src/cmd/rc/parse.c"
+#line 1804 "src/cmd/rc/parse.c"
break;
- case 52: /* nonkeyword: Tcount atom */
-#line 124 "src/cmd/rc/syntax.y"
+ case 54: /* nonkeyword: Tcount atom */
+#line 126 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tcount, (yyvsp[0].tree)); }
-#line 1787 "src/cmd/rc/parse.c"
+#line 1810 "src/cmd/rc/parse.c"
break;
- case 53: /* nonkeyword: Tjoin atom */
-#line 125 "src/cmd/rc/syntax.y"
+ case 55: /* nonkeyword: Tjoin atom */
+#line 127 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tjoin, (yyvsp[0].tree)); }
-#line 1793 "src/cmd/rc/parse.c"
+#line 1816 "src/cmd/rc/parse.c"
break;
- case 54: /* nonkeyword: '`' block */
-#line 126 "src/cmd/rc/syntax.y"
+ case 56: /* nonkeyword: '`' block */
+#line 128 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('`', (yyvsp[0].tree)); }
-#line 1799 "src/cmd/rc/parse.c"
+#line 1822 "src/cmd/rc/parse.c"
break;
- case 65: /* words: %empty */
-#line 133 "src/cmd/rc/syntax.y"
+ case 68: /* words: %empty */
+#line 135 "src/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1805 "src/cmd/rc/parse.c"
+#line 1828 "src/cmd/rc/parse.c"
break;
- case 66: /* words: words word */
-#line 134 "src/cmd/rc/syntax.y"
+ case 69: /* words: words word */
+#line 136 "src/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Twords, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1811 "src/cmd/rc/parse.c"
+#line 1834 "src/cmd/rc/parse.c"
break;
- case 67: /* wordsnl: %empty */
-#line 137 "src/cmd/rc/syntax.y"
+ case 70: /* wordsnl: %empty */
+#line 139 "src/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1817 "src/cmd/rc/parse.c"
+#line 1840 "src/cmd/rc/parse.c"
break;
- case 69: /* wordsnl: wordsnl word */
-#line 139 "src/cmd/rc/syntax.y"
+ case 72: /* wordsnl: wordsnl word */
+#line 141 "src/cmd/rc/syntax.y"
{(yyval.tree) = (!(yyvsp[-1].tree)) ? ((!(yyvsp[0].tree)) ? nil : (yyvsp[0].tree)) : ((!(yyvsp[0].tree)) ? (yyvsp[-1].tree) : maketree2(Twords, (yyvsp[-1].tree), (yyvsp[0].tree))); }
-#line 1823 "src/cmd/rc/parse.c"
+#line 1846 "src/cmd/rc/parse.c"
break;
-#line 1827 "src/cmd/rc/parse.c"
+#line 1850 "src/cmd/rc/parse.c"
default: break;
}
@@ -2048,5 +2071,5 @@ yyreturn:
return yyresult;
}
-#line 145 "src/cmd/rc/syntax.y"
+#line 147 "src/cmd/rc/syntax.y"
diff --git a/src/cmd/rc/rc.h b/src/cmd/rc/rc.h
index b51b78b..0c006e3 100644
--- a/src/cmd/rc/rc.h
+++ b/src/cmd/rc/rc.h
@@ -83,7 +83,10 @@ struct Var
Word *val;
short new : 1;
short newfunc : 1;
- Code *func;
+ struct {
+ Code *code;
+ int start;
+ } func;
void (*update)(Var *);
Var *link;
};
diff --git a/src/cmd/rc/syntax.y b/src/cmd/rc/syntax.y
index 78a7ae2..64ebb41 100644
--- a/src/cmd/rc/syntax.y
+++ b/src/cmd/rc/syntax.y
@@ -76,7 +76,7 @@ assign:
redir:
Tdup
-| Tredir word { $$ = hangchild1($1, $2, 0); }
+| Tredir word { $$ = hangchild1($1, $2, 0); }
epilog:
/* empty */ { $$ = nil; }
@@ -99,6 +99,7 @@ cmd:
| Twhile paren nl cmd { $$ = hangchild2($1, $2, 0, $4, 1); }
| Tif paren nl ifbody { $$ = hangchild1($2, $2, 0); }
| Tswitch '(' word ')' nl '{' nl casebody '}' { $$ = hangchild2($1, $3, 0, $8, 1); }
+| Tfunc words block { $$ = hangchild2($1, $2, 0, $3, 1); }
basic:
executable
diff --git a/src/cmd/rc/var.c b/src/cmd/rc/var.c
index 3e9635f..73532f3 100644
--- a/src/cmd/rc/var.c
+++ b/src/cmd/rc/var.c
@@ -132,13 +132,14 @@ makevar(char *name, Var *link)
{
Var *v = emalloc(sizeof(*v));
- v->name = name;
- v->val = 0;
- v->new = 0;
- v->newfunc = 0;
- v->link = link;
- v->func = nil;
- v->update = nil;
+ v->name = name;
+ v->val = 0;
+ v->new = 0;
+ v->newfunc = 0;
+ v->link = link;
+ v->update = nil;
+ v->func.code = nil;
+ v->func.start = 0;
return v;
}