func (v *BreakAndNextCheck) Visit(s *SemanticAnalyzer, n parser.Node) { switch n := n.(type) { case *parser.NextStat, *parser.BreakStat: if v.nestedLoopCount[v.functions[len(v.functions)-1]] == 0 { s.Err(n, "%s must be in a loop", util.CapitalizeFirst(n.NodeName())) } case *parser.LoopStat: v.nestedLoopCount[v.functions[len(v.functions)-1]]++ case *parser.FunctionDecl: v.functions = append(v.functions, n.Function) case *parser.LambdaExpr: v.functions = append(v.functions, n.Function) } }
func (v *MiscCheck) Visit(s *SemanticAnalyzer, n parser.Node) { if _, ok := n.(*parser.FunctionDecl); ok { v.InFunction++ } if v.InFunction <= 0 { switch n.(type) { case *parser.ReturnStat: s.Err(n, "%s must be in function", util.CapitalizeFirst(n.NodeName())) } } else { switch n.(type) { case *parser.TypeDecl: s.Err(n, "%s must not be in function", util.CapitalizeFirst(n.NodeName())) } } }
func (v *UnreachableCheck) PostVisit(s *SemanticAnalyzer, n parser.Node) { switch n := n.(type) { case *parser.Block: for i, c := range n.Nodes { if i < len(n.Nodes)-1 && IsNodeTerminating(c) { s.Err(n.Nodes[i+1], "Unreachable code") } } if len(n.Nodes) > 0 { n.IsTerminating = IsNodeTerminating(n.Nodes[len(n.Nodes)-1]) } case *parser.FunctionDecl: v.visitFunction(s, n, n.Function) case *parser.LambdaExpr: v.visitFunction(s, n, n.Function) } }