Commit 7c9b9af7 authored by Austin Clements's avatar Austin Clements

Convert interpreter to whole-package compilation.

R=rsc
APPROVED=rsc
DELTA=334  (110 added, 211 deleted, 13 changed)
OCL=33135
CL=33137
parent ceaa7741
# 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.
include $(GOROOT)/src/Make.$(GOARCH)
TARG=eval
GOFILES=\
compiler.go\
decls.go\
expr.go\
func.go\
scope.go\
stmt.go\
type.go\
typec.go\
util.go\
value.go\
include $(GOROOT)/src/Make.pkg
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package eval package eval
import ( import (
"eval";
"fmt"; "fmt";
"go/ast"; "go/ast";
"go/scanner"; "go/scanner";
...@@ -31,19 +30,6 @@ func (a *compiler) diagAt(pos positioned, format string, args ...) { ...@@ -31,19 +30,6 @@ func (a *compiler) diagAt(pos positioned, format string, args ...) {
a.errors.Error(pos.Pos(), fmt.Sprintf(format, args)); a.errors.Error(pos.Pos(), fmt.Sprintf(format, args));
} }
type FuncDecl struct
func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (f *Frame) Func)
type exprCompiler struct
func (a *compiler) compileExpr(b *block, expr ast.Expr, constant bool) *exprCompiler
type assignCompiler struct
func (a *compiler) checkAssign(pos token.Position, rs []*exprCompiler, errOp, errPosName string) (*assignCompiler, bool)
func (a *compiler) compileAssign(pos token.Position, lt Type, rs []*exprCompiler, errOp, errPosName string) (func(lv Value, f *Frame))
func (a *compiler) compileType(b *block, typ ast.Expr) Type
func (a *compiler) compileTypeDecl(b *block, decl *ast.GenDecl) bool
func (a *compiler) compileFuncType(b *block, typ *ast.FuncType) *FuncDecl
func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool)
type label struct { type label struct {
name string; name string;
...@@ -64,9 +50,6 @@ type label struct { ...@@ -64,9 +50,6 @@ type label struct {
used token.Position; used token.Position;
} }
type codeBuf struct
type flowBuf struct
type FuncType struct
// A funcCompiler captures information used throughout the compilation // A funcCompiler captures information used throughout the compilation
// of a single function body. // of a single function body.
type funcCompiler struct { type funcCompiler struct {
...@@ -81,8 +64,6 @@ type funcCompiler struct { ...@@ -81,8 +64,6 @@ type funcCompiler struct {
err bool; err bool;
} }
func (a *funcCompiler) checkLabels()
// A blockCompiler captures information used throughout the compilation // A blockCompiler captures information used throughout the compilation
// of a single block within a function. // of a single block within a function.
type blockCompiler struct { type blockCompiler struct {
...@@ -96,11 +77,6 @@ type blockCompiler struct { ...@@ -96,11 +77,6 @@ type blockCompiler struct {
parent *blockCompiler; parent *blockCompiler;
} }
func (a *blockCompiler) compileStmt(s ast.Stmt)
func (a *blockCompiler) compileStmts(body *ast.BlockStmt)
func (a *blockCompiler) enterChild() *blockCompiler
func (a *blockCompiler) exit()
// An exprContext stores information used throughout the compilation // An exprContext stores information used throughout the compilation
// of a single expression. It does not embed funcCompiler because // of a single expression. It does not embed funcCompiler because
// expressions can appear at top level. // expressions can appear at top level.
......
...@@ -13,8 +13,6 @@ import ( ...@@ -13,8 +13,6 @@ import (
* Types * Types
*/ */
type Value interface
type Type interface { type Type interface {
// compat returns whether this type is compatible with another // compat returns whether this type is compatible with another
// type. If conv is false, this is normal compatibility, // type. If conv is false, this is normal compatibility,
...@@ -128,7 +126,6 @@ type PtrValue interface { ...@@ -128,7 +126,6 @@ type PtrValue interface {
Set(Value); Set(Value);
} }
type Func interface
type FuncValue interface { type FuncValue interface {
Value; Value;
Get() Func; Get() Func;
...@@ -158,8 +155,6 @@ type Constant struct { ...@@ -158,8 +155,6 @@ type Constant struct {
Value Value; Value Value;
} }
type Scope struct
// A block represents a definition block in which a name may not be // A block represents a definition block in which a name may not be
// defined more than once. // defined more than once.
type block struct { type block struct {
...@@ -192,15 +187,6 @@ type Scope struct { ...@@ -192,15 +187,6 @@ type Scope struct {
maxVars int; maxVars int;
} }
func (b *block) enterChild() *block
func (b *block) exit()
func (b *block) ChildScope() *Scope
func (b *block) DefineVar(name string, pos token.Position, t Type) (*Variable, Def)
func (b *block) DefineSlot(t Type) *Variable
func (b *block) DefineConst(name string, pos token.Position, t Type, v Value) *Constant
func (b *block) DefineType(name string, pos token.Position, t Type) Type
func (b *block) Lookup(name string) (level int, def Def)
// The universal scope // The universal scope
func newUniverse() *Scope { func newUniverse() *Scope {
sc := &Scope{nil, 0}; sc := &Scope{nil, 0};
...@@ -221,11 +207,6 @@ type Frame struct { ...@@ -221,11 +207,6 @@ type Frame struct {
Vars []Value; Vars []Value;
} }
func (f *Frame) Get(level int, index int) Value
func (f *Frame) child(numVars int) *Frame
func (s *Scope) NewFrame(outer *Frame) *Frame
/* /*
* Functions * Functions
*/ */
......
...@@ -6,7 +6,6 @@ package eval ...@@ -6,7 +6,6 @@ package eval
import ( import (
"bignum"; "bignum";
"eval";
"go/ast"; "go/ast";
"go/scanner"; "go/scanner";
"go/token"; "go/token";
...@@ -59,35 +58,6 @@ func newExprCompiler(c *exprContext, pos token.Position) *exprCompiler { ...@@ -59,35 +58,6 @@ func newExprCompiler(c *exprContext, pos token.Position) *exprCompiler {
}; };
} }
// Operator generators
// TODO(austin) Remove these forward declarations
func (a *exprCompiler) genConstant(v Value)
func (a *exprCompiler) genIdentOp(level int, index int)
func (a *exprCompiler) genIndexArray(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genFuncCall(call func(f *Frame) []Value)
func (a *exprCompiler) genValue(vf func(*Frame) Value)
func (a *exprCompiler) genUnaryOpNeg(v *exprCompiler)
func (a *exprCompiler) genUnaryOpNot(v *exprCompiler)
func (a *exprCompiler) genUnaryOpXor(v *exprCompiler)
func (a *exprCompiler) genBinOpAdd(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpSub(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpMul(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpQuo(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpRem(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpAnd(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpOr(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpXor(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpAndNot(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpShl(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpShr(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpLss(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpGtr(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpLeq(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpGeq(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpEql(l *exprCompiler, r *exprCompiler)
func (a *exprCompiler) genBinOpNeq(l *exprCompiler, r *exprCompiler)
func genAssign(lt Type, r *exprCompiler) (func(lv Value, f *Frame))
func (a *exprCompiler) copy() *exprCompiler { func (a *exprCompiler) copy() *exprCompiler {
ec := newExprCompiler(a.exprContext, a.pos); ec := newExprCompiler(a.exprContext, a.pos);
ec.desc = a.desc; ec.desc = a.desc;
......
...@@ -4,11 +4,6 @@ ...@@ -4,11 +4,6 @@
package eval package eval
import (
"container/vector";
"eval";
)
/* /*
* Virtual machine * Virtual machine
*/ */
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package eval package eval
import ( import (
"eval";
"fmt"; "fmt";
"go/token"; "go/token";
"log"; "log";
......
...@@ -6,7 +6,6 @@ package eval ...@@ -6,7 +6,6 @@ package eval
import ( import (
"bignum"; "bignum";
"eval";
"log"; "log";
"os"; "os";
"go/ast"; "go/ast";
...@@ -244,8 +243,7 @@ func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable { ...@@ -244,8 +243,7 @@ func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable {
return v; return v;
} }
// TODO(austin) Move the real definition // TODO(austin) Move doAssign to here
func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, declTypeExpr ast.Expr)
/* /*
* Statement visitors * Statement visitors
......
...@@ -6,7 +6,6 @@ package eval ...@@ -6,7 +6,6 @@ package eval
import ( import (
"bignum"; "bignum";
"eval";
"go/ast"; "go/ast";
"go/token"; "go/token";
"log"; "log";
...@@ -147,7 +146,10 @@ func (boolType) String() string { ...@@ -147,7 +146,10 @@ func (boolType) String() string {
return "<bool>"; return "<bool>";
} }
func (t *boolType) Zero() Value func (t *boolType) Zero() Value {
res := boolV(false);
return &res;
}
/* /*
* Uint * Uint
...@@ -199,7 +201,31 @@ func (t *uintType) String() string { ...@@ -199,7 +201,31 @@ func (t *uintType) String() string {
return "<" + t.name + ">"; return "<" + t.name + ">";
} }
func (t *uintType) Zero() Value func (t *uintType) Zero() Value {
switch t.Bits {
case 0:
if t.Ptr {
res := uintptrV(0);
return &res;
} else {
res := uintV(0);
return &res;
}
case 8:
res := uint8V(0);
return &res;
case 16:
res := uint16V(0);
return &res;
case 32:
res := uint32V(0);
return &res;
case 64:
res := uint64V(0);
return &res;
}
panic("unexpected uint bit count: ", t.Bits);
}
func (t *uintType) minVal() *bignum.Rational { func (t *uintType) minVal() *bignum.Rational {
return bignum.Rat(0, 1); return bignum.Rat(0, 1);
...@@ -260,7 +286,27 @@ func (t *intType) String() string { ...@@ -260,7 +286,27 @@ func (t *intType) String() string {
return "<" + t.name + ">"; return "<" + t.name + ">";
} }
func (t *intType) Zero() Value func (t *intType) Zero() Value {
switch t.Bits {
case 8:
res := int8V(0);
return &res;
case 16:
res := int16V(0);
return &res;
case 32:
res := int32V(0);
return &res;
case 64:
res := int64V(0);
return &res;
case 0:
res := intV(0);
return &res;
}
panic("unexpected int bit count: ", t.Bits);
}
func (t *intType) minVal() *bignum.Rational { func (t *intType) minVal() *bignum.Rational {
bits := t.Bits; bits := t.Bits;
...@@ -309,7 +355,9 @@ func (t *idealIntType) String() string { ...@@ -309,7 +355,9 @@ func (t *idealIntType) String() string {
return "ideal integer"; return "ideal integer";
} }
func (t *idealIntType) Zero() Value func (t *idealIntType) Zero() Value {
return &idealIntV{bignum.Int(0)};
}
/* /*
* Float * Float
...@@ -347,7 +395,20 @@ func (t *floatType) String() string { ...@@ -347,7 +395,20 @@ func (t *floatType) String() string {
return "<" + t.name + ">"; return "<" + t.name + ">";
} }
func (t *floatType) Zero() Value func (t *floatType) Zero() Value {
switch t.Bits {
case 32:
res := float32V(0);
return &res;
case 64:
res := float64V(0);
return &res;
case 0:
res := floatV(0);
return &res;
}
panic("unexpected float bit count: ", t.Bits);
}
var maxFloat32Val = bignum.MakeRat(bignum.Int(0xffffff).Shl(127-23), bignum.Nat(1)); var maxFloat32Val = bignum.MakeRat(bignum.Int(0xffffff).Shl(127-23), bignum.Nat(1));
var maxFloat64Val = bignum.MakeRat(bignum.Int(0x1fffffffffffff).Shl(1023-52), bignum.Nat(1)); var maxFloat64Val = bignum.MakeRat(bignum.Int(0x1fffffffffffff).Shl(1023-52), bignum.Nat(1));
...@@ -415,7 +476,9 @@ func (t *idealFloatType) String() string { ...@@ -415,7 +476,9 @@ func (t *idealFloatType) String() string {
return "ideal float"; return "ideal float";
} }
func (t *idealFloatType) Zero() Value func (t *idealFloatType) Zero() Value {
return &idealFloatV{bignum.Rat(1, 0)};
}
/* /*
* String * String
...@@ -440,7 +503,10 @@ func (t *stringType) String() string { ...@@ -440,7 +503,10 @@ func (t *stringType) String() string {
return "<string>"; return "<string>";
} }
func (t *stringType) Zero() Value func (t *stringType) Zero() Value {
res := stringV("");
return &res;
}
/* /*
* Array * Array
...@@ -487,7 +553,18 @@ func (t *ArrayType) String() string { ...@@ -487,7 +553,18 @@ func (t *ArrayType) String() string {
return "[]" + t.Elem.String(); return "[]" + t.Elem.String();
} }
func (t *ArrayType) Zero() Value 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;
}
/* /*
* Struct * Struct
...@@ -606,7 +683,13 @@ func (t *StructType) String() string { ...@@ -606,7 +683,13 @@ func (t *StructType) String() string {
return s + "}"; return s + "}";
} }
func (t *StructType) Zero() Value func (t *StructType) Zero() Value {
res := structV(make([]Value, len(t.Elems)));
for i, f := range t.Elems {
res[i] = f.Type.Zero();
}
return &res;
}
/* /*
* Pointer * Pointer
...@@ -646,7 +729,9 @@ func (t *PtrType) String() string { ...@@ -646,7 +729,9 @@ func (t *PtrType) String() string {
return "*" + t.Elem.String(); return "*" + t.Elem.String();
} }
func (t *PtrType) Zero() Value func (t *PtrType) Zero() Value {
return &ptrV{nil};
}
/* /*
* Function * Function
...@@ -749,7 +834,9 @@ func (t *FuncType) String() string { ...@@ -749,7 +834,9 @@ func (t *FuncType) String() string {
return s; return s;
} }
func (t *FuncType) Zero() Value func (t *FuncType) Zero() Value {
return &funcV{nil};
}
type FuncDecl struct { type FuncDecl struct {
Type *FuncType; Type *FuncType;
...@@ -919,4 +1006,10 @@ func (t *MultiType) String() string { ...@@ -919,4 +1006,10 @@ func (t *MultiType) String() string {
return typeListString(t.Elems, nil); return typeListString(t.Elems, nil);
} }
func (t *MultiType) Zero() Value func (t *MultiType) Zero() Value {
res := make([]Value, len(t.Elems));
for i, t := range t.Elems {
res[i] = t.Zero();
}
return multiV(res);
}
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package eval package eval
import ( import (
"eval";
"go/ast"; "go/ast";
"go/token"; "go/token";
"log"; "log";
...@@ -16,12 +15,6 @@ import ( ...@@ -16,12 +15,6 @@ import (
* Type compiler * Type compiler
*/ */
// TODO(austin) Without this, I get a "conflicting definitions for
// eval.compiler" when gopack'ing typec.6 from gobuild.
// Interestingly, if I create the Makefile with this line, then
// comment it out and use the Makefile, things work.
type exprCompiler struct
type typeCompiler struct { type typeCompiler struct {
*compiler; *compiler;
block *block; block *block;
...@@ -32,8 +25,6 @@ type typeCompiler struct { ...@@ -32,8 +25,6 @@ type typeCompiler struct {
lateCheck func() bool lateCheck func() bool
} }
func (a *typeCompiler) compileType(x ast.Expr, allowRec bool) Type
func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type { func (a *typeCompiler) compileIdent(x *ast.Ident, allowRec bool) Type {
_, def := a.block.Lookup(x.Value); _, def := a.block.Lookup(x.Value);
if def == nil { if def == nil {
......
...@@ -6,7 +6,6 @@ package eval ...@@ -6,7 +6,6 @@ package eval
import ( import (
"bignum"; "bignum";
"eval";
"fmt"; "fmt";
"go/token"; "go/token";
) )
......
...@@ -6,7 +6,6 @@ package eval ...@@ -6,7 +6,6 @@ package eval
import ( import (
"bignum"; "bignum";
"eval";
"fmt"; "fmt";
) )
...@@ -32,11 +31,6 @@ func (v *boolV) Set(x bool) { ...@@ -32,11 +31,6 @@ func (v *boolV) Set(x bool) {
*v = boolV(x); *v = boolV(x);
} }
func (t *boolType) Zero() Value {
res := boolV(false);
return &res;
}
/* /*
* Uint * Uint
*/ */
...@@ -149,32 +143,6 @@ func (v *uintptrV) Set(x uint64) { ...@@ -149,32 +143,6 @@ func (v *uintptrV) Set(x uint64) {
*v = uintptrV(x); *v = uintptrV(x);
} }
func (t *uintType) Zero() Value {
switch t.Bits {
case 0:
if t.Ptr {
res := uintptrV(0);
return &res;
} else {
res := uintV(0);
return &res;
}
case 8:
res := uint8V(0);
return &res;
case 16:
res := uint16V(0);
return &res;
case 32:
res := uint32V(0);
return &res;
case 64:
res := uint64V(0);
return &res;
}
panic("unexpected uint bit count: ", t.Bits);
}
/* /*
* Int * Int
*/ */
...@@ -269,28 +237,6 @@ func (v *intV) Set(x int64) { ...@@ -269,28 +237,6 @@ func (v *intV) Set(x int64) {
*v = intV(x); *v = intV(x);
} }
func (t *intType) Zero() Value {
switch t.Bits {
case 8:
res := int8V(0);
return &res;
case 16:
res := int16V(0);
return &res;
case 32:
res := int32V(0);
return &res;
case 64:
res := int64V(0);
return &res;
case 0:
res := intV(0);
return &res;
}
panic("unexpected int bit count: ", t.Bits);
}
/* /*
* Ideal int * Ideal int
*/ */
...@@ -311,10 +257,6 @@ func (v *idealIntV) Get() *bignum.Integer { ...@@ -311,10 +257,6 @@ func (v *idealIntV) Get() *bignum.Integer {
return v.V; return v.V;
} }
func (t *idealIntType) Zero() Value {
return &idealIntV{bignum.Int(0)};
}
/* /*
* Float * Float
*/ */
...@@ -373,21 +315,6 @@ func (v *floatV) Set(x float64) { ...@@ -373,21 +315,6 @@ func (v *floatV) Set(x float64) {
*v = floatV(x); *v = floatV(x);
} }
func (t *floatType) Zero() Value {
switch t.Bits {
case 32:
res := float32V(0);
return &res;
case 64:
res := float64V(0);
return &res;
case 0:
res := floatV(0);
return &res;
}
panic("unexpected float bit count: ", t.Bits);
}
/* /*
* Ideal float * Ideal float
*/ */
...@@ -408,10 +335,6 @@ func (v *idealFloatV) Get() *bignum.Rational { ...@@ -408,10 +335,6 @@ func (v *idealFloatV) Get() *bignum.Rational {
return v.V; return v.V;
} }
func (t *idealFloatType) Zero() Value {
return &idealFloatV{bignum.Rat(1, 0)};
}
/* /*
* String * String
*/ */
...@@ -434,11 +357,6 @@ func (v *stringV) Set(x string) { ...@@ -434,11 +357,6 @@ func (v *stringV) Set(x string) {
*v = stringV(x); *v = stringV(x);
} }
func (t *stringType) Zero() Value {
res := stringV("");
return &res;
}
/* /*
* Array * Array
*/ */
...@@ -465,19 +383,6 @@ func (v *arrayV) Elem(i int64) Value { ...@@ -465,19 +383,6 @@ func (v *arrayV) Elem(i int64) Value {
return (*v)[i]; 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;
}
/* /*
* Struct * Struct
*/ */
...@@ -513,14 +418,6 @@ func (v *structV) Field(i int) Value { ...@@ -513,14 +418,6 @@ func (v *structV) Field(i int) Value {
return (*v)[i]; return (*v)[i];
} }
func (t *StructType) Zero() Value {
res := structV(make([]Value, len(t.Elems)));
for i, f := range t.Elems {
res[i] = f.Type.Zero();
}
return &res;
}
/* /*
* Pointer * Pointer
*/ */
...@@ -546,10 +443,6 @@ func (v *ptrV) Set(x Value) { ...@@ -546,10 +443,6 @@ func (v *ptrV) Set(x Value) {
v.target = x; v.target = x;
} }
func (t *PtrType) Zero() Value {
return &ptrV{nil};
}
/* /*
* Functions * Functions
*/ */
...@@ -575,10 +468,6 @@ func (v *funcV) Set(x Func) { ...@@ -575,10 +468,6 @@ func (v *funcV) Set(x Func) {
v.target = x; v.target = x;
} }
func (t *FuncType) Zero() Value {
return &funcV{nil};
}
/* /*
* Multi-values * Multi-values
*/ */
...@@ -603,14 +492,6 @@ func (v multiV) Assign(o Value) { ...@@ -603,14 +492,6 @@ func (v multiV) Assign(o Value) {
} }
} }
func (t *MultiType) Zero() Value {
res := make([]Value, len(t.Elems));
for i, t := range t.Elems {
res[i] = t.Zero();
}
return multiV(res);
}
/* /*
* Universal constants * Universal constants
*/ */
......
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