Closed benhoyt closed 1 year ago
FWIW, GoAWK had issues with this prior to the resolver rewrite in v1.23.0, though it was an error rather than a panic:
$ git checkout v1.22.0
$ go run . -f t.awk
t.awk:1:33: can't pass scalar "a" as array param
function f1(a) { if (0) f5(z1); f2(a) }
^
exit status 1
$ go run . -f t.awk # it's intermittent there as well
42
Old enough versions, like 1.13.0 or 1.9.2 working well on this one.
Note that this broke between v1.18.0 and v1.19.0 in commit https://github.com/benhoyt/goawk/commit/0bc9499481ee7775f1cc5fcca3bcac1443811bf4, which introduces topological sorting. Previously we tried to resolved vars in a loop, up to 500 max iterations while we were still "progressing" (i.e., assigning one or more unknown types), which was potentially O(N^2) but at least did the job.
@xonixx It's a bit of a brute-force solution, but here's my fix: https://github.com/benhoyt/goawk/pull/187 -- let me know if you have better ideas.
Looks good to me. Looks like not much else can be done with the current architecture. Also I guess that topo sort is needed strictly as an optimization, right?
Also I guess that topo sort is needed strictly as an optimization, right?
Yes, that's right. It's on optimization for "normal" tree-like call graphs to only take one pass.
I think I'll merge this fix, and contemplate this further. I'm sure there's a more elegant way to solve this, but it's not urgent or particularly necessary.
Per @xonixx's comment, GoAWK can still panic on mutually-recursive functions that don't have clear type information (pass their args onto new functions without using them as a scalar or array). This doesn't happen often in real code, but it's relatively simple to create an example that breaks the compiler. Copying @xonixx's message below: