Support && and ||.

* gash/script.scm (and-terms, or-terms): New macros.
* gash/peg.scm (transform): Transform to use them.
(parse-): Parse && and || as binary term operator.
* test/20-and.sh: Test it.
* test/20-or.sh: Test it.
* check.sh (tests): Run it.
This commit is contained in:
Jan Nieuwenhuizen 2018-11-04 09:29:02 +01:00
parent 45479fc651
commit 6250b22951
6 changed files with 32 additions and 4 deletions

View File

@ -48,6 +48,8 @@ tests="
11-for-split-sequence
20-semi.sh
20-or.sh
20-and.sh
20-pipe-exit-0
20-pipe-exit-1
20-pipe-sed

View File

@ -152,9 +152,9 @@
(define-peg-string-patterns
"script <-- ws* (term (separator term)* separator?)?
term <- pipeline (sp* (and / or) ws* pipeline)*
and <-- '&&'
or <-- '||'
term <- (and / or / pipeline) (sp* (and / or /pipeline))*
and <-- pipeline sp* amp-amp ws* pipeline
or <-- pipeline sp* pipe-pipe ws* pipeline
pipe < '|'
pipeline <-- negate? pipeline-head pipeline-tail*
pipeline-head <- sp* command
@ -223,7 +223,7 @@
rhs <- (substitution / word)*
assign < '='
dollar < '$'
literal <-- backslash? (!ws !tick !dollar !pipe !semi !par !nl !sp !rbrace .)+
literal <-- backslash? (!ws !amp !tick !dollar !pipe !semi !par !nl !sp !rbrace .)+
variable <-- dollar ('$' / '*' / '?' / '@' / [0-9] / identifier / lbrace identifier rbrace)
variable-and-or <- dollar lbrace (variable-or / variable-and ) rbrace
variable-and <-- identifier plus rhs
@ -238,6 +238,8 @@
separator <- (sp* break ws*) / ws+
sequential-sep <- (semi !semi ws*) / ws+
amp <- '&'
amp-amp < '&&'
pipe-pipe < '||'
backslash <- '\\'
semi < ';'
lpar < '('
@ -326,6 +328,9 @@
(('sequence o ...)
`(sequence (quote ,(map transform o))))
(('and l r) `(and-terms ,(transform l) ,(transform r)))
(('or l r) `(or-terms ,(transform l) ,(transform r)))
(('substitution o) `(substitution ,(transform o)))
(('if-clause expr then) `(if-clause ,(transform expr) ,(transform then)))
(('if-clause expr then else) `(if-clause ,(transform expr) ,(transform then) ,(transform else)))

View File

@ -39,6 +39,7 @@
#:use-module (gash util)
#:export (
and-terms
background
builtin
command
@ -48,6 +49,7 @@
if-clause
ignore-error
literal
or-terms
pipeline
run
script
@ -177,6 +179,22 @@
#'(let ((it (ignore-error expr)))
(if (zero? it) then else)))))))
(define-syntax and-terms
(lambda (x)
(syntax-case x ()
((_ left right)
(with-syntax ((it (datum->syntax x 'it)))
#'(let ((it left))
(if (zero? it) right it)))))))
(define-syntax or-terms
(lambda (x)
(syntax-case x ()
((_ left right)
(with-syntax ((it (datum->syntax x 'it)))
#'(let ((it (ignore-error left)))
(if (zero? it) it right)))))))
(define (pipeline . commands)
(define (handle job)
(when (> %debug-level 1)

1
test/20-and.exit Normal file
View File

@ -0,0 +1 @@
2

1
test/20-and.sh Normal file
View File

@ -0,0 +1 @@
true && exit 2

1
test/20-or.sh Normal file
View File

@ -0,0 +1 @@
false || true