diff --git a/.github/workflows/liquid.yml b/.github/workflows/liquid.yml index c018a495..51b0bee2 100644 --- a/.github/workflows/liquid.yml +++ b/.github/workflows/liquid.yml @@ -56,11 +56,7 @@ jobs: bundler-cache: true bundler: latest - name: Run liquid-spec for all adapters - run: | - for adapter in spec/*.rb; do - echo "=== Running $adapter ===" - bundle exec liquid-spec run "$adapter" --no-max-failures - done + run: bin/liquid-spec-all-adapters memory_profile: runs-on: ubuntu-latest diff --git a/bin/liquid-spec-all-adapters b/bin/liquid-spec-all-adapters new file mode 100755 index 00000000..eb403268 --- /dev/null +++ b/bin/liquid-spec-all-adapters @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +for adapter in spec/*.rb; do + echo "=== Running $adapter ===" + bundle exec liquid-spec run "$adapter" --no-max-failures +done diff --git a/lib/liquid/parser.rb b/lib/liquid/parser.rb index df4d6a27..dcdc37a3 100644 --- a/lib/liquid/parser.rb +++ b/lib/liquid/parser.rb @@ -59,18 +59,18 @@ module Liquid logical end - # Logical relations in Liquid, unlike other languages, are right-to-left - # associative. This creates a right-leaning tree and is why the method - # looks a bit more complicated - # + # Logical relations use right-to-left associativity. # `a and b or c` is evaluated like (a and (b or c)) - # logical := equality (("and" | "or") equality)* + # This enables short-circuit: if `a` is false, entire expression short-circuits. + # logical := equality (("and" | "or") logical)? def logical - operator = nil - expr = equality - expr = BinaryExpression.new(expr, operator, equality) if (operator = consume?(:logical)) - expr.right_node = BinaryExpression.new(expr.right_node, operator, equality) while (operator = consume?(:logical)) - expr + left = equality + if (operator = consume?(:logical)) + right = logical # recursive call builds proper RTL tree + BinaryExpression.new(left, operator, right) + else + left + end end # equality := comparison (("==" | "!=" | "<>") comparison)*