func itpExpand(left, right ast.Expr) string { var s string switch v := left.(type) { case *ast.Interp: s += v.Obj.Decl.(*ast.BasicLit).Value case *ast.BasicLit: s += v.Value } if right != nil { if left.End() < right.Pos() { s += " " } } return s }
func resolve(in ast.Expr, doOp bool) (*ast.BasicLit, error) { x := &ast.BasicLit{ ValuePos: in.Pos(), } var err error switch v := in.(type) { case *ast.StringExpr: list := make([]string, 0, len(v.List)) for _, l := range v.List { lit, err := resolve(l, doOp) if err != nil { return nil, err } list = append(list, lit.Value) } x.Kind = token.QSTRING x.Value = strings.Join(list, "") case *ast.ListLit: // During expr simplification, list are just string delim := " " if v.Comma { delim = ", " } var k token.Token ss := make([]string, len(v.Value)) for i := range v.Value { lit, err := resolve(v.Value[i], doOp) k = lit.Kind if err != nil { return nil, err } ss[i] = lit.Value } x = &ast.BasicLit{ Kind: token.STRING, Value: strings.Join(ss, delim), ValuePos: v.Pos(), } if len(v.Value) == 1 { x.Kind = k } case *ast.UnaryExpr: x = v.X.(*ast.BasicLit) case *ast.BinaryExpr: x, err = binary(v, doOp) case *ast.BasicLit: x = v case *ast.Ident: if v.Obj == nil { return nil, fmt.Errorf("calc: undefined variable %s", v.Name) } // FIXME: we shouldn't attempt to resolve invalid values ie. // interp inside @each if v.Obj.Decl == nil { log.Println("warning, resolution was attempted on an invalid value") return x, nil } rhs := v.Obj.Decl.(*ast.AssignStmt).Rhs kind := token.INT var val []string for _, x := range rhs { lit, err := resolve(x, doOp) if err != nil { return nil, err } // TODO: insufficient! if lit.Kind != kind { kind = lit.Kind } val = append(val, lit.Value) } // TODO: commas are missing x.Value = strings.Join(val, ", ") x.Kind = kind case *ast.CallExpr: x, err = resolve(v.Resolved, doOp) case *ast.Interp: if v.Obj == nil { panic("unresolved interpolation") } x, err = resolve(v.Obj.Decl.(ast.Expr), doOp) default: err = fmt.Errorf("unsupported calc.resolve % #v\n", v) panic(err) } return x, err }