aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-26 09:44:47 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-26 09:44:47 -0700
commit094d3c76925cf6c05a8bfcc112849627d16279b8 (patch)
tree2ee67380e480241b8d89427493d794704783387e
parent3733507b090311b70ca8a2fed0c739b808f679c6 (diff)
feat(rc): added index operations
-rw-r--r--sys/cmd/rc/code.c8
-rw-r--r--sys/cmd/rc/exec.c149
-rw-r--r--sys/cmd/rc/exec.h28
-rw-r--r--sys/cmd/rc/main.c1
-rw-r--r--sys/cmd/rc/parse.c372
-rw-r--r--sys/cmd/rc/syntax.y15
6 files changed, 358 insertions, 215 deletions
diff --git a/sys/cmd/rc/code.c b/sys/cmd/rc/code.c
index bcc3d38..0723279 100644
--- a/sys/cmd/rc/code.c
+++ b/sys/cmd/rc/code.c
@@ -72,6 +72,14 @@ walk(Tree *node)
emitf(Xjoin);
break;
+ case Tindex:
+ emitf(Xmark);
+ walk(node->child[1]);
+ emitf(Xmark);
+ walk(node->child[0]);
+ emitf(Xindex);
+ break;
+
case ';':
walk(node->child[0]);
walk(node->child[1]);
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c
index e8d59c1..fbcfb9b 100644
--- a/sys/cmd/rc/exec.c
+++ b/sys/cmd/rc/exec.c
@@ -703,6 +703,119 @@ Xconcatenate(void)
}
void
+Xdollar(void)
+{
+ int n;
+ char *s, *t;
+ Word *a, *star;
+
+ if(count(runner->args->word)!=1){
+ Xerror("variable name not singleton!\n");
+ return;
+ }
+ s = runner->args->word->str;
+ // deglob(s);
+ n = 0;
+
+ for(t = s;'0'<=*t && *t<='9';t++)
+ n = n*10+*t-'0';
+
+ a = runner->args->link->word;
+
+ if(n==0 || *t)
+ a = copywords(var(s)->val, a);
+ else{
+ star = var("*")->val;
+ if(star && 1<=n && n<=count(star)){
+ while(--n)
+ star = star->link;
+
+ a = makeword(star->str, a);
+ }
+ }
+
+ poplist();
+ runner->args->word = a;
+}
+
+static
+Word*
+cpwords(Word *array, Word *tail, int n)
+{
+ Word *cp, **end;
+
+ cp = nil, end = &cp;
+ while(n-- > 0){
+ *end = makeword(array->str, nil);
+ end = &(*end)->link;
+ array = array->link;
+ }
+ *end = tail;
+
+ return cp;
+}
+
+
+static
+Word*
+getindex(Word *array, int len, Word *index, Word *tail)
+{
+ char *s;
+ int n, m;
+ if(!index)
+ return tail;
+
+ tail = getindex(array, len, index->link, tail);
+
+ s = index->str;
+ //deglob(s)
+
+ m = 0, n = 0;
+ while('0' <= *s && *s <= '9')
+ n = 10*n + (*s++ - '0');
+ if(*s == '-'){
+ if(*++s == 0)
+ m = len - n;
+ else{
+ while('0' <= *s && *s <= '9')
+ m = 10*m + (*s++ - '0');
+ m -= n;
+ }
+ }
+
+ if(n<1 || n > len || m < 0)
+ return tail;
+ if(n+m > len)
+ m = len-n;
+ while(--n > 0)
+ array = array->link;
+ return cpwords(array, tail, m+1);
+}
+
+void
+Xindex(void)
+{
+ char *s;
+ Word *val, *ret;
+
+ if(count(runner->args->word) != 1){
+ Xerror("variable name not a singleton");
+ return;
+ }
+ s = runner->args->word->str;
+ //deglob(s)
+ val = var(s)->val;
+ poplist();
+
+ ret = runner->args->link->word; // pointer to next stack frame
+ ret = getindex(val, count(val), runner->args->word, ret);
+ poplist();
+
+ // push result back on stack
+ runner->args->word = ret;
+}
+
+void
Xjoin(void)
{
int n;
@@ -744,42 +857,6 @@ Xjoin(void)
}
void
-Xdollar(void)
-{
- int n;
- char *s, *t;
- Word *a, *star;
-
- if(count(runner->args->word)!=1){
- Xerror("variable name not singleton!\n");
- return;
- }
- s = runner->args->word->str;
- // deglob(s);
- n = 0;
-
- for(t = s;'0'<=*t && *t<='9';t++)
- n = n*10+*t-'0';
-
- a = runner->args->link->word;
-
- if(n==0 || *t)
- a = copywords(var(s)->val, a);
- else{
- star = var("*")->val;
- if(star && 1<=n && n<=count(star)){
- while(--n)
- star = star->link;
-
- a = makeword(star->str, a);
- }
- }
-
- poplist();
- runner->args->word = a;
-}
-
-void
Xassign(void)
{
Var *v;
diff --git a/sys/cmd/rc/exec.h b/sys/cmd/rc/exec.h
index 9edd9ed..635eb1d 100644
--- a/sys/cmd/rc/exec.h
+++ b/sys/cmd/rc/exec.h
@@ -2,24 +2,23 @@
/*
* opcode routines
- * Arguments on stack (...)
- * Arguments in line [...]
- * Code in line with jump around {...}
+ * arguments on stack (...)
+ * arguments in line [...]
+ * code in line with jump around {...}
*/
-void Xtrue(void);
-void Xfalse(void);
-void Xdollar(void);
-void Xexit(void);
-void Xmark(void);
-void Xreturn(void);
-void Xlocal(void);
-void Xreadcmd(void);
-void Xunlocal(void);
+void Xmark(void); // Xmark marks stack location for word
+void Xtrue(void); // Xtrue{...} execute {} if true
+void Xfalse(void); // Xfalse{...} execute {} if false
+void Xdollar(void); // Xdollar(name) get value of name
+void Xindex(void); // Xindex
+void Xlocal(void); // Xlocal(name,val) create local variable, assign value
+void Xunlocal(void); // Xunlocal delete local variable
+void Xreadcmd(void); //
void Xassign(void);
void Xbang(void);
void Xasync(void);
-void Xbasic(void); // Xbasic(args) run command and wait for result
+void Xbasic(void); // Xbasic(args) run command and wait for result
void Xsubshell(void);
void Xword(void);
void Xjoin(void);
@@ -30,6 +29,9 @@ void Xpipe(void);
void Xpipewait(void);
void Xpopredir(void);
+void Xreturn(void);
+void Xexit(void);
+
void Xerror(char*);
/* builtin commands */
diff --git a/sys/cmd/rc/main.c b/sys/cmd/rc/main.c
index 3f2e02e..9e35a87 100644
--- a/sys/cmd/rc/main.c
+++ b/sys/cmd/rc/main.c
@@ -60,4 +60,5 @@ main(int argc, char *argv[])
// enablevi();
xboot(argc, argv);
+ /* unreachable */
}
diff --git a/sys/cmd/rc/parse.c b/sys/cmd/rc/parse.c
index 774e8d4..687956b 100644
--- a/sys/cmd/rc/parse.c
+++ b/sys/cmd/rc/parse.c
@@ -139,27 +139,29 @@ enum yysymbol_kind_t
YYSYMBOL_34_ = 34, /* ';' */
YYSYMBOL_35_ = 35, /* '&' */
YYSYMBOL_36_ = 36, /* '=' */
- YYSYMBOL_YYACCEPT = 37, /* $accept */
- YYSYMBOL_rc = 38, /* rc */
- YYSYMBOL_line = 39, /* line */
- YYSYMBOL_body = 40, /* body */
- YYSYMBOL_paren = 41, /* paren */
- YYSYMBOL_block = 42, /* block */
- YYSYMBOL_cmds = 43, /* cmds */
- YYSYMBOL_cmdsln = 44, /* cmdsln */
- YYSYMBOL_ifbody = 45, /* ifbody */
- YYSYMBOL_assign = 46, /* assign */
- YYSYMBOL_redir = 47, /* redir */
- YYSYMBOL_epilog = 48, /* epilog */
- YYSYMBOL_cmd = 49, /* cmd */
- YYSYMBOL_basic = 50, /* basic */
- YYSYMBOL_atom = 51, /* atom */
- YYSYMBOL_word = 52, /* word */
- YYSYMBOL_executable = 53, /* executable */
- YYSYMBOL_nonkeyword = 54, /* nonkeyword */
- YYSYMBOL_keyword = 55, /* keyword */
- YYSYMBOL_wordsnl = 56, /* wordsnl */
- YYSYMBOL_nl = 57 /* nl */
+ YYSYMBOL_37_ = 37, /* '`' */
+ YYSYMBOL_YYACCEPT = 38, /* $accept */
+ YYSYMBOL_rc = 39, /* rc */
+ YYSYMBOL_line = 40, /* line */
+ YYSYMBOL_body = 41, /* body */
+ YYSYMBOL_paren = 42, /* paren */
+ YYSYMBOL_block = 43, /* block */
+ YYSYMBOL_cmds = 44, /* cmds */
+ YYSYMBOL_cmdsln = 45, /* cmdsln */
+ YYSYMBOL_ifbody = 46, /* ifbody */
+ YYSYMBOL_assign = 47, /* assign */
+ YYSYMBOL_redir = 48, /* redir */
+ YYSYMBOL_epilog = 49, /* epilog */
+ YYSYMBOL_cmd = 50, /* cmd */
+ YYSYMBOL_basic = 51, /* basic */
+ YYSYMBOL_atom = 52, /* atom */
+ YYSYMBOL_word = 53, /* word */
+ YYSYMBOL_executable = 54, /* executable */
+ YYSYMBOL_nonkeyword = 55, /* nonkeyword */
+ YYSYMBOL_keyword = 56, /* keyword */
+ YYSYMBOL_words = 57, /* words */
+ YYSYMBOL_wordsnl = 58, /* wordsnl */
+ YYSYMBOL_nl = 59 /* nl */
};
typedef enum yysymbol_kind_t yysymbol_kind_t;
@@ -485,18 +487,18 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 47
+#define YYFINAL 49
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 195
+#define YYLAST 290
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 37
+#define YYNTOKENS 38
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 21
+#define YYNNTS 22
/* YYNRULES -- Number of rules. */
-#define YYNRULES 59
+#define YYNRULES 63
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 90
+#define YYNSTATES 96
/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK 281
@@ -522,7 +524,7 @@ static const yytype_int8 yytranslate[] =
2, 36, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 27, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 27, 2, 37, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 32, 2, 33, 2, 2, 2, 2,
@@ -552,8 +554,9 @@ static const yytype_uint8 yyrline[] =
56, 57, 60, 61, 64, 65, 68, 71, 72, 75,
76, 79, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 92, 93, 94, 97, 98, 101, 102, 105,
- 106, 109, 110, 111, 112, 113, 117, 117, 117, 117,
- 117, 117, 117, 117, 117, 124, 125, 126, 128, 130
+ 106, 109, 110, 111, 112, 113, 114, 115, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 123, 124, 127,
+ 128, 129, 131, 133
};
#endif
@@ -574,9 +577,9 @@ static const char *const yytname[] =
"Tfunc", "Tredir", "Tdup", "Tpipe", "Tindex", "Tbasic", "Targs", "Tword",
"Twords", "Tparen", "Tblock", "')'", "Tandand", "Toror", "'\\n'", "'^'",
"'$'", "Tcount", "Tjoin", "'('", "'{'", "'}'", "';'", "'&'", "'='",
- "$accept", "rc", "line", "body", "paren", "block", "cmds", "cmdsln",
- "ifbody", "assign", "redir", "epilog", "cmd", "basic", "atom", "word",
- "executable", "nonkeyword", "keyword", "wordsnl", "nl", YY_NULLPTR
+ "'`'", "$accept", "rc", "line", "body", "paren", "block", "cmds",
+ "cmdsln", "ifbody", "assign", "redir", "epilog", "cmd", "basic", "atom",
+ "word", "executable", "nonkeyword", "keyword", "words", "wordsnl", "nl", YY_NULLPTR
};
static const char *
@@ -586,7 +589,7 @@ yysymbol_name (yysymbol_kind_t yysymbol)
}
#endif
-#define YYPACT_NINF (-34)
+#define YYPACT_NINF (-46)
#define yypact_value_is_default(Yyn) \
((Yyn) == YYPACT_NINF)
@@ -600,15 +603,16 @@ yysymbol_name (yysymbol_kind_t yysymbol)
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- 70, -24, 163, 163, 129, -34, -34, 129, 129, 129,
- -34, 163, 26, 2, 38, 163, 163, 163, 62, 27,
- 17, -34, 163, -34, 30, 30, -34, -34, -34, -34,
- -34, -34, -34, -34, -34, -34, 21, -34, -34, -34,
- -34, -34, 100, 16, -34, 163, 146, -34, -34, 38,
- -34, -34, 30, 30, -34, -34, -34, -34, -34, -34,
- 21, 129, 129, 45, 136, 129, -34, -34, 21, -34,
- -34, -34, -34, 136, 136, 136, -34, 21, -34, -34,
- 11, -34, 35, -34, -34, 30, 30, -34, 136, 35
+ 22, -17, 253, 253, 197, -46, -46, 197, 197, 197,
+ -46, 253, -13, 45, 23, 49, 253, 253, 253, 57,
+ 92, 7, -46, 253, -46, 40, 40, -46, -46, -46,
+ -46, -46, -46, -46, -46, -46, -46, 31, -46, -46,
+ 44, -46, -46, 127, 37, -46, 253, 5, -46, -46,
+ -46, 49, -46, -46, 40, 40, -46, -46, -46, -46,
+ -46, -46, 31, 197, 197, 52, 225, 197, -46, -46,
+ -46, 31, -46, -46, -46, -46, 225, 225, 225, -46,
+ 31, -46, -46, 60, -46, 32, -46, 162, -46, 40,
+ 40, -46, -46, 31, 225, 32
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -617,30 +621,31 @@ static const yytype_int16 yypact[] =
static const yytype_int8 yydefact[] =
{
21, 0, 21, 21, 0, 17, 41, 0, 0, 0,
- 55, 21, 0, 0, 19, 21, 21, 21, 4, 22,
- 32, 39, 21, 58, 29, 30, 47, 46, 48, 49,
- 50, 51, 52, 53, 54, 37, 18, 35, 36, 42,
- 44, 45, 0, 0, 12, 21, 6, 1, 3, 19,
- 23, 5, 28, 27, 58, 58, 58, 10, 11, 34,
- 33, 0, 0, 0, 21, 0, 43, 56, 57, 9,
- 7, 13, 20, 21, 21, 21, 40, 16, 8, 59,
- 19, 31, 14, 38, 24, 25, 26, 58, 21, 15
+ 59, 21, 0, 0, 0, 19, 21, 21, 21, 4,
+ 22, 32, 39, 21, 62, 29, 30, 49, 48, 50,
+ 51, 52, 53, 54, 55, 56, 37, 18, 35, 36,
+ 42, 45, 46, 0, 0, 12, 21, 6, 47, 1,
+ 3, 19, 23, 5, 28, 27, 62, 62, 62, 10,
+ 11, 34, 33, 0, 0, 0, 21, 0, 57, 44,
+ 60, 61, 9, 7, 13, 20, 21, 21, 21, 40,
+ 16, 8, 63, 19, 31, 14, 38, 0, 24, 25,
+ 26, 62, 43, 58, 21, 15
};
/* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] =
{
- -34, -34, 46, -3, -34, 7, 14, -34, -34, -34,
- -13, 23, 0, -34, 4, -15, -34, 1, -34, -34,
- -33
+ -46, -46, 64, -8, -46, -5, 26, -46, -46, -46,
+ -14, 33, 0, -46, 16, -16, -46, 1, -46, -46,
+ -46, -45
};
/* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] =
{
- 0, 12, 13, 43, 23, 14, 44, 45, 81, 16,
- 17, 50, 46, 19, 35, 36, 20, 21, 38, 42,
- 64
+ 0, 13, 14, 44, 24, 15, 45, 46, 84, 17,
+ 18, 52, 47, 20, 36, 37, 21, 22, 39, 87,
+ 43, 66
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -648,50 +653,70 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
- 18, 49, 24, 25, 60, 37, 59, 22, 37, 37,
- 37, 39, 40, 41, 15, 18, 52, 53, 87, 63,
- 37, 73, 74, 75, 4, 5, 47, 68, 48, 15,
- 26, 27, 28, 29, 30, 31, 49, 32, 33, 34,
- 4, 5, 70, 37, 61, 54, 6, 77, 65, 69,
- 54, 4, 5, 62, 88, 7, 8, 9, 10, 55,
- 56, 51, 37, 37, 82, 76, 37, 49, 78, 83,
- -2, 80, 72, 84, 85, 86, 1, 54, 0, 0,
- 2, 3, 0, 4, 5, 0, 55, 56, 89, 6,
- 0, 0, 0, 0, 0, 0, 57, 58, 7, 8,
- 9, 10, 11, 26, 27, 28, 29, 30, 31, 0,
- 32, 33, 34, 0, 0, 0, 0, 0, 0, 6,
- 0, 0, 0, 66, 0, 0, 67, 0, 7, 8,
- 9, 10, 26, 27, 28, 29, 30, 31, 0, 32,
- 33, 34, 1, 0, 0, 0, 2, 3, 6, 4,
- 5, 0, 0, 0, 0, 6, 0, 7, 8, 9,
- 10, 54, 79, 0, 7, 8, 9, 10, 11, 1,
- 55, 56, 71, 2, 3, 0, 4, 5, 0, 0,
- 57, 58, 6, 0, 0, 0, 0, 0, 0, 0,
- 0, 7, 8, 9, 10, 11
+ 19, 51, 25, 26, 62, 38, 61, 48, 38, 38,
+ 38, 76, 77, 78, 23, 65, 19, 54, 55, 11,
+ 56, 38, -2, 40, 41, 42, 16, 71, 1, 57,
+ 58, 74, 2, 3, 63, 4, 5, 51, 73, 59,
+ 60, 6, 16, 64, 38, 49, 94, 56, 80, 50,
+ 7, 8, 9, 10, 11, 56, 57, 58, 67, 12,
+ 68, 83, 4, 5, 38, 38, 85, 91, 38, 51,
+ 72, 93, 56, 4, 5, 81, 88, 89, 90, 79,
+ 53, 57, 58, 86, 75, 0, 0, 0, 38, 0,
+ 0, 59, 60, 0, 95, 27, 28, 29, 30, 31,
+ 32, 0, 33, 34, 35, 4, 5, 0, 0, 0,
+ 0, 6, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 8, 9, 10, 0, 0, 0, 0, 0, 12,
+ 27, 28, 29, 30, 31, 32, 0, 33, 34, 35,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 69, 0, 0, 70, 0, 7, 8, 9, 10, 0,
+ 0, 0, 0, 0, 12, 27, 28, 29, 30, 31,
+ 32, 0, 33, 34, 35, 0, 0, 0, 0, 0,
+ 0, 6, 0, 0, 0, 92, 0, 0, 0, 0,
+ 7, 8, 9, 10, 0, 0, 0, 0, 0, 12,
+ 27, 28, 29, 30, 31, 32, 0, 33, 34, 35,
+ 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 8, 9, 10, 0,
+ 0, 1, 0, 0, 12, 2, 3, 0, 4, 5,
+ 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
+ 0, 82, 0, 7, 8, 9, 10, 11, 0, 1,
+ 0, 0, 12, 2, 3, 0, 4, 5, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 8, 9, 10, 11, 0, 0, 0, 0,
+ 12
};
static const yytype_int8 yycheck[] =
{
- 0, 14, 2, 3, 19, 4, 19, 31, 7, 8,
- 9, 7, 8, 9, 0, 15, 16, 17, 7, 22,
- 19, 54, 55, 56, 13, 14, 0, 42, 26, 15,
- 3, 4, 5, 6, 7, 8, 49, 10, 11, 12,
- 13, 14, 45, 42, 27, 15, 19, 62, 27, 33,
- 15, 13, 14, 36, 87, 28, 29, 30, 31, 24,
- 25, 15, 61, 62, 64, 61, 65, 80, 23, 65,
- 0, 64, 49, 73, 74, 75, 6, 15, -1, -1,
- 10, 11, -1, 13, 14, -1, 24, 25, 88, 19,
- -1, -1, -1, -1, -1, -1, 34, 35, 28, 29,
- 30, 31, 32, 3, 4, 5, 6, 7, 8, -1,
- 10, 11, 12, -1, -1, -1, -1, -1, -1, 19,
- -1, -1, -1, 23, -1, -1, 26, -1, 28, 29,
- 30, 31, 3, 4, 5, 6, 7, 8, -1, 10,
- 11, 12, 6, -1, -1, -1, 10, 11, 19, 13,
- 14, -1, -1, -1, -1, 19, -1, 28, 29, 30,
- 31, 15, 26, -1, 28, 29, 30, 31, 32, 6,
- 24, 25, 26, 10, 11, -1, 13, 14, -1, -1,
- 34, 35, 19, -1, -1, -1, -1, -1, -1, -1,
- -1, 28, 29, 30, 31, 32
+ 0, 15, 2, 3, 20, 4, 20, 12, 7, 8,
+ 9, 56, 57, 58, 31, 23, 16, 17, 18, 32,
+ 15, 20, 0, 7, 8, 9, 0, 43, 6, 24,
+ 25, 26, 10, 11, 27, 13, 14, 51, 46, 34,
+ 35, 19, 16, 36, 43, 0, 91, 15, 64, 26,
+ 28, 29, 30, 31, 32, 15, 24, 25, 27, 37,
+ 16, 66, 13, 14, 63, 64, 66, 7, 67, 83,
+ 33, 87, 15, 13, 14, 23, 76, 77, 78, 63,
+ 16, 24, 25, 67, 51, -1, -1, -1, 87, -1,
+ -1, 34, 35, -1, 94, 3, 4, 5, 6, 7,
+ 8, -1, 10, 11, 12, 13, 14, -1, -1, -1,
+ -1, 19, -1, -1, -1, -1, -1, -1, -1, -1,
+ 28, 29, 30, 31, -1, -1, -1, -1, -1, 37,
+ 3, 4, 5, 6, 7, 8, -1, 10, 11, 12,
+ -1, -1, -1, -1, -1, -1, 19, -1, -1, -1,
+ 23, -1, -1, 26, -1, 28, 29, 30, 31, -1,
+ -1, -1, -1, -1, 37, 3, 4, 5, 6, 7,
+ 8, -1, 10, 11, 12, -1, -1, -1, -1, -1,
+ -1, 19, -1, -1, -1, 23, -1, -1, -1, -1,
+ 28, 29, 30, 31, -1, -1, -1, -1, -1, 37,
+ 3, 4, 5, 6, 7, 8, -1, 10, 11, 12,
+ -1, -1, -1, -1, -1, -1, 19, -1, -1, -1,
+ -1, -1, -1, -1, -1, 28, 29, 30, 31, -1,
+ -1, 6, -1, -1, 37, 10, 11, -1, 13, 14,
+ -1, -1, -1, -1, 19, -1, -1, -1, -1, -1,
+ -1, 26, -1, 28, 29, 30, 31, 32, -1, 6,
+ -1, -1, 37, 10, 11, -1, 13, 14, -1, -1,
+ -1, -1, 19, -1, -1, -1, -1, -1, -1, -1,
+ -1, 28, 29, 30, 31, 32, -1, -1, -1, -1,
+ 37
};
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
@@ -699,25 +724,27 @@ static const yytype_int8 yycheck[] =
static const yytype_int8 yystos[] =
{
0, 6, 10, 11, 13, 14, 19, 28, 29, 30,
- 31, 32, 38, 39, 42, 43, 46, 47, 49, 50,
- 53, 54, 31, 41, 49, 49, 3, 4, 5, 6,
- 7, 8, 10, 11, 12, 51, 52, 54, 55, 51,
- 51, 51, 56, 40, 43, 44, 49, 0, 26, 47,
- 48, 39, 49, 49, 15, 24, 25, 34, 35, 47,
- 52, 27, 36, 40, 57, 27, 23, 26, 52, 33,
- 40, 26, 48, 57, 57, 57, 51, 52, 23, 26,
- 42, 45, 49, 51, 49, 49, 49, 7, 57, 49
+ 31, 32, 37, 39, 40, 43, 44, 47, 48, 50,
+ 51, 54, 55, 31, 42, 50, 50, 3, 4, 5,
+ 6, 7, 8, 10, 11, 12, 52, 53, 55, 56,
+ 52, 52, 52, 58, 41, 44, 45, 50, 43, 0,
+ 26, 48, 49, 40, 50, 50, 15, 24, 25, 34,
+ 35, 48, 53, 27, 36, 41, 59, 27, 16, 23,
+ 26, 53, 33, 41, 26, 49, 59, 59, 59, 52,
+ 53, 23, 26, 43, 46, 50, 52, 57, 50, 50,
+ 50, 7, 23, 53, 59, 50
};
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
static const yytype_int8 yyr1[] =
{
- 0, 37, 38, 38, 39, 39, 40, 40, 41, 42,
- 43, 43, 44, 44, 45, 45, 46, 47, 47, 48,
- 48, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 50, 50, 50, 51, 51, 52, 52, 53,
- 53, 54, 54, 54, 54, 54, 55, 55, 55, 55,
- 55, 55, 55, 55, 55, 56, 56, 56, 57, 57
+ 0, 38, 39, 39, 40, 40, 41, 41, 42, 43,
+ 44, 44, 45, 45, 46, 46, 47, 48, 48, 49,
+ 49, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+ 50, 50, 51, 51, 51, 52, 52, 53, 53, 54,
+ 54, 55, 55, 55, 55, 55, 55, 55, 56, 56,
+ 56, 56, 56, 56, 56, 56, 56, 57, 57, 58,
+ 58, 58, 59, 59
};
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
@@ -727,8 +754,9 @@ static const yytype_int8 yyr2[] =
2, 2, 1, 2, 1, 4, 3, 1, 2, 0,
2, 0, 1, 2, 4, 4, 4, 2, 2, 2,
2, 4, 1, 2, 2, 1, 1, 1, 3, 1,
- 3, 1, 2, 3, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 0, 2, 2, 0, 2
+ 3, 1, 2, 5, 3, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 2, 0,
+ 2, 2, 0, 2
};
@@ -1464,215 +1492,239 @@ yyreduce:
case 2: /* rc: %empty */
#line 38 "sys/cmd/rc/syntax.y"
{ return 0; }
-#line 1468 "sys/cmd/rc/parse.c"
+#line 1496 "sys/cmd/rc/parse.c"
break;
case 3: /* rc: line '\n' */
#line 39 "sys/cmd/rc/syntax.y"
{ return compile((yyvsp[-1].tree)); }
-#line 1474 "sys/cmd/rc/parse.c"
+#line 1502 "sys/cmd/rc/parse.c"
break;
case 5: /* line: cmds line */
#line 43 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1480 "sys/cmd/rc/parse.c"
+#line 1508 "sys/cmd/rc/parse.c"
break;
case 7: /* body: cmdsln body */
#line 47 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(';', (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1486 "sys/cmd/rc/parse.c"
+#line 1514 "sys/cmd/rc/parse.c"
break;
case 8: /* paren: '(' body ')' */
#line 50 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tparen, (yyvsp[-1].tree)); }
-#line 1492 "sys/cmd/rc/parse.c"
+#line 1520 "sys/cmd/rc/parse.c"
break;
case 9: /* block: '{' body '}' */
#line 53 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tblock, (yyvsp[-1].tree)); }
-#line 1498 "sys/cmd/rc/parse.c"
+#line 1526 "sys/cmd/rc/parse.c"
break;
case 11: /* cmds: cmd '&' */
#line 57 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1('&', (yyvsp[-1].tree)); }
-#line 1504 "sys/cmd/rc/parse.c"
+#line 1532 "sys/cmd/rc/parse.c"
break;
case 14: /* ifbody: cmd */
#line 64 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tif, nil, (yyvsp[0].tree)); }
-#line 1510 "sys/cmd/rc/parse.c"
+#line 1538 "sys/cmd/rc/parse.c"
break;
case 15: /* ifbody: block Telse nl cmd */
#line 65 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree3(Tif, nil, (yyvsp[-3].tree), (yyvsp[-2].tree)); }
-#line 1516 "sys/cmd/rc/parse.c"
+#line 1544 "sys/cmd/rc/parse.c"
break;
case 16: /* assign: executable '=' word */
#line 68 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('=', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1522 "sys/cmd/rc/parse.c"
+#line 1550 "sys/cmd/rc/parse.c"
break;
case 18: /* redir: Tredir word */
#line 72 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 0); }
-#line 1528 "sys/cmd/rc/parse.c"
+#line 1556 "sys/cmd/rc/parse.c"
break;
case 19: /* epilog: %empty */
#line 75 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1534 "sys/cmd/rc/parse.c"
+#line 1562 "sys/cmd/rc/parse.c"
break;
case 20: /* epilog: redir epilog */
#line 76 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
-#line 1540 "sys/cmd/rc/parse.c"
+#line 1568 "sys/cmd/rc/parse.c"
break;
case 21: /* cmd: %empty */
#line 79 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1546 "sys/cmd/rc/parse.c"
+#line 1574 "sys/cmd/rc/parse.c"
break;
case 22: /* cmd: basic */
#line 80 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbasic, (yyvsp[0].tree)); }
-#line 1552 "sys/cmd/rc/parse.c"
+#line 1580 "sys/cmd/rc/parse.c"
break;
case 23: /* cmd: block epilog */
#line 81 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangepilog((yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1558 "sys/cmd/rc/parse.c"
+#line 1586 "sys/cmd/rc/parse.c"
break;
case 24: /* cmd: cmd Tpipe nl cmd */
#line 82 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild2((yyvsp[-2].tree), (yyvsp[-3].tree), 0, (yyvsp[0].tree), 1); }
-#line 1564 "sys/cmd/rc/parse.c"
+#line 1592 "sys/cmd/rc/parse.c"
break;
case 25: /* cmd: cmd Tandand nl cmd */
#line 83 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Tandand, (yyvsp[-3].tree), (yyvsp[0].tree)); }
-#line 1570 "sys/cmd/rc/parse.c"
+#line 1598 "sys/cmd/rc/parse.c"
break;
case 26: /* cmd: cmd Toror nl cmd */
#line 84 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Toror, (yyvsp[-3].tree), (yyvsp[0].tree)); }
-#line 1576 "sys/cmd/rc/parse.c"
+#line 1604 "sys/cmd/rc/parse.c"
break;
case 27: /* cmd: redir cmd */
#line 85 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 1); }
-#line 1582 "sys/cmd/rc/parse.c"
+#line 1610 "sys/cmd/rc/parse.c"
break;
case 28: /* cmd: assign cmd */
#line 86 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-1].tree), (yyvsp[0].tree), 2); }
-#line 1588 "sys/cmd/rc/parse.c"
+#line 1616 "sys/cmd/rc/parse.c"
break;
case 29: /* cmd: Tbang cmd */
#line 87 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tbang, (yyvsp[0].tree)); }
-#line 1594 "sys/cmd/rc/parse.c"
+#line 1622 "sys/cmd/rc/parse.c"
break;
case 30: /* cmd: Tsubshell cmd */
#line 88 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tsubshell, (yyvsp[0].tree)); }
-#line 1600 "sys/cmd/rc/parse.c"
+#line 1628 "sys/cmd/rc/parse.c"
break;
case 31: /* cmd: Tif paren nl ifbody */
#line 89 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = hangchild1((yyvsp[-2].tree), (yyvsp[-3].tree), 0); }
-#line 1606 "sys/cmd/rc/parse.c"
+#line 1634 "sys/cmd/rc/parse.c"
break;
case 33: /* basic: basic word */
#line 93 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1612 "sys/cmd/rc/parse.c"
+#line 1640 "sys/cmd/rc/parse.c"
break;
case 34: /* basic: basic redir */
#line 94 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2(Targs, (yyvsp[-1].tree), (yyvsp[0].tree)); }
-#line 1618 "sys/cmd/rc/parse.c"
+#line 1646 "sys/cmd/rc/parse.c"
break;
case 36: /* atom: keyword */
#line 98 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree1(Tword, (yyvsp[0].tree)); }
-#line 1624 "sys/cmd/rc/parse.c"
+#line 1652 "sys/cmd/rc/parse.c"
break;
case 38: /* word: word '^' atom */
#line 102 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1630 "sys/cmd/rc/parse.c"
+#line 1658 "sys/cmd/rc/parse.c"
break;
case 40: /* executable: executable '^' atom */
#line 106 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = maketree2('^', (yyvsp[-2].tree), (yyvsp[0].tree)); }
-#line 1636 "sys/cmd/rc/parse.c"
+#line 1664 "sys/cmd/rc/parse.c"
break;
case 42: /* nonkeyword: '$' atom */
#line 110 "sys/cmd/rc/syntax.y"
- { (yyval.tree) = maketree1('$', (yyvsp[0].tree)); }
-#line 1642 "sys/cmd/rc/parse.c"
+ { (yyval.tree) = maketree1('$', (yyvsp[0].tree)); }
+#line 1670 "sys/cmd/rc/parse.c"
break;
- case 43: /* nonkeyword: '(' wordsnl ')' */
+ case 43: /* nonkeyword: '$' atom Tindex words ')' */
#line 111 "sys/cmd/rc/syntax.y"
- { (yyval.tree) = (yyvsp[-1].tree); }
-#line 1648 "sys/cmd/rc/parse.c"
+ { (yyval.tree) = maketree2(Tindex, (yyvsp[-3].tree), (yyvsp[-1].tree)); }
+#line 1676 "sys/cmd/rc/parse.c"
break;
- case 44: /* nonkeyword: Tcount atom */
+ case 44: /* nonkeyword: '(' wordsnl ')' */
#line 112 "sys/cmd/rc/syntax.y"
- { (yyval.tree) = maketree1(Tcount, (yyvsp[0].tree)); }
-#line 1654 "sys/cmd/rc/parse.c"
+ { (yyval.tree) = (yyvsp[-1].tree); }
+#line 1682 "sys/cmd/rc/parse.c"
break;
- case 45: /* nonkeyword: Tjoin atom */
+ case 45: /* nonkeyword: Tcount atom */
#line 113 "sys/cmd/rc/syntax.y"
- { (yyval.tree) = maketree1(Tjoin, (yyvsp[0].tree)); }
-#line 1660 "sys/cmd/rc/parse.c"
+ { (yyval.tree) = maketree1(Tcount, (yyvsp[0].tree)); }
+#line 1688 "sys/cmd/rc/parse.c"
+ break;
+
+ case 46: /* nonkeyword: Tjoin atom */
+#line 114 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = maketree1(Tjoin, (yyvsp[0].tree)); }
+#line 1694 "sys/cmd/rc/parse.c"
+ break;
+
+ case 47: /* nonkeyword: '`' block */
+#line 115 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = maketree1('`', (yyvsp[0].tree)); }
+#line 1700 "sys/cmd/rc/parse.c"
break;
- case 55: /* wordsnl: %empty */
+ case 57: /* words: %empty */
+#line 123 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = nil; }
+#line 1706 "sys/cmd/rc/parse.c"
+ break;
+
+ case 58: /* words: words word */
#line 124 "sys/cmd/rc/syntax.y"
+ { (yyval.tree) = maketree2(Twords, (yyvsp[-1].tree), (yyvsp[0].tree)); }
+#line 1712 "sys/cmd/rc/parse.c"
+ break;
+
+ case 59: /* wordsnl: %empty */
+#line 127 "sys/cmd/rc/syntax.y"
{ (yyval.tree) = nil; }
-#line 1666 "sys/cmd/rc/parse.c"
+#line 1718 "sys/cmd/rc/parse.c"
break;
- case 57: /* wordsnl: wordsnl word */
-#line 126 "sys/cmd/rc/syntax.y"
+ case 61: /* wordsnl: wordsnl word */
+#line 129 "sys/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 1672 "sys/cmd/rc/parse.c"
+#line 1724 "sys/cmd/rc/parse.c"
break;
-#line 1676 "sys/cmd/rc/parse.c"
+#line 1728 "sys/cmd/rc/parse.c"
default: break;
}
@@ -1896,5 +1948,5 @@ yyreturnlab:
return yyresult;
}
-#line 131 "sys/cmd/rc/syntax.y"
+#line 134 "sys/cmd/rc/syntax.y"
diff --git a/sys/cmd/rc/syntax.y b/sys/cmd/rc/syntax.y
index 2e7e1da..f3c9f29 100644
--- a/sys/cmd/rc/syntax.y
+++ b/sys/cmd/rc/syntax.y
@@ -27,7 +27,7 @@
%type<tree> line cmds cmdsln body paren block ifbody assign epilog redir;
%type<tree> cmd basic executable nonkeyword keyword word words wordsnl atom;
%type<tree> Tfor Tin Twhile Tif Telse Tswitch Ttwiddle Tbang Tsubshell Tfunc;
-%type<tree> Tword Tredir Tpipe;
+%type<tree> Tword Tredir Tpipe Tdup;
/* grammar */
@@ -107,11 +107,14 @@ executable:
nonkeyword:
Tword
-| '$' atom { $$ = maketree1('$', $2); }
-| '(' wordsnl ')' { $$ = $2; }
-| Tcount atom { $$ = maketree1(Tcount, $2); }
-| Tjoin atom { $$ = maketree1(Tjoin, $2); }
-//| '`' block { $$ = maketree1('`', $2); }
+| '$' atom { $$ = maketree1('$', $2); }
+| '$' atom Tindex words ')' { $$ = maketree2(Tindex, $2, $4); }
+| '(' wordsnl ')' { $$ = $2; }
+| Tcount atom { $$ = maketree1(Tcount, $2); }
+| Tjoin atom { $$ = maketree1(Tjoin, $2); }
+| '`' block { $$ = maketree1('`', $2); }
+//| '(' words ')' { $$ = maketree1(Tparen, $2); }
+//| Tredir block { $$ = hangchild1($1, $2, 0); $$->type = Tpipefd; }
keyword:
Tin|Tfor|Twhile|Tif|Telse|Tswitch|Tbang|Tsubshell|Tfunc