From 5c20d687c495f2cb3f3a390d04854dcceb2ef74e Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 21 Oct 2021 11:17:15 -0700 Subject: feat(rc): expanded tree printing --- sys/cmd/rc/lex.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 5 deletions(-) (limited to 'sys/cmd/rc/lex.c') diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c index eb3a268..31c7cdc 100644 --- a/sys/cmd/rc/lex.c +++ b/sys/cmd/rc/lex.c @@ -10,6 +10,9 @@ struct Lexer { int c[2]; ushort doprompt; + ushort hadword; + ushort haddollar; + ushort inquote; char buf[BUFSIZ]; }; @@ -166,40 +169,67 @@ putrune(char *buf, int c) // ----------------------------------------------------------------------- // exported functions +// TODO: turn into static tables int iswordchar(int c) { return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF; } +int +isidentchar(int c) +{ + return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); +} + int yylex(void) { - int c; + int c, d = peekc(); Tree *node; char *w = lexer.buf; yylval.tree = nil; + /* inject tokens */ + if(lexer.hadword){ + if(d=='('){ + advance(); + strcpy(lexer.buf, "( [Tindex]"); + return Tindex; + } + if(iswordchar(d) || d=='\'' || d=='`' || d=='$' || d=='"'){ + strcpy(lexer.buf, "^"); + return '^'; + } + } + + lexer.inquote = 0; + skipws(); switch(c=advance()){ case EOF: + lexer.haddollar = 0; put3('E','O','F'); return EOF; case '@': + lexer.haddollar = 0; put1('@'); return Tsubshell; case '!': + lexer.haddollar = 0; put1('!'); return Tbang; case '&': + lexer.haddollar = 0; put1('&'); return '&'; case '|': + lexer.haddollar = 0; if(nextis('|')){ put2('|','|'); return Toror; @@ -213,6 +243,7 @@ yylex(void) goto redir; case '>': + lexer.haddollar = 0; node = maketree(); *w++ = '>'; node->type = Tredir; @@ -226,6 +257,7 @@ yylex(void) goto redir; case '<': + lexer.haddollar = 0; node = maketree(); *w++ = '<'; node->type = Tredir; @@ -270,7 +302,7 @@ yylex(void) goto badredir; node->redir.type = Rclose; }else{ - node->redir.type = Rdup; + node->redir.type = Rdupfd; node->redir.fd[1] = node->redir.fd[0]; node->redir.fd[0] = 0; do{ @@ -289,6 +321,7 @@ yylex(void) return node->type; case '$': + lexer.haddollar = 1; if(nextis('#')){ put2('$','#'); return Tcount; @@ -300,22 +333,54 @@ yylex(void) put1('$'); return '$'; + case '\'': + lexer.hadword = 1; + lexer.inquote = 1; + lexer.haddollar = 0; + for(;;){ + c = advance(); + if(c==EOF) + break; + + if(c=='\''){ + if(peekc()!='\'') + break; + advance(); + } + w = putrune(w, c); + } + if(w) + *w = 0; + node = token(Tword, lexer.buf); + node->quoted = 1; + return node->type; + default: ; } - if(!iswordchar(c)) + if(!iswordchar(c)){ + put1(c); + lexer.haddollar = 0; return c; + } for(;;){ w = putrune(w, c); c = peekc(); - if(!iswordchar(c)) + if(lexer.haddollar ? !isidentchar(c) : !iswordchar(c)) break; advance(); } - w[0] = 0; + + lexer.hadword = 1; + lexer.haddollar = 0; + if(w) + *w = 0; node = token(Tword, lexer.buf); + // TODO: keywords + + node->quoted = 0; yylval.tree = node; return node->type; -- cgit v1.2.1