Commit c90bc34d authored by Austin Clements's avatar Austin Clements

Implement cap, len, and make, as well as the general framework

for built-in functions and type conversions.  Extract out
common operations on expression nodes for converting them to
ints and implicitly dereferencing arrays.

R=rsc
APPROVED=rsc
DELTA=442  (365 added, 50 deleted, 27 changed)
OCL=34064
CL=34064
parent e667e8a4
......@@ -67,5 +67,21 @@ type KeyNotFound struct {
}
func (e KeyNotFound) String() string {
return fmt.Sprintf("key %s not found in map", e.Key);
return fmt.Sprintf("key '%v' not found in map", e.Key);
}
type NegativeLength struct {
Len int64;
}
func (e NegativeLength) String() string {
return fmt.Sprintf("negative length: %d", e.Len);
}
type NegativeCapacity struct {
Len int64;
}
func (e NegativeCapacity) String() string {
return fmt.Sprintf("negative capacity: %d", e.Len);
}
This diff is collapsed.
......@@ -175,15 +175,6 @@ var (
UintptrType = universe.DefineType("uintptr", universePos, &uintType{commonType{}, 0, true, "uintptr"});
)
func init() {
// To avoid portability issues all numeric types are distinct
// except byte, which is an alias for uint8.
// Make byte an alias for the named type uint8. Type aliases
// are otherwise impossible in Go, so just hack it here.
universe.defs["byte"] = universe.defs["uint8"];
}
func (t *uintType) compat(o Type, conv bool) bool {
t2, ok := o.lit().(*uintType);
return ok && t == t2;;
......@@ -730,11 +721,26 @@ type FuncType struct {
In []Type;
Variadic bool;
Out []Type;
builtin string;
}
var funcTypes = newTypeArrayMap()
var variadicFuncTypes = newTypeArrayMap()
// Create singleton function types for magic built-in functions
var (
capType = &FuncType{builtin: "cap"};
closeType = &FuncType{builtin: "close"};
closedType = &FuncType{builtin: "closed"};
lenType = &FuncType{builtin: "len"};
makeType = &FuncType{builtin: "make"};
newType = &FuncType{builtin: "new"};
panicType = &FuncType{builtin: "panic"};
paniclnType = &FuncType{builtin: "panicln"};
printType = &FuncType{builtin: "print"};
printlnType = &FuncType{builtin: "println"};
)
// Two function types are identical if they have the same number of
// parameters and result values and if corresponding parameter and
// result types are identical. All "..." parameters have identical
......@@ -757,7 +763,7 @@ func NewFuncType(in []Type, variadic bool, out []Type) *FuncType {
return tI.(*FuncType);
}
t := &FuncType{commonType{}, in, variadic, out};
t := &FuncType{commonType{}, in, variadic, out, ""};
outMap.Put(out, t);
return t;
}
......@@ -807,6 +813,9 @@ func typeListString(ts []Type, ns []*ast.Ident) string {
}
func (t *FuncType) String() string {
if t.builtin != "" {
return "built-in function " + t.builtin;
}
args := typeListString(t.In, nil);
if t.Variadic {
if len(args) > 0 {
......@@ -894,6 +903,8 @@ func (t *SliceType) String() string {
}
func (t *SliceType) Zero() Value {
// The value of an uninitialized slice is nil. The length and
// capacity of a nil slice are 0.
return &sliceV{Slice{nil, 0, 0}};
}
......@@ -940,6 +951,7 @@ func (t *MapType) String() string {
}
func (t *MapType) Zero() Value {
// The value of an uninitialized map is nil.
return &mapV{nil};
}
......@@ -1097,3 +1109,28 @@ func (t *MultiType) Zero() Value {
}
return multiV(res);
}
/*
* Initialize the universe
*/
func init() {
// To avoid portability issues all numeric types are distinct
// except byte, which is an alias for uint8.
// Make byte an alias for the named type uint8. Type aliases
// are otherwise impossible in Go, so just hack it here.
universe.defs["byte"] = universe.defs["uint8"];
// Built-in functions
universe.DefineConst("cap", universePos, capType, nil);
universe.DefineConst("close", universePos, closeType, nil);
universe.DefineConst("closed", universePos, closedType, nil);
universe.DefineConst("len", universePos, lenType, nil);
universe.DefineConst("make", universePos, makeType, nil);
universe.DefineConst("new", universePos, newType, nil);
universe.DefineConst("panic", universePos, panicType, nil);
universe.DefineConst("panicln", universePos, paniclnType, nil);
universe.DefineConst("print", universePos, printType, nil);
universe.DefineConst("println", universePos, printlnType, nil);
}
......@@ -258,6 +258,8 @@ func (a *typeCompiler) compileMapType(x *ast.MapType) Type {
func (a *typeCompiler) compileType(x ast.Expr, allowRec bool) Type {
switch x := x.(type) {
case *ast.BadExpr:
// Error already reported by parser
a.silentErrors++;
return nil;
case *ast.Ident:
......
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