package main import "fmt" // renderExpr centralizes expression lowering; callers supply parameter, owned // field, or getter references. No expression decisions are left to templates. func renderExpr(n *Node, ref func(string) string, m *Module) (string, error) { if n == nil { return "", nil } switch n.Kind { case "value": return n.Text, nil case "fieldref": return ref(n.Text), nil case "enumref": e, owner := findEnum(m, n.Attr["ref"]) if e == nil { return "", n.fail("unknown enum %s", n.Attr["ref"]) } return "int(" + qualified(m, owner, e.Name+goName(n.Text)) + ")", nil case "op", "unop", "popcount": var parts []string for _, c := range n.Children { s, err := renderExpr(c, ref, m) if err != nil { return "", err } parts = append(parts, s) } if n.Kind == "popcount" { return "bits.OnesCount(uint(" + parts[0] + "))", nil } if n.Kind == "unop" { return "(^" + parts[0] + ")", nil } if len(parts) != 2 { return "", n.fail("invalid binary expression") } return "(" + parts[0] + " " + n.Attr["op"] + " " + parts[1] + ")", nil } return "", fmt.Errorf("%s:%d: unsupported expression %s", n.File, n.Line, n.Kind) }