From 4cdba05a3b5cb3e22bd6a9726b15977da060b0ad Mon Sep 17 00:00:00 2001 From: Andy Chu Date: Sun, 26 Aug 2018 21:30:19 -0700 Subject: [PATCH] Working on translating here docs to Oil. - Test an invariant of the arena with here docs. - Make the here-dq.sh test pass by adding a line_span() instance for the ending delimiter. - here-sq.sh still doesn't pass. - Statically evaluate the here doc delimiter at the end of the line, rather when you encounter it. This makes it so there are fewer things in the HereDoc node. - Remove HereDoc.was_filled. Add here_end_span_id. - here-doc spec test: Clarify that multiple leading tabs are stripped. - Move some parse error bugs from cmd_parse_test.py to test/parse-errors.sh. This revealed a bug in osh -c 'cat < token for translation? redir = Redir(token op, int fd, word arg_word) | HereDoc(token op, int fd, - word here_begin, -- For translation - string here_end, bool do_expansion, -- Derived from here_begin - word? body, bool was_filled) + word here_begin, -- e.g. EOF or 'EOF' + int here_end_span_id, -- this span is an entire line + word? body) assign_op = Equal | PlusEqual assign_pair = (lhs_expr lhs, assign_op op, word? rhs) diff --git a/osh/word_parse.py b/osh/word_parse.py index 280c7aee64..d5a0ef0065 100644 --- a/osh/word_parse.py +++ b/osh/word_parse.py @@ -642,6 +642,7 @@ def _ReadDoubleQuotedPart(self, eof_type=Id.Undefined_Tok, here_doc=False): left_spid = const.NO_INTEGER # gets set later right_spid = const.NO_INTEGER # gets set later + # TODO: Use here doc. if self.cur_token is not None: # None in here doc case left_token = self.cur_token left_spid = left_token.span_id @@ -682,7 +683,7 @@ def _ReadDoubleQuotedPart(self, eof_type=Id.Undefined_Tok, here_doc=False): quoted_part.parts.append(ast.LiteralPart(self.cur_token)) else: done = True # assume Id.Right_DoubleQuote - right_spid = self.cur_token.span_id + right_spid = self.cur_token.span_id elif self.token_kind == Kind.Eof: if here_doc: # here docs will have an EOF in their token stream @@ -1203,8 +1204,13 @@ def ReadHereDocBody(self): CompoundWord. NOTE: We could also just use a DoubleQuotedPart for both cases? """ - w = ast.CompoundWord() dq = self._ReadDoubleQuotedPart(here_doc=True) assert dq is not None - w.parts.append(dq) - return w + return ast.CompoundWord([dq]) + + # TODO: _ReadDQContext(parts) should be shared between + # _ReadDoubleQuotedPart() and ReadHereDocBody() + # Call with dq_part.parts + # and here_doc_node.body + + diff --git a/spec/here-doc.test.sh b/spec/here-doc.test.sh index 1a67dc823f..739cdd596b 100644 --- a/spec/here-doc.test.sh +++ b/spec/here-doc.test.sh @@ -295,12 +295,14 @@ EOF cat <<-EOF 1 2 - 3 + 3 # 2 tabs are both stripped + 4 # spaces are preserved EOF ## STDOUT: 1 2 - 3 +3 # 2 tabs are both stripped + 4 # spaces are preserved ## END #### Here doc within subshell with boolean diff --git a/test/arena.sh b/test/arena.sh new file mode 100755 index 0000000000..f10bd358ee --- /dev/null +++ b/test/arena.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# +# Usage: +# ./arena.sh + +set -o nounset +set -o pipefail +set -o errexit + +source test/common.sh + +compare() { + local path=$1 + + mkdir -p _tmp/arena + bin/osh --parse-and-print-arena $path > _tmp/arena/left.txt + diff -u $path _tmp/arena/left.txt +} + +here-doc() { + compare test/arena/here-dq.sh + compare test/arena/here-sq.sh +} + +readonly -a PASSING=( + here-doc +) + +all-passing() { + run-all "${PASSING[@]}" +} + +run-for-release() { + local out_dir=_tmp/arena + mkdir -p $out_dir + + all-passing | tee $out_dir/log.txt + + echo "Wrote $out_dir/log.txt" +} + +"$@" diff --git a/test/arena/here-dq.sh b/test/arena/here-dq.sh new file mode 100755 index 0000000000..2a0766780a --- /dev/null +++ b/test/arena/here-dq.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +echo "DQ" + +cat <