Esempio n. 1
0
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
}
Esempio n. 2
0
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
}