mirror of
https://github.com/golang/go
synced 2024-11-12 08:50:22 -07:00
Split decls.go up, taking advantage of whole-package
compilation to put the definitions in reasonable places. No code changes, just movement. R=rsc APPROVED=rsc DELTA=479 (232 added, 247 deleted, 0 changed) OCL=34067 CL=34069
This commit is contained in:
parent
345c1bd473
commit
30dcb13420
@ -9,7 +9,6 @@ GOFILES=\
|
||||
abort.go\
|
||||
bridge.go\
|
||||
compiler.go\
|
||||
decls.go\
|
||||
expr.go\
|
||||
func.go\
|
||||
scope.go\
|
||||
|
@ -37,6 +37,17 @@ func (a *compiler) numError() int {
|
||||
return a.numErrors + a.silentErrors;
|
||||
}
|
||||
|
||||
// The universal scope
|
||||
func newUniverse() *Scope {
|
||||
sc := &Scope{nil, 0};
|
||||
sc.block = &block{
|
||||
scope: sc,
|
||||
defs: make(map[string] Def)
|
||||
};
|
||||
return sc;
|
||||
}
|
||||
var universe *Scope = newUniverse();
|
||||
|
||||
|
||||
// TODO(austin) These can all go in stmt.go now
|
||||
type label struct {
|
||||
|
@ -1,250 +0,0 @@
|
||||
// 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";
|
||||
"go/token";
|
||||
)
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
type Type interface {
|
||||
// compat returns whether this type is compatible with another
|
||||
// type. If conv is false, this is normal compatibility,
|
||||
// where two named types are compatible only if they are the
|
||||
// same named type. If conv if true, this is conversion
|
||||
// compatibility, where two named types are conversion
|
||||
// compatible if their definitions are conversion compatible.
|
||||
//
|
||||
// TODO(austin) Deal with recursive types
|
||||
compat(o Type, conv bool) bool;
|
||||
// lit returns this type's literal. If this is a named type,
|
||||
// this is the unnamed underlying type. Otherwise, this is an
|
||||
// identity operation.
|
||||
lit() Type;
|
||||
// isBoolean returns true if this is a boolean type.
|
||||
isBoolean() 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;
|
||||
// Zero returns a new zero value of this type.
|
||||
Zero() Value;
|
||||
// String returns the string representation of this type.
|
||||
String() string;
|
||||
// The position where this type was defined, if any.
|
||||
Pos() token.Position;
|
||||
}
|
||||
|
||||
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 {
|
||||
String() string;
|
||||
// Assign copies another value into this one. It should
|
||||
// assume that the other value satisfies the same specific
|
||||
// value interface (BoolValue, etc.), but must not assume
|
||||
// anything about its specific type.
|
||||
Assign(o Value);
|
||||
}
|
||||
|
||||
type BoolValue interface {
|
||||
Value;
|
||||
Get() bool;
|
||||
Set(bool);
|
||||
}
|
||||
|
||||
type UintValue interface {
|
||||
Value;
|
||||
Get() uint64;
|
||||
Set(uint64);
|
||||
}
|
||||
|
||||
type IntValue interface {
|
||||
Value;
|
||||
Get() int64;
|
||||
Set(int64);
|
||||
}
|
||||
|
||||
// TODO(austin) IdealIntValue and IdealFloatValue should not exist
|
||||
// because ideals are not l-values.
|
||||
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 ArrayValue interface {
|
||||
Value;
|
||||
// TODO(austin) Get() is here for uniformity, but is
|
||||
// completely useless. If a lot of other types have similarly
|
||||
// useless Get methods, just special-case these uses.
|
||||
Get() ArrayValue;
|
||||
Elem(i int64) Value;
|
||||
// From returns an ArrayValue backed by the same array that
|
||||
// starts from element i.
|
||||
From(i int64) ArrayValue;
|
||||
}
|
||||
|
||||
type StructValue interface {
|
||||
Value;
|
||||
// TODO(austin) This is another useless Get()
|
||||
Get() StructValue;
|
||||
Field(i int) Value;
|
||||
}
|
||||
|
||||
type PtrValue interface {
|
||||
Value;
|
||||
Get() Value;
|
||||
Set(Value);
|
||||
}
|
||||
|
||||
type Func interface {
|
||||
NewFrame() *Frame;
|
||||
Call(*Frame);
|
||||
}
|
||||
|
||||
type FuncValue interface {
|
||||
Value;
|
||||
Get() Func;
|
||||
Set(Func);
|
||||
}
|
||||
|
||||
type Slice struct {
|
||||
Base ArrayValue;
|
||||
Len, Cap int64;
|
||||
}
|
||||
|
||||
type SliceValue interface {
|
||||
Value;
|
||||
Get() Slice;
|
||||
Set(Slice);
|
||||
}
|
||||
|
||||
type Map interface {
|
||||
Len() int64;
|
||||
// Retrieve an element from the map, returning nil if it does
|
||||
// not exist.
|
||||
Elem(key interface{}) Value;
|
||||
// Set an entry in the map. If val is nil, delete the entry.
|
||||
SetElem(key interface{}, val Value);
|
||||
// TODO(austin) Perhaps there should be an iterator interface instead.
|
||||
Iter(func(key interface{}, val Value) bool);
|
||||
}
|
||||
|
||||
type MapValue interface {
|
||||
Value;
|
||||
Get() Map;
|
||||
Set(Map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scopes
|
||||
*/
|
||||
|
||||
// A definition can be a *Variable, *Constant, or Type.
|
||||
type Def interface {
|
||||
Pos() token.Position;
|
||||
}
|
||||
|
||||
type Variable struct {
|
||||
token.Position;
|
||||
// Index of this variable in the Frame structure
|
||||
Index int;
|
||||
// Static type of this variable
|
||||
Type Type;
|
||||
// Value of this variable. This is only used by Scope.NewFrame;
|
||||
// therefore, it is useful for global scopes but cannot be used
|
||||
// in function scopes.
|
||||
Init Value;
|
||||
}
|
||||
|
||||
type Constant struct {
|
||||
token.Position;
|
||||
Type Type;
|
||||
Value Value;
|
||||
}
|
||||
|
||||
// A block represents a definition block in which a name may not be
|
||||
// defined more than once.
|
||||
type block struct {
|
||||
// The block enclosing this one, including blocks in other
|
||||
// scopes.
|
||||
outer *block;
|
||||
// The nested block currently being compiled, or nil.
|
||||
inner *block;
|
||||
// The Scope containing this block.
|
||||
scope *Scope;
|
||||
// The Variables, Constants, and Types defined in this block.
|
||||
defs map[string] Def;
|
||||
// The index of the first variable defined in this block.
|
||||
// This must be greater than the index of any variable defined
|
||||
// in any parent of this block within the same Scope at the
|
||||
// time this block is entered.
|
||||
offset int;
|
||||
// The number of Variables defined in this block.
|
||||
numVars int;
|
||||
}
|
||||
|
||||
// A Scope is the compile-time analogue of a Frame, which captures
|
||||
// some subtree of blocks.
|
||||
type Scope struct {
|
||||
// The root block of this scope.
|
||||
*block;
|
||||
// The maximum number of variables required at any point in
|
||||
// this Scope. This determines the number of slots needed in
|
||||
// Frame's created from this Scope at run-time.
|
||||
maxVars int;
|
||||
}
|
||||
|
||||
// The universal scope
|
||||
func newUniverse() *Scope {
|
||||
sc := &Scope{nil, 0};
|
||||
sc.block = &block{
|
||||
scope: sc,
|
||||
defs: make(map[string] Def)
|
||||
};
|
||||
return sc;
|
||||
}
|
||||
var universe *Scope = newUniverse();
|
||||
|
||||
/*
|
||||
* Frames
|
||||
*/
|
||||
|
||||
type Frame struct {
|
||||
Outer *Frame;
|
||||
Vars []Value;
|
||||
}
|
@ -10,6 +10,65 @@ import (
|
||||
"log";
|
||||
)
|
||||
|
||||
/*
|
||||
* Blocks and scopes
|
||||
*/
|
||||
|
||||
// A definition can be a *Variable, *Constant, or Type.
|
||||
type Def interface {
|
||||
Pos() token.Position;
|
||||
}
|
||||
|
||||
type Variable struct {
|
||||
token.Position;
|
||||
// Index of this variable in the Frame structure
|
||||
Index int;
|
||||
// Static type of this variable
|
||||
Type Type;
|
||||
// Value of this variable. This is only used by Scope.NewFrame;
|
||||
// therefore, it is useful for global scopes but cannot be used
|
||||
// in function scopes.
|
||||
Init Value;
|
||||
}
|
||||
|
||||
type Constant struct {
|
||||
token.Position;
|
||||
Type Type;
|
||||
Value Value;
|
||||
}
|
||||
|
||||
// A block represents a definition block in which a name may not be
|
||||
// defined more than once.
|
||||
type block struct {
|
||||
// The block enclosing this one, including blocks in other
|
||||
// scopes.
|
||||
outer *block;
|
||||
// The nested block currently being compiled, or nil.
|
||||
inner *block;
|
||||
// The Scope containing this block.
|
||||
scope *Scope;
|
||||
// The Variables, Constants, and Types defined in this block.
|
||||
defs map[string] Def;
|
||||
// The index of the first variable defined in this block.
|
||||
// This must be greater than the index of any variable defined
|
||||
// in any parent of this block within the same Scope at the
|
||||
// time this block is entered.
|
||||
offset int;
|
||||
// The number of Variables defined in this block.
|
||||
numVars int;
|
||||
}
|
||||
|
||||
// A Scope is the compile-time analogue of a Frame, which captures
|
||||
// some subtree of blocks.
|
||||
type Scope struct {
|
||||
// The root block of this scope.
|
||||
*block;
|
||||
// The maximum number of variables required at any point in
|
||||
// this Scope. This determines the number of slots needed in
|
||||
// Frame's created from this Scope at run-time.
|
||||
maxVars int;
|
||||
}
|
||||
|
||||
func (b *block) enterChild() *block {
|
||||
if b.inner != nil && b.inner.scope == b.scope {
|
||||
log.Crash("Failed to exit child block before entering another child");
|
||||
@ -117,6 +176,15 @@ func (s *Scope) NewFrame(outer *Frame) *Frame {
|
||||
return fr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frames
|
||||
*/
|
||||
|
||||
type Frame struct {
|
||||
Outer *Frame;
|
||||
Vars []Value;
|
||||
}
|
||||
|
||||
func (f *Frame) Get(level int, index int) Value {
|
||||
for ; level > 0; level-- {
|
||||
f = f.Outer;
|
||||
|
@ -26,6 +26,44 @@ import (
|
||||
// sense in the comparison operators section. The compatibility and
|
||||
// assignment compatibility sections should be rolled into one.
|
||||
|
||||
type Type interface {
|
||||
// compat returns whether this type is compatible with another
|
||||
// type. If conv is false, this is normal compatibility,
|
||||
// where two named types are compatible only if they are the
|
||||
// same named type. If conv if true, this is conversion
|
||||
// compatibility, where two named types are conversion
|
||||
// compatible if their definitions are conversion compatible.
|
||||
//
|
||||
// TODO(austin) Deal with recursive types
|
||||
compat(o Type, conv bool) bool;
|
||||
// lit returns this type's literal. If this is a named type,
|
||||
// this is the unnamed underlying type. Otherwise, this is an
|
||||
// identity operation.
|
||||
lit() Type;
|
||||
// isBoolean returns true if this is a boolean type.
|
||||
isBoolean() 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;
|
||||
// Zero returns a new zero value of this type.
|
||||
Zero() Value;
|
||||
// String returns the string representation of this type.
|
||||
String() string;
|
||||
// The position where this type was defined, if any.
|
||||
Pos() token.Position;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
var universePos = token.Position{"<universe>", 0, 0, 0};
|
||||
|
||||
/*
|
||||
|
@ -9,6 +9,121 @@ import (
|
||||
"fmt";
|
||||
)
|
||||
|
||||
type Value interface {
|
||||
String() string;
|
||||
// Assign copies another value into this one. It should
|
||||
// assume that the other value satisfies the same specific
|
||||
// value interface (BoolValue, etc.), but must not assume
|
||||
// anything about its specific type.
|
||||
Assign(o Value);
|
||||
}
|
||||
|
||||
type BoolValue interface {
|
||||
Value;
|
||||
Get() bool;
|
||||
Set(bool);
|
||||
}
|
||||
|
||||
type UintValue interface {
|
||||
Value;
|
||||
Get() uint64;
|
||||
Set(uint64);
|
||||
}
|
||||
|
||||
type IntValue interface {
|
||||
Value;
|
||||
Get() int64;
|
||||
Set(int64);
|
||||
}
|
||||
|
||||
// TODO(austin) IdealIntValue and IdealFloatValue should not exist
|
||||
// because ideals are not l-values.
|
||||
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 ArrayValue interface {
|
||||
Value;
|
||||
// TODO(austin) Get() is here for uniformity, but is
|
||||
// completely useless. If a lot of other types have similarly
|
||||
// useless Get methods, just special-case these uses.
|
||||
Get() ArrayValue;
|
||||
Elem(i int64) Value;
|
||||
// From returns an ArrayValue backed by the same array that
|
||||
// starts from element i.
|
||||
From(i int64) ArrayValue;
|
||||
}
|
||||
|
||||
type StructValue interface {
|
||||
Value;
|
||||
// TODO(austin) This is another useless Get()
|
||||
Get() StructValue;
|
||||
Field(i int) Value;
|
||||
}
|
||||
|
||||
type PtrValue interface {
|
||||
Value;
|
||||
Get() Value;
|
||||
Set(Value);
|
||||
}
|
||||
|
||||
type Func interface {
|
||||
NewFrame() *Frame;
|
||||
Call(*Frame);
|
||||
}
|
||||
|
||||
type FuncValue interface {
|
||||
Value;
|
||||
Get() Func;
|
||||
Set(Func);
|
||||
}
|
||||
|
||||
type Slice struct {
|
||||
Base ArrayValue;
|
||||
Len, Cap int64;
|
||||
}
|
||||
|
||||
type SliceValue interface {
|
||||
Value;
|
||||
Get() Slice;
|
||||
Set(Slice);
|
||||
}
|
||||
|
||||
type Map interface {
|
||||
Len() int64;
|
||||
// Retrieve an element from the map, returning nil if it does
|
||||
// not exist.
|
||||
Elem(key interface{}) Value;
|
||||
// Set an entry in the map. If val is nil, delete the entry.
|
||||
SetElem(key interface{}, val Value);
|
||||
// TODO(austin) Perhaps there should be an iterator interface instead.
|
||||
Iter(func(key interface{}, val Value) bool);
|
||||
}
|
||||
|
||||
type MapValue interface {
|
||||
Value;
|
||||
Get() Map;
|
||||
Set(Map);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bool
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user