ezrosent / frawk

an efficient awk-like language
Apache License 2.0
1.24k stars 34 forks source link

Weird behaviour mixing float calculations and string in print. #75

Closed ghuls closed 2 years ago

ghuls commented 2 years ago

Weird behaviour mixing float calculations and string in print.

❯ printf '1\t2\t3\t4\n' | frawk -F '\t' '{print $1 / 2 "\t" $2; }'
0.5

motif_collections_data/cluster_buster/all on  master 
❯ printf '1\t2\t3\t4\n' | frawk -F '\t' '{print ($1 / 2) "\t" $2; }'
0.5 2

❯ printf '1\t2\t3\t4\n' | frawk -F '\t' '{print $1 / 2 "\t" $2 / 3; }'
0.16666666666666666

motif_collections_data/cluster_buster/all on  master 
❯ printf '1\t2\t3\t4\n' | frawk -F '\t' '{print $1 / 2 "\t" ($2 / 3); }'
0.5

motif_collections_data/cluster_buster/all on  master 
❯ printf '1\t2\t3\t4\n' | frawk -F '\t' '{print ($1 / 2) "\t" ($2 / 3); }'
0.5 0.6666666666666666
ezrosent commented 2 years ago

This is an operator precedence issue

$ frawk --dump-cfg -F '\t' '{print $1 / 2 "\t" $2 / 3; }' 
...
    8-1 = $(1@int)
    9-1 = <concat>(2@int, " ")
    10-1 = $(2@int)
    11-1 = <concat>(9-1, 10-1)
    12-1 = /(8-1, 11-1)
    13-1 = /(12-1, 3@int)
    print(13-1, 7-1)
...

So this is getting parsed as 1 / (2 "\t" $2) / 3.

This is the same problem as in #54, where the precedence of concatenation in frawk is too high. I might consolidate those two issues soon, but this is a good example of why it'd be nice to replicate Awk's operator precedence semantics. As you've pointed out, the workaround is to use more parentheses.

ezrosent commented 2 years ago

Closing in favor of #54