Skip to content

Commit

Permalink
jq: Fix functions with empty list body
Browse files Browse the repository at this point in the history
jq's find_free_references failed on empty lists; add handling for that
case.

Add relevant test in step4.
  • Loading branch information
dubek authored and kanaka committed Aug 26, 2024
1 parent dab788c commit f7ab284
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 24 deletions.
52 changes: 28 additions & 24 deletions impls/jq/utils.jq
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,34 @@ def find_free_references(keys):
| if .kind == "symbol" then
if keys | contains([$dot.value]) then [] else [$dot.value] end
else if "list" == $dot.kind then
# if - scan args
# def! - scan body
# let* - add keys sequentially, scan body
# fn* - add keys, scan body
# quote - []
# quasiquote - ???
$dot.value[0] as $head
| if $head.kind == "symbol" then
(
select($head.value == "if") | $dot.value[1:] | map(_refs) | reduce .[] as $x ([]; . + $x)
) // (
select($head.value == "def!") | $dot.value[2] | _refs
) // (
select($head.value == "let*") | $dot.value[2] | find_free_references(($dot.value[1].value as $value | ([ range(0; $value|length; 2) ] | map(select(. % 2 == 0) | $value[.].value))) + keys)
) // (
select($head.value == "fn*") | $dot.value[2] | find_free_references(($dot.value[1].value | map(.value)) + keys)
) // (
select($head.value == "quote") | []
) // (
select($head.value == "quasiquote") | []
) // ($dot.value | map(_refs) | reduce .[] as $x ([]; . + $x))
else
[ $dot.values[1:][] | _refs ]
end
if $dot.value|length == 0 then
[]
else
# if - scan args
# def! - scan body
# let* - add keys sequentially, scan body
# fn* - add keys, scan body
# quote - []
# quasiquote - ???
$dot.value[0] as $head
| if $head.kind == "symbol" then
(
select($head.value == "if") | $dot.value[1:] | map(_refs) | reduce .[] as $x ([]; . + $x)
) // (
select($head.value == "def!") | $dot.value[2] | _refs
) // (
select($head.value == "let*") | $dot.value[2] | find_free_references(($dot.value[1].value as $value | ([ range(0; $value|length; 2) ] | map(select(. % 2 == 0) | $value[.].value))) + keys)
) // (
select($head.value == "fn*") | $dot.value[2] | find_free_references(($dot.value[1].value | map(.value)) + keys)
) // (
select($head.value == "quote") | []
) // (
select($head.value == "quasiquote") | []
) // ($dot.value | map(_refs) | reduce .[] as $x ([]; . + $x))
else
[ $dot.values[1:][] | _refs ]
end
end
else if "vector" == $dot.kind then
($dot.value | map(_refs) | reduce .[] as $x ([]; . + $x))
else if "hashmap" == $dot.kind then
Expand Down
2 changes: 2 additions & 0 deletions impls/tests/step4_if_fn_do.mal
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@
;=>7
( (fn* () 4) )
;=>4
( (fn* () ()) )
;=>()

( (fn* (f x) (f x)) (fn* (a) (+ 1 a)) 7)
;=>8
Expand Down

0 comments on commit f7ab284

Please sign in to comment.