Support ${foob-bar} and ${foo+bar}.

* gash/environment.scm (variable): Add default parameter.
(variable-or, variable-and): New function.
* test/07-variable-or.sh: Test it.
* test/07-variable-or-not.sh:
* test/08-variable-and.sh:
* test/08-variable-and-not.sh:
This commit is contained in:
Jan Nieuwenhuizen 2018-11-03 10:04:26 +01:00
parent 418652bee1
commit bca65e807b
11 changed files with 44 additions and 14 deletions

View File

@ -29,6 +29,12 @@ tests="
06-compound-word
06-command-compound-word
07-variable-or
07-variable-not-or
08-variable-and
08-variable-not-and
10-if
10-if-false
10-if-word-variable

View File

@ -29,6 +29,8 @@
set-shell-opt!
shell-opt?
variable
variable-and
variable-or
))
;; FIXME: export/env vs set
@ -50,14 +52,21 @@
(assoc-set! %global-variables name value))
#t))
(define (variable name)
(define* (variable name #:optional (default ""))
(let ((name (if (string-prefix? "$" name) (string-drop name 1) name)))
(or (assoc-ref %global-variables name)
(if (shell-opt? "nounset") (begin
;; TODO: throw/error
(format (current-error-port) "gash: ~a: unbound variable\n" name)
#f)
""))))
default))))
(define (variable-or name default)
(variable name default))
(define (variable-and name default)
(let ((value (variable name #f)))
(and value default)))
(define (set-shell-opt! name set?)
(let* ((shell-opts (variable "SHELLOPTS"))

View File

@ -212,30 +212,28 @@
filename <-- word
name <-- identifier
identifier <- [_a-zA-Z][_a-zA-Z0-9]*
oldword <- substitution / assignment / number / variable / delim / literal
word-for-test-assign-sh <-- assignment / (delim / number / variable / literal)+
word-for-test-if2-sh <-- assignment / delim / (number / variable / literal)+
word <-- assignment / (delim / number / variable / literal)+
word <-- assignment / delim / (number / variable / brace-variable / literal)+
number <-- [0-9]+
lsubst < '$('
rsubst < ')'
tick < '`'
substitution <-- lsubst script rsubst / tick script tick
assignment <-- name assign (substitution / word)*
assignment <-- name assign rhs
rhs <- (substitution / word)*
assign < '='
dollar <- '$'
literal <-- (!tick !dollar !pipe !semi !par !nl !sp .)+
variable <-- dollar (dollar / '*' / '?' / '@' / [0-9] / identifier / ([{] (![}] .)+ [}]))
dollar < '$'
literal <-- (!tick !dollar !pipe !semi !par !nl !sp !rbrace .)+
variable <-- dollar ('$' / '*' / '?' / '@' / [0-9] / identifier)
brace-variable <- dollar lbrace (variable-or / variable-and / identifier) rbrace
variable-and <-- identifier plus rhs
variable-or <-- identifier minus rhs
delim <- singlequotes / doublequotes / substitution
sq < [']
dq < [\"]
bt < [`]
singlequotes <-- sq (doublequotes / (!sq .))* sq
doublequotes <-- dq (singlequotes / substitution / variable / (!dq .))* dq
doublequotes <-- dq (singlequotes / substitution / variable / variable-and-or / (!dq .))* dq
break <- amp / semi !semi
separator <- (sp* break ws*) / ws+
sequential-sep <- (semi !semi ws*) / ws+
@ -243,6 +241,10 @@
semi < ';'
lpar < '('
rpar < ')'
lbrace < [{]
rbrace < [}]
plus < [+]
minus < '-'
par < lpar / rpar
nl < '\n'
sp < [\t ]
@ -282,6 +284,9 @@
((('literal _ ...) _ ...) (map transform (flatten ast)))
((('pipeline _ ...) _ ...) (map transform (flatten ast)))
((('singlequotes _ ...) _ ...) (map transform (flatten ast)))
((('word _ ...) ('word _ ...)) (transform (cons 'word ast)))
((('word _ ...) _ ...) (map transform (flatten ast)))
(('script ('pipeline ('command command ... (word (literal "&")))))

View File

@ -0,0 +1,2 @@
foo=baz
echo ${foo-bar}

View File

@ -0,0 +1 @@
baz

1
test/07-variable-or.sh Normal file
View File

@ -0,0 +1 @@
echo ${foo-bar}

View File

@ -0,0 +1 @@
bar

2
test/08-variable-and.sh Normal file
View File

@ -0,0 +1,2 @@
foo=baz
echo ${foo+bar}

View File

@ -0,0 +1 @@
bar

View File

@ -0,0 +1 @@
echo ${foo+bar}

View File

@ -0,0 +1 @@