Commit fb9490c2 authored by Austin Clements's avatar Austin Clements

Implement slice types

R=rsc
APPROVED=rsc
DELTA=286  (217 added, 42 deleted, 27 changed)
OCL=33319
CL=33383
parent 350a8e1a
......@@ -111,6 +111,9 @@ type ArrayValue interface {
// 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 {
......@@ -126,12 +129,28 @@ type PtrValue interface {
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);
}
/*
* Scopes
*/
......@@ -206,12 +225,3 @@ type Frame struct {
Outer *Frame;
Vars []Value;
}
/*
* Functions
*/
type Func interface {
NewFrame() *Frame;
Call(*Frame);
}
This diff is collapsed.
......@@ -579,7 +579,6 @@ type StructField struct {
type StructType struct {
commonType;
Elems []StructField;
maxDepth int;
}
var structTypes = newTypeArrayMap()
......@@ -626,19 +625,7 @@ func NewStructType(fields []StructField) *StructType {
t, ok := tMap[key];
if !ok {
// Create new struct type
// Compute max anonymous field depth
maxDepth := 1;
for _, f := range fields {
// TODO(austin) Careful of type T struct { *T }
if st, ok := f.Type.(*StructType); ok {
if st.maxDepth + 1 > maxDepth {
maxDepth = st.maxDepth + 1;
}
}
}
t = &StructType{commonType{}, fields, maxDepth};
t = &StructType{commonType{}, fields};
tMap[key] = t;
}
return t;
......@@ -870,11 +857,47 @@ func (t *FuncDecl) String() string {
type InterfaceType struct {
// TODO(austin)
}
*/
type SliceType struct {
// TODO(austin)
commonType;
Elem Type;
}
var sliceTypes = make(map[Type] *SliceType)
// Two slice types are identical if they have identical element types.
func NewSliceType(elem Type) *SliceType {
t, ok := sliceTypes[elem];
if !ok {
t = &SliceType{commonType{}, elem};
sliceTypes[elem] = t;
}
return t;
}
func (t *SliceType) compat(o Type, conv bool) bool {
t2, ok := o.lit().(*SliceType);
if !ok {
return false;
}
return t.Elem.compat(t2.Elem, conv);
}
func (t *SliceType) lit() Type {
return t;
}
func (t *SliceType) String() string {
return "[]" + t.Elem.String();
}
func (t *SliceType) Zero() Value {
return &sliceV{Slice{nil, 0, 0}};
}
/*
type MapType struct {
// TODO(austin)
}
......
......@@ -56,20 +56,22 @@ func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type {
}
func (a *typeCompiler) compileArrayType(x *ast.ArrayType, allowRec bool) Type {
// Compile element type
elem := a.compileType(x.Elt, allowRec);
// Compile length expression
if x.Len == nil {
a.diagAt(x, "slice types not implemented");
return nil;
if elem == nil {
return nil;
}
return NewSliceType(elem);
}
if _, ok := x.Len.(*ast.Ellipsis); ok {
a.diagAt(x.Len, "... array initailizers not implemented");
return nil;
}
l, ok := a.compileArrayLen(a.block, x.Len);
// Compile element type
elem := a.compileType(x.Elt, allowRec);
if !ok {
return nil;
}
......
......@@ -383,6 +383,11 @@ func (v *arrayV) Elem(i int64) Value {
return (*v)[i];
}
func (v *arrayV) From(i int64) ArrayValue {
res := (*v)[i:len(*v)];
return &res;
}
/*
* Struct
*/
......@@ -468,6 +473,37 @@ func (v *funcV) Set(x Func) {
v.target = x;
}
/*
* Slices
*/
type sliceV struct {
Slice;
}
func (v *sliceV) String() string {
res := "{";
for i := int64(0); i < v.Len; i++ {
if i > 0 {
res += ", ";
}
res += v.Base.Elem(i).String();
}
return res + "}";
}
func (v *sliceV) Assign(o Value) {
v.Slice = o.(SliceValue).Get();
}
func (v *sliceV) Get() Slice {
return v.Slice;
}
func (v *sliceV) Set(x Slice) {
v.Slice = x;
}
/*
* Multi-values
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment