Esempio n. 1
0
func calculateExprs(ctx *Context, bin *ast.BinaryExpr, doOp bool) (string, error) {

	lit, err := calc.Resolve(bin, doOp)
	if err != nil {
		return "", err
	}
	return lit.Value, nil
}
Esempio n. 2
0
func callBuiltin(name string, fn call, expr *ast.CallExpr) (ast.Expr, error) {

	// Walk through the function
	// These should be processed at registration time
	callargs := make([]ast.Expr, len(fn.params))
	for i := range fn.params {
		expr := fn.params[i].Value
		// if expr != nil {
		// 	callargs[i] = expr.(*ast.BasicLit)
		// }
		callargs[i] = expr
	}
	var argpos int
	incoming := expr.Args

	// Verify args and convert to BasicLit before passing along
	if len(callargs) < len(incoming) {
		for i, p := range incoming {
			lit, ok := p.(*ast.BasicLit)
			if !ok {
				log.Fatalf("failed to convert to lit % #v\n", p)
			}
			log.Printf("inc %d %s:% #v\n", i, lit.Kind, p)
		}
		return nil, fmt.Errorf("mismatched arg count %s got: %d wanted: %d",
			name, len(incoming), len(callargs))
	}

	for i, arg := range incoming {
		if argpos < i {
			argpos = i
		}
		switch v := arg.(type) {
		case *ast.KeyValueExpr:
			pos := fn.Pos(v.Key.(*ast.Ident))
			callargs[pos] = v.Value.(*ast.BasicLit)
		case *ast.ListLit:
			callargs[argpos] = v
		case *ast.Ident:
			if v.Obj != nil {
				ass := v.Obj.Decl.(*ast.AssignStmt)
				callargs[argpos] = ass.Rhs[0]
			} else {
				callargs[argpos] = v
			}

		default:
			lit, err := calc.Resolve(v, true)
			if err == nil {
				callargs[argpos] = lit
			} else {
				return nil, err
			}
		}
	}
	if fn.ch != nil {
		lits := make([]*ast.BasicLit, len(callargs))
		var err error
		for i, x := range callargs {
			lits[i], err = calc.Resolve(x, true)
			// lits[i], ok = exprToLit(x)
			if err != nil {
				return nil, fmt.Errorf("failed to parse arg(%d) in %s: %s", i, fn.name, err)
			}
		}
		return fn.ch(expr, lits...)
	}
	return fn.handle(expr, callargs...)
}