* gash/arithmetic.scm: New file.
* Makefile.am (SOURCES): Add it.
* gash/lexer.scm (get-arithmetic-expansion): New procedure.
(get-expansion): Check for "$((" and use the new procedure to read an
arithmetic expansion.
* gash/eval.scm (word->qword): Handle '<sh-arithmetic>'.
* tests/unit/eval.scm: Add tests.
* tests/spec/Makefile.am (TESTS): Add 'arith'.
* tests/spec/oil.scm: Patch seven of its tests and filter out fifteen
others.
* doc/gash.texi, doc/syntax.txt: Add '<sh-arithmetic>' syntax.
This adjustment paves the way for writing a compiler.
* gash/word.scm (eval-cmd-sub, string-not-null?, word->qword,
expand-word): Move these...
* gash/eval.scm: ...to this module.
* tests/unit/word.scm: Adjust qword tests to use 'expand-qword', and
move non-qword (evaluation) tests to...
* tests/unit/eval.scm: ...this new file, adjusting them to use
'eval-word'.
* Makefile.am (UNIT_TESTS): Add the new file.
* gash/shell.scm (swap-and-shift-pairs): Remove procedure.
(make-pipes): Remove procedure.
(plumb): Accept another port as an argument and close it when setting
up the child process.
(sh:pipeline): Do not use 'make-pipes' to create all the pipe ports
upfront, but rather create them as needed and give them directly to
'plumb'.
* gash/shell.scm (redir->parameter+port): Rename this...
(process-redirect): ...to this, and make it return a list with the
third element being a boolean indicating if the port was opened by us.
(sh:with-redirects): Close ports when the new boolean is set.
The old implementation had several bugs, prompting this complete
rewrite.
* gash/compat/srfi-43.scm (vector-empty?): New procedure.
* gash/pattern.scm (pattern-null?): New procedure.
* gash/word.scm (qword->pattern-string): New procedure.
(qword->pattern): Rewrite using 'qword->pattern-string'.
(find-files): New procedure.
(expand-pathnames): Rewrite using 'find-files' and add a docstring.
* tests/unit/word.scm: Add tests.
(mock): New syntax.
(make-pure-scandir): New procedure.
(with-mocked-files): New syntax.
* gash/pattern.scm (<pattern>): Remove the 'start-anchored?' and
'end-anchored?' fields.
(parse-pattern): Replace the fields with empty parts at the start or
end of the parts list.
(pattern-plain?): Instead of checking the fields, just check the
number of parts.
(pattern-match?, pattern-drop, pattern-drop-right): Do not worry about
the fields, because the empty parts ensure the right thing happens.
These were mixed up, with ':+' behaving like '+' and vice versa.
* gash/word.scm (word->qword): Swap implementations of '<sh-ref-and>'
and '<sh-ref-and*>'.
* tests/unit/word.scm: Swap tests.
* gash/lexer.scm (read-backquoted-command): Make the default procedure
accept a 'quoted?' keyword.
(get-backquoted-command): Accept a 'quoted?' keyword and pass it on to
'read-backquoted-command'.
(get-expansion): Accept a 'quoted?' keyword and pass it on to
'get-backquoted-command'.
(get-double-quotation): Set the 'quoted?' keyword when calling
'get-expansion'.
* tests/unit/lexer.scm: Add tests.
* gash/parser.scm (call-with-backquoted-input-port): Accept a
'quoted?' keyword which, if set, adds the double quote character to
the set of escapable characters.
(read-sh/backquoted): Accept a 'quoted?' keyword and pass it on to
'call-with-backquoted-input-port'.
* tests/unit/parser.scm: Add tests.
* gash/word.scm (word->qword): Add an implementation for the
'<sh-ref-assert>' and '<sh-ref-assert*>' cases.
* tests/variable-operators.org: New file.
* Makefile.am (FULL_TESTS): Add it.
* gash/eval.scm (eval-word): Add 'on-command-substitution' keyword.
(eval-sh): On '<sh-set!>' reset the exit status unless a command
substitution has occurred.
* tests/assignments.org: Add tests.
* gash/shell.scm (sh:exec-let): Do not throw on special built-in
errors.
* gash/built-ins/break.scm (main),
gash/built-ins/continue.scm (main),
gash/built-ins/return.scm (main),
gash/built-ins/shift.scm (main): Throw on error.
* gash/built-ins/utils.scm (string->nonnegative-integer): New procedure.
* gash/built-ins/trap.scm (main): If the first argument is a number,
treat it as if the action were '-'.
* gash/built-ins/read.scm (split-fields): New procedure.
(main): Use it to split the input into fields and assign each field to
its corresponding variable.
* tests/read.org: New file.
* Makefile.am (FULL_TESTS): Add it.
* gash/environment.scm (save-variables-excursion): New procedure.
* gash/shell.scm (sh:exec-let): Use it to set up temporary assignments
during the extent of a function.
* tests/temporary-assignments.org: New file.
* Makefile.am (TESTS): Add it.
* gash/pattern.scm (parse-matching-bracket-expression): Do not
report errors until a full bracket expression has been parsed.
* tests/unit/pattern.scm: Add test.
This commit adds an implementation for the '#', '##', '%', and '%%'
variable operators.
* gash/word.scm (word->qword): Add an implementation for the
'<sh-ref-except-min>', '<sh-ref-except-max>', '<sh-ref-skip-min>',
and '<sh-ref-skip-max>' cases.
* gash/pattern.scm (string-contains-part-right): New procedure.
(pattern-drop): New procedure.
(pattern-drop-right): New procedure.
* tests/unit/pattern.scm: Test the dropping procedures.
* gash/compat/srfi-43.scm: New file.
* Makefile.am: Add it.
* gash/pattern.scm (<pattern>): New record type.
(parse-part): New procedure.
(parse-pattern): Return a '<pattern>'.
(pattern-plain?, pattern-match?): Accept a '<pattern>'.
(string-starts-with-part, string-ends-with-part,
string-contains-part): Treat 'part' as a vector.
It turns out that 'with-continuation-barrier' allows delimited
continuations (i.e., prompts) to get through.
* gash/shell.scm (%subshell): Replace 'with-continuation-barrier' with
'dynamic-wind', making sure to preserve exit statuses that were leaked
through before.
* tests/unit/shell.scm (call-with-temporary-directory): Replace
'with-continuation-barrier' with 'dynamic-wind'.
* tests/spec/oil.scm: Enable previously failing tests.
* gash/built-ins/utils.scm (string->exit-status): New procedure.
* gash/built-ins/return.scm (main): Use it to simplify argument
checking; check for too many arguments; and print messages on
errors.
* tests/functions.org (Too many arguments to return): New test.
* gash/built-ins/utils.scm (string->positive-integer): New function.
* gash/built-ins/break.scm (main): Use it to simplify argument
checking; check for too many arguments; and print messages on errors.
* gash/built-ins/continue.scm (main): Ditto.
* gash/shell.scm (sh:exec-let): Throw an error if a special built-in
fails.
* tests/spec/oil.scm: Enable and adjust previously failing tests.
This commit fixes many differences between the parser output and the
syntax document.
* gash/parser.scm (make-parser): Only wrap a command list with
'<sh-begin>' when necessary.
* tests/unit/parser.scm: Update tests accordingly.