2023-02-22 23:03:42 -05:00
|
|
|
#!/bin/bash
|
|
|
|
# Assert that a program can be derived from the ASG as expected.
|
|
|
|
#
|
|
|
|
# See `./README.md` for more information.
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
mypath=$(dirname "$0")
|
|
|
|
. "$mypath/../../conf.sh"
|
|
|
|
|
2023-02-24 14:11:27 -05:00
|
|
|
# Performing this check within `<()` below won't cause a failure.
|
|
|
|
: "${P_XMLLINT?}" # conf.sh
|
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
run-test() {
|
|
|
|
local name="${1?Missing test name}"
|
|
|
|
local dir="${2?Missing dir}"
|
|
|
|
shift 2
|
|
|
|
|
|
|
|
rm -f "$dir/"*.log
|
|
|
|
|
|
|
|
header "$dir" "$name"
|
|
|
|
|
|
|
|
"test-$name" "$dir" "$@" || {
|
|
|
|
local ret=$?
|
|
|
|
echo ' [FAIL]'
|
|
|
|
return "$ret"
|
|
|
|
}
|
|
|
|
|
|
|
|
echo ' [ OK ]'
|
|
|
|
}
|
|
|
|
|
|
|
|
timed-tamec() {
|
|
|
|
local dir="${1?Missing directory name}"
|
|
|
|
local in="${2?Missing input filename}"
|
|
|
|
local out="${3?Missing output filename}"
|
|
|
|
|
|
|
|
dir="${dir%/}" # strip trailing slash, if any (just to style output)
|
|
|
|
|
|
|
|
local -i ret=0
|
|
|
|
|
2023-03-09 11:02:46 -05:00
|
|
|
# /usr/bin/time does not have high enough precision
|
|
|
|
# This won't be wholly accurate because time is spent in shell,
|
|
|
|
# but it'll be close enough.
|
|
|
|
local -i start_ns=$(date +%s%N)
|
|
|
|
|
2023-06-13 23:23:51 -04:00
|
|
|
local objty=xmlo
|
|
|
|
if [ -f "$dir/is-experimental" ]; then
|
|
|
|
objty=xmlo-experimental
|
|
|
|
fi
|
|
|
|
|
2023-03-09 11:02:46 -05:00
|
|
|
command time -f "%F/%Rfault %I/%Oio %Mrss %c/%wctx \n%C" -o "$dir/time.log" \
|
2023-06-13 23:23:51 -04:00
|
|
|
"${TAMER_PATH_TAMEC?}" -o "$dir/$out" --emit "$objty" "$dir/$in" \
|
2023-03-09 10:43:35 -05:00
|
|
|
&> "$dir/tamec-$out.log" \
|
|
|
|
|| ret=$?
|
|
|
|
|
2023-03-09 11:02:46 -05:00
|
|
|
local -i end_ns=$(date +%s%N)
|
|
|
|
local -i elapsed_ms=$(( (end_ns - start_ns) / 1000000 ))
|
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
# First line will be "Command exited with non-zero status N" on failure.
|
|
|
|
# The last line will be '%C' above.
|
|
|
|
# So, we want the second-to-last line.
|
2023-03-09 11:02:46 -05:00
|
|
|
#
|
|
|
|
# Newline omission is intentional.
|
|
|
|
printf "<%3dms %s" "$elapsed_ms" "$(tail -n2 "$dir/time.log" | head -n1)"
|
2023-03-09 10:43:35 -05:00
|
|
|
|
|
|
|
return "$ret"
|
|
|
|
}
|
|
|
|
|
|
|
|
header() {
|
|
|
|
# allocate enough space based on the path we'll output
|
|
|
|
local -i mypath_len=${#mypath}
|
tamer: xmli reconstruction of desugared interpolated metavars
Well, this is both good news and bad news.
The good news is that this finally produces the expected output and
reconstructs sources from interpolated values on the ASG. Yay!
...the bad news is that it's wrong. Notice how the fixpoint test is
disabled.
So, my plan was originally to commit it like this first and see if I was
comfortable relaxing the convention that `<param>` nodes had to appear in
the header. That's nice to do, that's cleaner to do, but would the
XSLT-based compiler really care? I had to investigate.
Well, turns out that TAMER does care. Because, well over a decade ago, I
re-used `<param>`, which could represent not only a template param, but also
a global param, or a function param.
So, XML->NIR considers all `<param>` nodes at the head of a template to be
template parameters. But after the first non-header element, we transition
to another state that allows it to be pretty much anything.
And so, I can't relax that restriction.
And because of that, I can't just stream the tree to the xmli generator,
I'll have to queue up nodes and order them.
Oh well, I tried.
DEV-13163
2023-07-13 16:41:27 -04:00
|
|
|
local -i dirlen=$((mypath_len + 14))
|
2023-03-09 10:43:35 -05:00
|
|
|
|
|
|
|
# newline intentionally omitted
|
|
|
|
printf "%-${dirlen}s %-20s " "$@"
|
|
|
|
}
|
|
|
|
|
2023-02-24 14:11:27 -05:00
|
|
|
# Derive a program from `src.xml` and verify that it meets our expectations.
|
|
|
|
#
|
|
|
|
# This test is inherently fragile, as it will break any time we perform
|
|
|
|
# certain types of optimizations or change internal representations. _But
|
|
|
|
# that is intended._ We want to be well aware of such changes in derivation
|
|
|
|
# so that we can judge whether it needs adjustment.
|
|
|
|
test-derive-from-src() {
|
2023-03-09 09:19:05 -05:00
|
|
|
local dir="${1?Missing directory name}"
|
2023-02-22 23:03:42 -05:00
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
timed-tamec "$dir" src.xml out.xmli || return
|
2023-03-09 09:19:05 -05:00
|
|
|
|
|
|
|
diff <("$P_XMLLINT" --format "$dir/expected.xml" || echo 'ERR expected.xml') \
|
2023-03-09 10:43:35 -05:00
|
|
|
<("$P_XMLLINT" --format "$dir/out.xmli" || echo 'ERR out.xmli') \
|
|
|
|
&> "$dir/diff.log"
|
2023-02-24 14:11:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Having taken `A` and derived `B`, we should be able to take `B` and derive
|
|
|
|
# `C`, where `B` and `C` are equivalent programs.
|
|
|
|
#
|
|
|
|
# That is, this derivation should be transitively equivalent and reach a
|
|
|
|
# fixpoint on the second derivation. This serves as a sanity check to
|
|
|
|
# ensure that the program we generated makes sense to our own system.
|
|
|
|
#
|
|
|
|
# Note that, in the future, we'll have to strip handoff metadata
|
|
|
|
# (`preproc:*` data) from the output so that it will be accepted by TAMER.
|
|
|
|
test-fixpoint() {
|
2023-03-09 09:19:05 -05:00
|
|
|
local dir="${1?Missing directory name}"
|
|
|
|
|
tamer: xmli reconstruction of desugared interpolated metavars
Well, this is both good news and bad news.
The good news is that this finally produces the expected output and
reconstructs sources from interpolated values on the ASG. Yay!
...the bad news is that it's wrong. Notice how the fixpoint test is
disabled.
So, my plan was originally to commit it like this first and see if I was
comfortable relaxing the convention that `<param>` nodes had to appear in
the header. That's nice to do, that's cleaner to do, but would the
XSLT-based compiler really care? I had to investigate.
Well, turns out that TAMER does care. Because, well over a decade ago, I
re-used `<param>`, which could represent not only a template param, but also
a global param, or a function param.
So, XML->NIR considers all `<param>` nodes at the head of a template to be
template parameters. But after the first non-header element, we transition
to another state that allows it to be pretty much anything.
And so, I can't relax that restriction.
And because of that, I can't just stream the tree to the xmli generator,
I'll have to queue up nodes and order them.
Oh well, I tried.
DEV-13163
2023-07-13 16:41:27 -04:00
|
|
|
if [ -f "$dir/no-fixpoint" ]; then
|
|
|
|
echo -n '!!!WARNING!!! test skipped: `no-fixpoint` file '
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
timed-tamec "$dir" out.xmli out-2.xmli || return
|
2023-02-22 23:03:42 -05:00
|
|
|
|
2023-03-09 09:19:05 -05:00
|
|
|
diff <("$P_XMLLINT" --format "$dir/expected.xml" || echo 'ERR expected.xml') \
|
2023-03-09 10:43:35 -05:00
|
|
|
<("$P_XMLLINT" --format "$dir/out-2.xmli" || echo 'ERR out.xmli') \
|
|
|
|
&> "$dir/diff.log"
|
2023-02-24 14:11:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
main() {
|
2023-03-09 10:43:35 -05:00
|
|
|
local -a fail=()
|
2023-02-24 14:11:27 -05:00
|
|
|
|
2023-03-09 09:19:05 -05:00
|
|
|
for dir in "$mypath"/*/; do
|
2023-03-09 10:43:35 -05:00
|
|
|
run-test derive-from-src "$dir" && run-test fixpoint "$dir" \
|
|
|
|
|| fail=("${fail[@]}" "$dir")
|
2023-03-09 09:19:05 -05:00
|
|
|
done
|
2023-02-24 14:11:27 -05:00
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
test -z "${fail[@]}" || {
|
2023-02-22 23:03:42 -05:00
|
|
|
cat << EOF
|
|
|
|
!!! TEST FAILED
|
|
|
|
tamec: $TAMER_PATH_TAMEC
|
|
|
|
|
2023-02-24 14:11:27 -05:00
|
|
|
note: The compiler output and diff between the expected and given data
|
2023-03-09 10:43:35 -05:00
|
|
|
are below. Both files are formatted with \`xmllint\` automatically.
|
2023-02-22 23:03:42 -05:00
|
|
|
EOF
|
|
|
|
|
2023-03-09 10:43:35 -05:00
|
|
|
for dir in "${fail[@]}"; do
|
|
|
|
echo
|
|
|
|
echo ",=====[ $dir logs ]======"
|
|
|
|
echo "|"
|
|
|
|
cat "$dir/"*.log | sed 's/^/| /'
|
|
|
|
echo "|"
|
|
|
|
echo "\`====[ end $dir logs ]===="
|
|
|
|
done
|
|
|
|
|
2023-02-22 23:03:42 -05:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
main "$@"
|
|
|
|
|