From 97c15e2a4e496fc2a95730c96dd414b3599c9ae3 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 2 Jan 2023 12:03:00 -0600 Subject: [PATCH] Math priority fixes, and &&/|| had assignment suppression reversed. --- tests/sh.test | 6 ++++++ toys/pending/sh.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/tests/sh.test b/tests/sh.test index 768ae712..8ae3e1df 100644 --- a/tests/sh.test +++ b/tests/sh.test @@ -258,6 +258,12 @@ testing "nesting ? :" \ testing "inherited assignment suppression" 'echo $((0 ? (x++) : 2)); echo $x' \ "2\n\n" "" "" testing "boolean vs logical" 'echo $((2|4&&8))' '1\n' '' '' +testing "&& vs || priority" \ + 'echo $((w++||x++&&y++||z++)) w=$w x=$x y=$y z=$z' \ + '0 w=1 x=1 y= z=1\n' '' '' +testing "|| vs && priority" \ + 'echo $((w++&&x++||y++&&z++)) w=$w x=$x y=$y z=$z' \ + '0 w=1 x= y=1 z=\n' '' '' # Loops and flow control testing "case" 'for i in A C J B; do case "$i" in A) echo got A ;; B) echo and B ;; C) echo then C ;; *) echo default ;; esac; done' \ diff --git a/toys/pending/sh.c b/toys/pending/sh.c index ace4b216..1c595cfc 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -598,6 +598,7 @@ static int recalculate(long long *dd, char **ss, int lvl) // At lvl 0 "" is ok, anything higher needs a non-empty equation if (lvl || (cc && cc!=')')) return 0; *dd = 0; + return 1; } @@ -660,16 +661,16 @@ static int recalculate(long long *dd, char **ss, int lvl) } // x**y binds first - if (lvl<=13) while (strstart(nospace(ss), "**")) { - if (!recalculate(&ee, ss, noa|14)) return 0; + if (lvl<=14) while (strstart(nospace(ss), "**")) { + if (!recalculate(&ee, ss, noa|15)) return 0; if (ee<0) perror_msg("** < 0"); for (ff = *dd, *dd = 1; ee; ee--) *dd *= ff; } // w*x/y%z bind next - if (lvl<=12) while ((cc = **nospace(ss)) && strchr("*/%", cc)) { + if (lvl<=13) while ((cc = **nospace(ss)) && strchr("*/%", cc)) { ++*ss; - if (!recalculate(&ee, ss, noa|13)) return 0; + if (!recalculate(&ee, ss, noa|14)) return 0; if (cc=='*') *dd *= ee; else if (cc=='%') *dd %= ee; else if (!ee) { @@ -679,61 +680,61 @@ static int recalculate(long long *dd, char **ss, int lvl) } // x+y-z - if (lvl<=11) while ((cc = **nospace(ss)) && strchr("+-", cc)) { + if (lvl<=12) while ((cc = **nospace(ss)) && strchr("+-", cc)) { ++*ss; - if (!recalculate(&ee, ss, noa|12)) return 0; + if (!recalculate(&ee, ss, noa|13)) return 0; if (cc=='+') *dd += ee; else *dd -= ee; } // x<> - if (lvl<=10) while ((cc = **nospace(ss)) && strchr("<>", cc) && cc==(*ss)[1]){ + if (lvl<=11) while ((cc = **nospace(ss)) && strchr("<>", cc) && cc==(*ss)[1]){ *ss += 2; - if (!recalculate(&ee, ss, noa|11)) return 0; + if (!recalculate(&ee, ss, noa|12)) return 0; if (cc == '<') *dd <<= ee; else *dd >>= ee; } // x >= - if (lvl<=9) while ((cc = **nospace(ss)) && strchr("<>", cc)) { + if (lvl<=10) while ((cc = **nospace(ss)) && strchr("<>", cc)) { if ((ii = *++*ss=='=')) ++*ss; - if (!recalculate(&ee, ss, noa|10)) return 0; + if (!recalculate(&ee, ss, noa|11)) return 0; if (cc=='<') *dd = ii ? (*dd<=ee) : (*dd=ee) : (*dd>ee); } - if (lvl<=8) while ((cc = **nospace(ss)) && strchr("=!", cc) && (*ss)[1]=='='){ + if (lvl<=9) while ((cc = **nospace(ss)) && strchr("=!", cc) && (*ss)[1]=='='){ *ss += 2; - if (!recalculate(&ee, ss, noa|9)) return 0; + if (!recalculate(&ee, ss, noa|10)) return 0; *dd = (cc=='!') ? *dd != ee : *dd == ee; } - if (lvl<=7) while (**nospace(ss)=='&' && (*ss)[1]!='&') { + if (lvl<=8) while (**nospace(ss)=='&' && (*ss)[1]!='&') { ++*ss; - if (!recalculate(&ee, ss, noa|8)) return 0; + if (!recalculate(&ee, ss, noa|9)) return 0; *dd &= ee; } - if (lvl<=6) while (**nospace(ss)=='^') { + if (lvl<=7) while (**nospace(ss)=='^') { ++*ss; - if (!recalculate(&ee, ss, noa|7)) return 0; + if (!recalculate(&ee, ss, noa|8)) return 0; *dd ^= ee; } - if (lvl<=5) while (**nospace(ss)=='|' && (*ss)[1]!='|') { + if (lvl<=6) while (**nospace(ss)=='|' && (*ss)[1]!='|') { ++*ss; - if (!recalculate(&ee, ss, noa|6)) return 0; + if (!recalculate(&ee, ss, noa|7)) return 0; *dd |= ee; } if (lvl<=5) while (strstart(nospace(ss), "&&")) { - if (!recalculate(&ee, ss, noa|6|NO_ASSIGN*!!*dd)) return 0; + if (!recalculate(&ee, ss, noa|6|NO_ASSIGN*!*dd)) return 0; *dd = *dd && ee; } if (lvl<=4) while (strstart(nospace(ss), "||")) { - if (!recalculate(&ee, ss, noa|5|NO_ASSIGN*!*dd)) return 0; + if (!recalculate(&ee, ss, noa|5|NO_ASSIGN*!!*dd)) return 0; *dd = *dd || ee; } -- 2.39.2