From 094d3c76925cf6c05a8bfcc112849627d16279b8 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 26 Oct 2021 09:44:47 -0700 Subject: feat(rc): added index operations --- sys/cmd/rc/code.c | 8 ++ sys/cmd/rc/exec.c | 149 ++++++++++++++++----- sys/cmd/rc/exec.h | 28 ++-- sys/cmd/rc/main.c | 1 + sys/cmd/rc/parse.c | 372 ++++++++++++++++++++++++++++++---------------------- sys/cmd/rc/syntax.y | 15 ++- 6 files changed, 358 insertions(+), 215 deletions(-) (limited to 'sys') 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 @@ -702,6 +702,119 @@ Xconcatenate(void) runner->args->word = w; } +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) { @@ -743,42 +856,6 @@ Xjoin(void) efree(s); } -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) { 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 line cmds cmdsln body paren block ifbody assign epilog redir; %type cmd basic executable nonkeyword keyword word words wordsnl atom; %type Tfor Tin Twhile Tif Telse Tswitch Ttwiddle Tbang Tsubshell Tfunc; -%type Tword Tredir Tpipe; +%type 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 -- cgit v1.2.1