def walk
bolt@1.27.0.0 · src/rules/pedantic/tail.bend:30
import bolt@1.27.0.0/src/rules/pedantic/tail.bend as Tail
import Base
import bolt@1.27.0.0/src/finding.bend as F
import bolt@1.27.0.0/src/syntax/lex.bend as Lex
import bolt@1.27.0.0/src/syntax/tree.bend as Tree
30
31def walk(nn: Tree.Node, +name: String, +path: String, skip: Bool) -> List<&2, F.Finding>:
32 match nn:
33 case Tree.NCons{Tree.Leaf{Lex.Tok{k, +t, +l, +c}}, Tree.NCons{Tree.Group{Lex.Tok{_, +o, _, _}, +kids, _}, rest}}:
34 +call = String.eq(o, "(")
35 +me = Bool.and(Bool.and(call, String.eq(t, name)), Bool.not(skip))
36 +inside = walk(kids, name, path, False{})
37 +more = List.concat(&2, F.Finding, [
38 Bool.pick(List<&2, F.Finding>, Bool.and(call, String.eq(t, "Bool.pick")), [], inside),
39 walk(rest, name, path, False{})])
40 Bool.pick(List<&2, F.Finding>, me,
41 F.Finding{path, l, c, U32.from_nat(String.length(name)), "tail",
42 "This call to " ++ name ++ " is not a tail call, so a long list or string overflows the stack on the JS lane; carry an accumulator."}
43 <> more,
44 more)
45 case Tree.NCons{Tree.Group{open, kids, close}, rest}:
46 List.concat(&2, F.Finding, [walk(kids, name, path, False{}), walk(rest, name, path, False{})])
47 case Tree.NCons{Tree.Stmt{kind, +kids, body}, rest}:
48 List.concat(&2, F.Finding, [walk(kids, name, path, bare(kids, name)), walk(body, name, path, False{}),
49 walk(rest, name, path, False{})])
50 case Tree.NCons{h, rest}:
51 walk(rest, name, path, False{})
52 case other:
53 Nil{}