示例#1
0
// valString returns the string representation for the value v.
// Setting floatFmt forces an integer value to be formatted in
// normalized floating-point format.
// TODO(gri) Move this code into package exact.
func valString(v exact.Value, floatFmt bool) string {
	switch v.Kind() {
	case exact.Int:
		if floatFmt {
			return floatString(v)
		}
	case exact.Float:
		return floatString(v)
	case exact.Complex:
		re := exact.Real(v)
		im := exact.Imag(v)
		var s string
		if exact.Sign(re) != 0 {
			s = floatString(re)
			if exact.Sign(im) >= 0 {
				s += " + "
			} else {
				s += " - "
				im = exact.UnaryOp(token.SUB, im, 0) // negate im
			}
		}
		// im != 0, otherwise v would be exact.Int or exact.Float
		return s + floatString(im) + "i"
	}
	return v.String()
}
示例#2
0
func (check *checker) unary(x *operand, op token.Token) {
	switch op {
	case token.AND:
		// spec: "As an exception to the addressability
		// requirement x may also be a composite literal."
		if _, ok := unparen(x.expr).(*ast.CompositeLit); ok {
			x.mode = variable
		}
		if x.mode != variable {
			check.invalidOp(x.pos(), "cannot take address of %s", x)
			x.mode = invalid
			return
		}
		x.typ = &Pointer{base: x.typ}
		return

	case token.ARROW:
		typ, ok := x.typ.Underlying().(*Chan)
		if !ok {
			check.invalidOp(x.pos(), "cannot receive from non-channel %s", x)
			x.mode = invalid
			return
		}
		if typ.dir&ast.RECV == 0 {
			check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x)
			x.mode = invalid
			return
		}
		x.mode = commaok
		x.typ = typ.elem
		return
	}

	if !check.op(unaryOpPredicates, x, op) {
		x.mode = invalid
		return
	}

	if x.mode == constant {
		typ := x.typ.Underlying().(*Basic)
		size := -1
		if isUnsigned(typ) {
			size = int(check.conf.sizeof(typ))
		}
		x.val = exact.UnaryOp(op, x.val, size)
		// Typed constants must be representable in
		// their type after each constant operation.
		if isTyped(typ) {
			check.isRepresentableAs(x, typ)
		}
		return
	}

	x.mode = value
	// x.typ remains unchanged
}
示例#3
0
func (p *importer) fraction() exact.Value {
	sign := p.int()
	if sign == 0 {
		return exact.MakeInt64(0)
	}

	x := exact.BinaryOp(p.ufloat(), token.QUO, p.ufloat())
	if sign < 0 {
		x = exact.UnaryOp(token.SUB, x, 0)
	}
	return x
}
示例#4
0
func doOp(x exact.Value, op token.Token, y exact.Value) (z exact.Value) {
	defer panicHandler(&z)

	if x == nil {
		return exact.UnaryOp(op, y, -1)
	}

	switch op {
	case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
		return exact.MakeBool(exact.Compare(x, op, y))
	case token.SHL, token.SHR:
		s, _ := exact.Int64Val(y)
		return exact.Shift(x, op, uint(s))
	default:
		return exact.BinaryOp(x, op, y)
	}
}
示例#5
0
文件: expr.go 项目: rocky/ssa-interp
func evalAction(n ast.Node) exact.Value {
	switch e := n.(type) {
	case *ast.BasicLit:
		return val(e.Value)
	case *ast.BinaryExpr:
		x := evalAction(e.X)
		if x == nil {
			return nil
		}
		y := evalAction(e.Y)
		if y == nil {
			return nil
		}
		switch e.Op {
		case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
			return exact.MakeBool(exact.Compare(x, e.Op, y))
		case token.SHL, token.SHR:
			s, _ := exact.Int64Val(y)
			return exact.Shift(x, e.Op, uint(s))
		default:
			return exact.BinaryOp(x, e.Op, y)
		}
	case *ast.UnaryExpr:
		return exact.UnaryOp(e.Op, evalAction(e.X), -1)
	case *ast.CallExpr:
		fmt.Printf("Can't handle call (%s) yet at pos %d\n", e.Fun, e.Pos())
		return nil
	case *ast.Ident:
		fmt.Printf("Can't handle Ident %s here at pos %d\n", e.Name, e.Pos())
		return nil
	case *ast.ParenExpr:
		return evalAction(e.X)
	default:
		fmt.Println("Can't handle")
		fmt.Printf("n: %s, e: %s\n", n, e)
		return nil
	}
}