1
0
mirror of https://github.com/golang/go synced 2024-10-04 16:21:22 -06:00
go/usr/austin/eval/value.go
Austin Clements 90ffb7b8f5 Cleanup of Type/Value interface. Add Type.ZeroVal, replace
all type-specific value functions, and use ZeroVal to create
new frames.  Remove Value.Type; it was unused and difficult
for values with composite types.  Add Value.Assign methods.

R=rsc
APPROVED=rsc
DELTA=282  (135 added, 90 deleted, 57 changed)
OCL=31894
CL=31930
2009-07-21 13:31:23 -07:00

511 lines
7.5 KiB
Go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package eval
import (
"bignum";
"eval";
"fmt";
)
/*
* Bool
*/
type boolV bool
func (v *boolV) String() string {
return fmt.Sprint(*v);
}
func (v *boolV) Assign(o Value) {
*v = boolV(o.(BoolValue).Get());
}
func (v *boolV) Get() bool {
return bool(*v);
}
func (v *boolV) Set(x bool) {
*v = boolV(x);
}
func (t *boolType) Zero() Value {
res := boolV(false);
return &res;
}
/*
* Uint
*/
type uint8V uint8
func (v *uint8V) String() string {
return fmt.Sprint(*v);
}
func (v *uint8V) Assign(o Value) {
*v = uint8V(o.(UintValue).Get());
}
func (v *uint8V) Get() uint64 {
return uint64(*v);
}
func (v *uint8V) Set(x uint64) {
*v = uint8V(x);
}
type uint16V uint16
func (v *uint16V) String() string {
return fmt.Sprint(*v);
}
func (v *uint16V) Assign(o Value) {
*v = uint16V(o.(UintValue).Get());
}
func (v *uint16V) Get() uint64 {
return uint64(*v);
}
func (v *uint16V) Set(x uint64) {
*v = uint16V(x);
}
type uint32V uint32
func (v *uint32V) String() string {
return fmt.Sprint(*v);
}
func (v *uint32V) Assign(o Value) {
*v = uint32V(o.(UintValue).Get());
}
func (v *uint32V) Get() uint64 {
return uint64(*v);
}
func (v *uint32V) Set(x uint64) {
*v = uint32V(x);
}
type uint64V uint64
func (v *uint64V) String() string {
return fmt.Sprint(*v);
}
func (v *uint64V) Assign(o Value) {
*v = uint64V(o.(UintValue).Get());
}
func (v *uint64V) Get() uint64 {
return uint64(*v);
}
func (v *uint64V) Set(x uint64) {
*v = uint64V(x);
}
type uintV uint
func (v *uintV) String() string {
return fmt.Sprint(*v);
}
func (v *uintV) Assign(o Value) {
*v = uintV(o.(UintValue).Get());
}
func (v *uintV) Get() uint64 {
return uint64(*v);
}
func (v *uintV) Set(x uint64) {
*v = uintV(x);
}
type uintptrV uintptr
func (v *uintptrV) String() string {
return fmt.Sprint(*v);
}
func (v *uintptrV) Assign(o Value) {
*v = uintptrV(o.(UintValue).Get());
}
func (v *uintptrV) Get() uint64 {
return uint64(*v);
}
func (v *uintptrV) Set(x uint64) {
*v = uintptrV(x);
}
func (t *uintType) Zero() Value {
// TODO(austin) t may be a named type instead of one of the
// base types.
switch Type(t) {
case Uint8Type:
res := uint8V(0);
return &res;
case Uint16Type:
res := uint16V(0);
return &res;
case Uint32Type:
res := uint32V(0);
return &res;
case Uint64Type:
res := uint64V(0);
return &res;
case UintType:
res := uintV(0);
return &res;
case UintptrType:
res := uintptrV(0);
return &res;
}
panic("unknown uint type ", t.String());
}
/*
* Int
*/
type int8V int8
func (v *int8V) String() string {
return fmt.Sprint(*v);
}
func (v *int8V) Assign(o Value) {
*v = int8V(o.(IntValue).Get());
}
func (v *int8V) Get() int64 {
return int64(*v);
}
func (v *int8V) Set(x int64) {
*v = int8V(x);
}
type int16V int16
func (v *int16V) String() string {
return fmt.Sprint(*v);
}
func (v *int16V) Assign(o Value) {
*v = int16V(o.(IntValue).Get());
}
func (v *int16V) Get() int64 {
return int64(*v);
}
func (v *int16V) Set(x int64) {
*v = int16V(x);
}
type int32V int32
func (v *int32V) String() string {
return fmt.Sprint(*v);
}
func (v *int32V) Assign(o Value) {
*v = int32V(o.(IntValue).Get());
}
func (v *int32V) Get() int64 {
return int64(*v);
}
func (v *int32V) Set(x int64) {
*v = int32V(x);
}
type int64V int64
func (v *int64V) String() string {
return fmt.Sprint(*v);
}
func (v *int64V) Assign(o Value) {
*v = int64V(o.(IntValue).Get());
}
func (v *int64V) Get() int64 {
return int64(*v);
}
func (v *int64V) Set(x int64) {
*v = int64V(x);
}
type intV int
func (v *intV) String() string {
return fmt.Sprint(*v);
}
func (v *intV) Assign(o Value) {
*v = intV(o.(IntValue).Get());
}
func (v *intV) Get() int64 {
return int64(*v);
}
func (v *intV) Set(x int64) {
*v = intV(x);
}
func (t *intType) Zero() Value {
switch Type(t) {
case Int8Type:
res := int8V(0);
return &res;
case Int16Type:
res := int16V(0);
return &res;
case Int32Type:
res := int32V(0);
return &res;
case Int64Type:
res := int64V(0);
return &res;
case IntType:
res := intV(0);
return &res;
}
panic("unknown int type ", t.String());
}
/*
* Ideal int
*/
type idealIntV struct {
V *bignum.Integer;
}
func (v *idealIntV) String() string {
return v.V.String();
}
func (v *idealIntV) Assign(o Value) {
v.V = o.(IdealIntValue).Get();
}
func (v *idealIntV) Get() *bignum.Integer {
return v.V;
}
func (t *idealIntType) Zero() Value {
return &idealIntV{bignum.Int(0)};
}
/*
* Float
*/
type float32V float32
func (v *float32V) String() string {
return fmt.Sprint(*v);
}
func (v *float32V) Assign(o Value) {
*v = float32V(o.(FloatValue).Get());
}
func (v *float32V) Get() float64 {
return float64(*v);
}
func (v *float32V) Set(x float64) {
*v = float32V(x);
}
type float64V float64
func (v *float64V) String() string {
return fmt.Sprint(*v);
}
func (v *float64V) Assign(o Value) {
*v = float64V(o.(FloatValue).Get());
}
func (v *float64V) Get() float64 {
return float64(*v);
}
func (v *float64V) Set(x float64) {
*v = float64V(x);
}
type floatV float
func (v *floatV) String() string {
return fmt.Sprint(*v);
}
func (v *floatV) Assign(o Value) {
*v = floatV(o.(FloatValue).Get());
}
func (v *floatV) Get() float64 {
return float64(*v);
}
func (v *floatV) Set(x float64) {
*v = floatV(x);
}
func (t *floatType) Zero() Value {
switch Type(t) {
case Float32Type:
res := float32V(0);
return &res;
case Float64Type:
res := float64V(0);
return &res;
case FloatType:
res := floatV(0);
return &res;
}
panic("unknown float type ", t.String());
}
/*
* Ideal float
*/
type idealFloatV struct {
V *bignum.Rational;
}
func (v *idealFloatV) String() string {
return ratToString(v.V);
}
func (v *idealFloatV) Assign(o Value) {
v.V = o.(IdealFloatValue).Get();
}
func (v *idealFloatV) Get() *bignum.Rational {
return v.V;
}
func (t *idealFloatType) Zero() Value {
return &idealFloatV{bignum.Rat(1, 0)};
}
/*
* String
*/
type stringV string
func (v *stringV) String() string {
return fmt.Sprint(*v);
}
func (v *stringV) Assign(o Value) {
*v = stringV(o.(StringValue).Get());
}
func (v *stringV) Get() string {
return string(*v);
}
func (v *stringV) Set(x string) {
*v = stringV(x);
}
func (t *stringType) Zero() Value {
res := stringV("");
return &res;
}
/*
* Array
*/
type arrayV []Value
func (v *arrayV) String() string {
return fmt.Sprint(*v);
}
func (v *arrayV) Assign(o Value) {
oa := o.(ArrayValue);
l := int64(len(*v));
for i := int64(0); i < l; i++ {
(*v)[i].Assign(oa.Elem(i));
}
}
func (v *arrayV) Get() ArrayValue {
return v;
}
func (v *arrayV) Elem(i int64) Value {
return (*v)[i];
}
func (t *ArrayType) Zero() Value {
res := arrayV(make([]Value, t.Len));
// TODO(austin) It's unfortunate that each element is
// separately heap allocated. We could add ZeroArray to
// everything, though that doesn't help with multidimensional
// arrays. Or we could do something unsafe. We'll have this
// same problem with structs.
for i := int64(0); i < t.Len; i++ {
res[i] = t.Elem.Zero();
}
return &res;
}
/*
* Pointer
*/
type ptrV struct {
// nil if the pointer is nil
target Value;
}
func (v *ptrV) String() string {
return "&" + v.target.String();
}
func (v *ptrV) Assign(o Value) {
v.target = o.(PtrValue).Get();
}
func (v *ptrV) Get() Value {
return v.target;
}
func (v *ptrV) Set(x Value) {
v.target = x;
}
func (t *PtrType) Zero() Value {
res := ptrV{nil};
return &res;
}