diff --git a/gash/parser.scm b/gash/parser.scm index fee54c2..b813c49 100644 --- a/gash/parser.scm +++ b/gash/parser.scm @@ -1,5 +1,5 @@ ;;; Gash -- Guile As SHell -;;; Copyright © 2018 Timothy Sample +;;; Copyright © 2018, 2019 Timothy Sample ;;; ;;; This file is part of Gash. ;;; @@ -181,6 +181,12 @@ is also called when reducing case patterns that end with an unbalanced closing bracket. This ensures that when parsing valid Shell code, @var{open-bracket-hook} and @var{close-bracket-hook} should be called the same number of times.)" + + (define command-list->block + (match-lambda + ((cmd) cmd) + ((cmds ...) `( ,@cmds)))) + (lalr-parser (AND ; '&' @@ -243,17 +249,12 @@ the same number of times.)" (complete-command (list separator-op) - : (let ((lst (match $2 - ('AND (reverse! (cons `( ,(car $1)) (cdr $1)))) - ('SEMI (reverse! $1))))) - (if (null? (cdr lst)) - (car lst) - (cons ' lst))) + : (command-list->block + (match $2 + ('AND (reverse! (cons `( ,(car $1)) (cdr $1)))) + ('SEMI (reverse! $1)))) (list) - : (let ((lst (reverse! $1))) - (if (null? (cdr lst)) - (car lst) - (cons ' lst)))) + : (command-list->block (reverse! $1))) (list (list separator-op and-or) @@ -299,7 +300,7 @@ the same number of times.)" (compound-command (brace-group) - : $1 + : (command-list->block $1) (subshell) : $1 (for-clause) @@ -315,19 +316,15 @@ the same number of times.)" (subshell (LPAREN! compound-list RPAREN!) - : `( ,$2)) + : `( ,@$2)) (compound-list (linebreak term) - : (match $2 - ((cmd) cmd) - (cmds `( ,@(reverse! cmds)))) + : (reverse! $2) (linebreak term separator) - : (match (match $3 - ('AND (cons `( ,(car $2)) (cdr $2))) - ((or 'SEMI 'NEWLINE) $2)) - ((cmd) cmd) - (cmds `( ,@(reverse! cmds))))) + : (reverse! (match $3 + ('AND (cons `( ,(car $2)) (cdr $2))) + ((or 'SEMI 'NEWLINE) $2)))) (term (term separator and-or) @@ -339,13 +336,13 @@ the same number of times.)" (for-clause (For name do-group) - : `( (,$2 (( ( "@")))) ,$3) + : `( (,$2 (( ( "@")))) ,@$3) (For name sequential-sep do-group) - : `( (,$2 (( ( "@")))) ,$4) + : `( (,$2 (( ( "@")))) ,@$4) (For name linebreak in sequential-sep do-group) - : `( (,$2 ()) ,$6) + : `( (,$2 ()) ,@$6) (For name linebreak in wordlist sequential-sep do-group) - : `( (,$2 ,$5) ,$7)) + : `( (,$2 ,$5) ,@$7)) (name (NAME-with-keywords) @@ -385,21 +382,21 @@ the same number of times.)" (pattern! RPAREN! linebreak) : `(,$1 #f) (pattern! RPAREN! compound-list) - : `(,$1 ,$3) + : `(,$1 ,@$3) (LPAREN! pattern RPAREN! linebreak) : `(,$2 #f) (LPAREN! pattern RPAREN! compound-list) - : `(,$2 ,$4)) + : `(,$2 ,@$4)) (case-item (pattern! RPAREN! linebreak DSEMI linebreak) : `(,$1 #f) (pattern! RPAREN! compound-list DSEMI linebreak) - : `(,$1 ,$3) + : `(,$1 ,@$3) (LPAREN! pattern RPAREN! linebreak DSEMI linebreak) : `(,$2 #f) (LPAREN! pattern RPAREN! compound-list DSEMI linebreak) - : `(,$2 ,$4)) + : `(,$2 ,@$4)) (pattern (WORD*-without-Esac) @@ -409,25 +406,25 @@ the same number of times.)" (if-clause (If compound-list Then compound-list else-part Fi) - : `( (,$2 ,$4) ,@$5) + : `( (,(command-list->block $2) ,@$4) ,@$5) (If compound-list Then compound-list Fi) - : `( (,$2 ,$4))) + : `( (,(command-list->block $2) ,@$4))) (else-part (Elif compound-list Then compound-list) - : `((,$2 ,$4)) + : `((,(command-list->block $2) ,@$4)) (Elif compound-list Then compound-list else-part) - : (cons `(,$2 ,$4) $5) + : (cons `(,(command-list->block $2) ,@$4) $5) (Else compound-list) - : `(( ,$2))) + : `(( ,@$2))) (while-clause (While compound-list do-group) - : `( ,$2 ,$3)) + : `( ,(command-list->block $2) ,@$3)) (until-clause (Until compound-list do-group) - : `( ,$2 ,$3)) + : `( ,(command-list->block $2) ,@$3)) (function-definition (fname LPAREN! RPAREN! linebreak function-body) diff --git a/tests/unit/parser.scm b/tests/unit/parser.scm index a19b5de..46b3a68 100644 --- a/tests/unit/parser.scm +++ b/tests/unit/parser.scm @@ -153,8 +153,8 @@ echo bar; }")) (test-equal "Parses subshells" - '( ( ( "echo" "foo") - ( "echo" "bar"))) + '( ( "echo" "foo") + ( "echo" "bar")) (parse "(echo foo; echo bar)")) ;; Here documents @@ -179,10 +179,10 @@ (test-equal "Parses multiple here-documents in a compound list" '( - ( ( ((<< 0 ( "foo\n"))) - ( "cat")) - ( ((<< 0 ( "bar\n"))) - ( "cat")))) + ( ((<< 0 ( "foo\n"))) + ( "cat")) + ( ((<< 0 ( "bar\n"))) + ( "cat"))) (parse "(cat < - ( ( ((<< 0 ( "foo\n"))) - ( "cat")) - ( ((<< 0 ( "bar\n"))) - ( "cat")))) + ( ((<< 0 ( "foo\n"))) + ( "cat")) + ( ((<< 0 ( "bar\n"))) + ( "cat"))) (parse "(\ncat <