mirror of
https://github.com/golang/go.git
synced 2025-05-14 11:54:38 +00:00
container for values. Instead of having one evaluator function that returns a generic Value, there is now an evaluator function for each generalized type that simply returns a native type. The compiler is more type-safe now because there are almost no type conversions at evaluation time and it's impossible to invoke a nil evaluator function during evaluation. This also makes ideals and pointers really clean. As an added bonus, expression evaluation should be faster because it doesn't require heap allocation for every intermediate value, type switches, or lots of conversions to and from Value. It also involves fewer function calls. R=rsc APPROVED=rsc DELTA=431 (280 added, 115 deleted, 36 changed) OCL=31705 CL=31709
141 lines
2.4 KiB
Go
141 lines
2.4 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";
|
|
)
|
|
|
|
/*
|
|
* Types
|
|
*/
|
|
|
|
type Type interface {
|
|
// literal returns this type with all names recursively
|
|
// stripped.
|
|
// TODO(austin) Eliminate the need for this
|
|
literal() Type;
|
|
// compatible returns true if this type is compatible with o.
|
|
// XXX Assignment versus comparison compatibility?
|
|
compatible(o Type) bool;
|
|
// isInteger returns true if this is an integer type.
|
|
isInteger() bool;
|
|
// isFloat returns true if this is a floating type.
|
|
isFloat() bool;
|
|
// isIdeal returns true if this is an ideal int or float.
|
|
isIdeal() bool;
|
|
// String returns the string representation of this type.
|
|
String() string;
|
|
}
|
|
|
|
type BoundedType interface {
|
|
Type;
|
|
// minVal returns the smallest value of this type.
|
|
minVal() *bignum.Rational;
|
|
// maxVal returns the largest value of this type.
|
|
maxVal() *bignum.Rational;
|
|
}
|
|
|
|
/*
|
|
* Values
|
|
*/
|
|
|
|
type Value interface {
|
|
// TODO(austin) Is Type even necessary?
|
|
Type() Type;
|
|
String() string;
|
|
}
|
|
|
|
type BoolValue interface {
|
|
Value;
|
|
Get() bool;
|
|
Set(bool);
|
|
}
|
|
|
|
type UintValue interface {
|
|
Value;
|
|
Get() uint64;
|
|
Set(uint64);
|
|
}
|
|
|
|
type IntValue interface {
|
|
Value;
|
|
Get() int64;
|
|
Set(int64);
|
|
}
|
|
|
|
type IdealIntValue interface {
|
|
Value;
|
|
Get() *bignum.Integer;
|
|
}
|
|
|
|
type FloatValue interface {
|
|
Value;
|
|
Get() float64;
|
|
Set(float64);
|
|
}
|
|
|
|
type IdealFloatValue interface {
|
|
Value;
|
|
Get() *bignum.Rational;
|
|
}
|
|
|
|
type StringValue interface {
|
|
Value;
|
|
Get() string;
|
|
Set(string);
|
|
}
|
|
|
|
type PtrValue interface {
|
|
Value;
|
|
Get() Value;
|
|
Set(Value);
|
|
}
|
|
|
|
/*
|
|
* Scopes
|
|
*/
|
|
|
|
type Variable struct {
|
|
// Index of this variable in the Frame structure
|
|
Index int;
|
|
// Static type of this variable
|
|
Type Type;
|
|
}
|
|
|
|
type Constant struct {
|
|
// TODO(austin) Need Type?
|
|
Type Type;
|
|
Value Value;
|
|
}
|
|
|
|
// A definition can be a *Variable, *Constant, or Type.
|
|
type Def interface {}
|
|
|
|
type Scope struct {
|
|
outer *Scope;
|
|
defs map[string] Def;
|
|
numVars int;
|
|
}
|
|
|
|
func NewRootScope() *Scope
|
|
func (s *Scope) Fork() *Scope
|
|
func (s *Scope) DefineVar(name string, t Type) *Variable
|
|
func (s *Scope) DefineConst(name string, v Value) *Constant
|
|
func (s *Scope) DefineType(name string, t Type) bool
|
|
func (s *Scope) Lookup(name string) (Def, *Scope)
|
|
|
|
/*
|
|
* Frames
|
|
*/
|
|
|
|
type Frame struct {
|
|
Outer *Frame;
|
|
Scope *Scope;
|
|
Vars []Value;
|
|
}
|
|
|
|
func (f *Frame) Get(s *Scope, index int) Value
|