Commit 747cde81 authored by Russ Cox's avatar Russ Cox

s/vm/Thread/

change eval functions from taking *Frame to *Thread

R=austin
DELTA=500  (7 added, 4 deleted, 489 changed)
OCL=34256
CL=34260
parent 72a11c57
......@@ -39,49 +39,49 @@ func Try(f func()) os.Error {
return res;
}
type DivByZero struct {}
type DivByZeroError struct {}
func (DivByZero) String() string {
func (DivByZeroError) String() string {
return "divide by zero";
}
type NilPointer struct {}
type NilPointerError struct {}
func (NilPointer) String() string {
func (NilPointerError) String() string {
return "nil pointer dereference";
}
type IndexOutOfBounds struct {
type IndexError struct {
Idx, Len int64;
}
func (e IndexOutOfBounds) String() string {
func (e IndexError) String() string {
if e.Idx < 0 {
return fmt.Sprintf("negative index: %d", e.Idx);
}
return fmt.Sprintf("index %d exceeds length %d", e.Idx, e.Len);
}
type KeyNotFound struct {
type KeyError struct {
Key interface {};
}
func (e KeyNotFound) String() string {
func (e KeyError) String() string {
return fmt.Sprintf("key '%v' not found in map", e.Key);
}
type NegativeLength struct {
type NegativeLengthError struct {
Len int64;
}
func (e NegativeLength) String() string {
func (e NegativeLengthError) String() string {
return fmt.Sprintf("negative length: %d", e.Len);
}
type NegativeCapacity struct {
type NegativeCapacityError struct {
Len int64;
}
func (e NegativeCapacity) String() string {
func (e NegativeCapacityError) String() string {
return fmt.Sprintf("negative capacity: %d", e.Len);
}
......@@ -146,8 +146,8 @@ func (f *nativeFunc) NewFrame() *Frame {
return &Frame{nil, vars};
}
func (f *nativeFunc) Call(fr *Frame) {
f.fn(fr.Vars[0:f.in], fr.Vars[f.in:f.in+f.out]);
func (f *nativeFunc) Call(t *Thread) {
f.fn(t.f.Vars[0:f.in], t.f.Vars[f.in:f.in+f.out]);
}
// FuncFromNative creates an interpreter function from a native
......
......@@ -277,12 +277,12 @@ func (*testFunc) NewFrame() *Frame {
return &Frame{nil, &[2]Value {}};
}
func (*testFunc) Call(fr *Frame) {
n := fr.Vars[0].(IntValue).Get();
func (*testFunc) Call(t *Thread) {
n := t.f.Vars[0].(IntValue).Get();
res := n + 1;
fr.Vars[1].(IntValue).Set(res);
t.f.Vars[1].(IntValue).Set(res);
}
type oneTwoFunc struct {};
......@@ -291,9 +291,9 @@ func (*oneTwoFunc) NewFrame() *Frame {
return &Frame{nil, &[2]Value {}};
}
func (*oneTwoFunc) Call(fr *Frame) {
fr.Vars[0].(IntValue).Set(1);
fr.Vars[1].(IntValue).Set(2);
func (*oneTwoFunc) Call(t *Thread) {
t.f.Vars[0].(IntValue).Set(1);
t.f.Vars[1].(IntValue).Set(2);
}
type voidFunc struct {};
......@@ -302,7 +302,7 @@ func (*voidFunc) NewFrame() *Frame {
return &Frame{nil, []Value {}};
}
func (*voidFunc) Call(fr *Frame) {
func (*voidFunc) Call(t *Thread) {
}
func newTestScope() *Scope {
......
......@@ -26,16 +26,16 @@ type expr struct {
// Map index expressions permit special forms of assignment,
// for which we need to know the Map and key.
evalMapValue func(f *Frame) (Map, interface{});
evalMapValue func(t *Thread) (Map, interface{});
// Evaluate to the "address of" this value; that is, the
// settable Value object. nil for expressions whose address
// cannot be taken.
evalAddr func(f *Frame) Value;
evalAddr func(t *Thread) Value;
// Execute this expression as a statement. Only expressions
// that are valid expression statements should set this.
exec func(f *Frame);
exec func(t *Thread);
// If this expression is a type, this is its compiled type.
// This is only permitted in the function position of a call
......@@ -126,12 +126,12 @@ func (a *expr) convertTo(t Type) *expr {
n, d := rat.Value();
f := n.Quo(bignum.MakeInt(false, d));
v := f.Abs().Value();
res.eval = func(*Frame) uint64 { return v };
res.eval = func(*Thread) uint64 { return v };
case *intType:
n, d := rat.Value();
f := n.Quo(bignum.MakeInt(false, d));
v := f.Value();
res.eval = func(*Frame) int64 { return v };
res.eval = func(*Thread) int64 { return v };
case *idealIntType:
n, d := rat.Value();
f := n.Quo(bignum.MakeInt(false, d));
......@@ -139,7 +139,7 @@ func (a *expr) convertTo(t Type) *expr {
case *floatType:
n, d := rat.Value();
v := float64(n.Value())/float64(d.Value());
res.eval = func(*Frame) float64 { return v };
res.eval = func(*Thread) float64 { return v };
case *idealFloatType:
res.eval = func() *bignum.Rational { return rat };
default:
......@@ -172,8 +172,8 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr {
// Convert to int
na := a.newExpr(IntType, a.desc);
af := a.asUint();
na.eval = func(f *Frame) int64 {
return int64(af(f));
na.eval = func(t *Thread) int64 {
return int64(af(t));
};
return na;
......@@ -302,7 +302,7 @@ func (a *assignCompiler) allowMapForms(nls int) {
// a function that expects an l-value and the frame in which to
// evaluate the RHS expressions. The l-value must have exactly the
// type given by lt. Returns nil if type checking fails.
func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {
lmt, isMT := lt.(*MultiType);
rmt, isUnpack := a.rmt, a.isUnpack;
......@@ -333,7 +333,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
// multi-value and replace the RHS with expressions to pull
// out values from the temporary. Technically, this is only
// necessary when we need to perform assignment conversions.
var effect func(f *Frame);
var effect func(*Thread);
if isUnpack {
// This leaks a slot, but is definitely safe.
temp := b.DefineSlot(a.rmt);
......@@ -341,20 +341,20 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
if a.isMapUnpack {
rf := a.rs[0].evalMapValue;
vt := a.rmt.Elems[0];
effect = func(f *Frame) {
m, k := rf(f);
effect = func(t *Thread) {
m, k := rf(t);
v := m.Elem(k);
found := boolV(true);
if v == nil {
found = boolV(false);
v = vt.Zero();
}
f.Vars[tempIdx] = multiV([]Value {v, &found});
t.f.Vars[tempIdx] = multiV([]Value {v, &found});
};
} else {
rf := a.rs[0].asMulti();
effect = func(f *Frame) {
f.Vars[tempIdx] = multiV(rf(f));
effect = func(t *Thread) {
t.f.Vars[tempIdx] = multiV(rf(t));
};
}
orig := a.rs[0];
......@@ -365,7 +365,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
}
a.rs[i] = orig.newExpr(t, orig.desc);
index := i;
a.rs[i].genValue(func(f *Frame) Value { return f.Vars[tempIdx].(multiV)[index] });
a.rs[i].genValue(func(t *Thread) Value { return t.f.Vars[tempIdx].(multiV)[index] });
}
}
// Now len(a.rs) == len(a.rmt) and we've reduced any unpacking
......@@ -400,8 +400,8 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
rf := a.rs[i].asPtr();
a.rs[i] = a.rs[i].newExpr(lt, a.rs[i].desc);
len := at.Len;
a.rs[i].eval = func(f *Frame) Slice {
return Slice{rf(f).(ArrayValue), len, len};
a.rs[i].eval = func(t *Thread) Slice {
return Slice{rf(t).(ArrayValue), len, len};
};
rt = a.rs[i].t;
}
......@@ -428,17 +428,17 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
return genAssign(lt, a.rs[0]);
}
// Case 2 or 3
as := make([]func(lv Value, f *Frame), len(a.rs));
as := make([]func(lv Value, t *Thread), len(a.rs));
for i, r := range a.rs {
as[i] = genAssign(lmt.Elems[i], r);
}
return func(lv Value, f *Frame) {
return func(lv Value, t *Thread) {
if effect != nil {
effect(f);
effect(t);
}
lmv := lv.(multiV);
for i, a := range as {
a(lmv[i], f);
a(lmv[i], t);
}
};
}
......@@ -446,7 +446,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(lv Value, f *Frame)) {
// compileAssign compiles an assignment operation without the full
// generality of an assignCompiler. See assignCompiler for a
// description of the arguments.
func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*expr, errOp, errPosName string) (func(lv Value, f *Frame)) {
func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*expr, errOp, errPosName string) (func(Value, *Thread)) {
ac, ok := a.checkAssign(pos, rs, errOp, errPosName);
if !ok {
return nil;
......@@ -758,7 +758,7 @@ func (a *exprInfo) compileString(s string) *expr {
// TODO(austin) Use unnamed string type.
expr := a.newExpr(StringType, "string literal");
expr.eval = func(*Frame) string { return s };
expr.eval = func(*Thread) string { return s };
return expr;
}
......@@ -779,7 +779,7 @@ func (a *exprInfo) compileStringList(list []*expr) *expr {
return a.compileString(strings.Join(ss, ""));
}
func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(f *Frame) Func) *expr {
func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(*Thread) Func) *expr {
expr := a.newExpr(decl.Type, "function literal");
expr.eval = fn;
return expr;
......@@ -880,8 +880,8 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
}
expr := a.newExpr(ft, "selector expression");
pf := parent.asStruct();
evalAddr := func(f *Frame) Value {
return pf(f).Field(index);
evalAddr := func(t *Thread) Value {
return pf(t).Field(index);
};
expr.genValue(evalAddr);
return sub(expr);
......@@ -964,10 +964,10 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
lf := l.asArray();
rf := r.asInt();
bound := lt.Len;
expr.genValue(func(f *Frame) Value {
l, r := lf(f), rf(f);
expr.genValue(func(t *Thread) Value {
l, r := lf(t), rf(t);
if r < 0 || r >= bound {
Abort(IndexOutOfBounds{r, bound});
Abort(IndexError{r, bound});
}
return l.Elem(r);
});
......@@ -975,13 +975,13 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
case *SliceType:
lf := l.asSlice();
rf := r.asInt();
expr.genValue(func(f *Frame) Value {
l, r := lf(f), rf(f);
expr.genValue(func(t *Thread) Value {
l, r := lf(t), rf(t);
if l.Base == nil {
Abort(NilPointer{});
Abort(NilPointerError{});
}
if r < 0 || r >= l.Len {
Abort(IndexOutOfBounds{r, l.Len});
Abort(IndexError{r, l.Len});
}
return l.Base.Elem(r);
});
......@@ -991,10 +991,10 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
rf := r.asInt();
// TODO(austin) This pulls over the whole string in a
// remote setting, instead of just the one character.
expr.eval = func(f *Frame) uint64 {
l, r := lf(f), rf(f);
expr.eval = func(t *Thread) uint64 {
l, r := lf(t), rf(t);
if r < 0 || r >= int64(len(l)) {
Abort(IndexOutOfBounds{r, int64(len(l))});
Abort(IndexError{r, int64(len(l))});
}
return uint64(l[r]);
}
......@@ -1002,24 +1002,24 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
case *MapType:
lf := l.asMap();
rf := r.asInterface();
expr.genValue(func(f *Frame) Value {
m := lf(f);
k := rf(f);
expr.genValue(func(t *Thread) Value {
m := lf(t);
k := rf(t);
if m == nil {
Abort(NilPointer{});
Abort(NilPointerError{});
}
e := m.Elem(k);
if e == nil {
Abort(KeyNotFound{k});
Abort(KeyError{k});
}
return e;
});
// genValue makes things addressable, but map values
// aren't addressable.
expr.evalAddr = nil;
expr.evalMapValue = func(f *Frame) (Map, interface{}) {
expr.evalMapValue = func(t *Thread) (Map, interface{}) {
// TODO(austin) Key check? nil check?
return lf(f), rf(f);
return lf(t), rf(t);
};
default:
......@@ -1080,14 +1080,17 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {
// Compile
lf := l.asFunc();
call := func(f *Frame) []Value {
fun := lf(f);
call := func(t *Thread) []Value {
fun := lf(t);
fr := fun.NewFrame();
for i, t := range vts {
fr.Vars[i] = t.Zero();
}
assign(multiV(fr.Vars[0:nin]), f);
fun.Call(fr);
assign(multiV(fr.Vars[0:nin]), t);
oldf := t.f;
t.f = fr;
fun.Call(t);
t.f = oldf;
return fr.Vars[nin:nin+nout];
};
expr.genFuncCall(call);
......@@ -1119,14 +1122,14 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
// TODO(austin) It would be nice if this could
// be a constant int.
v := t.Len;
expr.eval = func(f *Frame) int64 {
expr.eval = func(t *Thread) int64 {
return v;
};
case *SliceType:
vf := arg.asSlice();
expr.eval = func(f *Frame) int64 {
return vf(f).Cap;
expr.eval = func(t *Thread) int64 {
return vf(t).Cap;
};
//case *ChanType:
......@@ -1146,30 +1149,30 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
switch t := arg.t.lit().(type) {
case *stringType:
vf := arg.asString();
expr.eval = func(f *Frame) int64 {
return int64(len(vf(f)));
expr.eval = func(t *Thread) int64 {
return int64(len(vf(t)));
};
case *ArrayType:
// TODO(austin) It would be nice if this could
// be a constant int.
v := t.Len;
expr.eval = func(f *Frame) int64 {
expr.eval = func(t *Thread) int64 {
return v;
};
case *SliceType:
vf := arg.asSlice();
expr.eval = func(f *Frame) int64 {
return vf(f).Len;
expr.eval = func(t *Thread) int64 {
return vf(t).Len;
};
case *MapType:
vf := arg.asMap();
expr.eval = func(f *Frame) int64 {
expr.eval = func(t *Thread) int64 {
// XXX(Spec) What's the len of an
// uninitialized map?
m := vf(f);
m := vf(t);
if m == nil {
return 0;
}
......@@ -1192,7 +1195,7 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
// arguments? Do they have to be ints? 6g
// accepts any integral type.
var lenexpr, capexpr *expr;
var lenf, capf func(f *Frame) int64;
var lenf, capf func(*Thread) int64;
if len(as) > 1 {
lenexpr = as[1].convertToInt(-1, "length", "make function");
if lenexpr == nil {
......@@ -1220,18 +1223,18 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
}
et := t.Elem;
expr := a.newExpr(t, "function call");
expr.eval = func(f *Frame) Slice {
l := lenf(f);
expr.eval = func(t *Thread) Slice {
l := lenf(t);
// XXX(Spec) What if len or cap is
// negative? The runtime panics.
if l < 0 {
Abort(NegativeLength{l});
Abort(NegativeLengthError{l});
}
c := l;
if capf != nil {
c = capf(f);
c = capf(t);
if c < 0 {
Abort(NegativeCapacity{c});
Abort(NegativeCapacityError{c});
}
// XXX(Spec) What happens if
// len > cap? The runtime
......@@ -1257,11 +1260,11 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e
return nil;
}
expr := a.newExpr(t, "function call");
expr.eval = func(f *Frame) Map {
expr.eval = func(t *Thread) Map {
if lenf == nil {
return make(evalMap);
}
l := lenf(f);
l := lenf(t);
return make(evalMap, l);
};
return expr;
......@@ -1287,10 +1290,10 @@ func (a *exprInfo) compileStarExpr(v *expr) *expr {
case *PtrType:
expr := a.newExpr(vt.Elem, "indirect expression");
vf := v.asPtr();
expr.genValue(func(f *Frame) Value {
v := vf(f);
expr.genValue(func(t *Thread) Value {
v := vf(t);
if v == nil {
Abort(NilPointer{});
Abort(NilPointerError{});
}
return v;
});
......@@ -1376,7 +1379,7 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {
case token.AND:
vf := v.evalAddr;
expr.eval = func(f *Frame) Value { return vf(f) };
expr.eval = func(t *Thread) Value { return vf(t) };
default:
log.Crashf("Compilation of unary op %v not implemented", op);
......@@ -1781,7 +1784,7 @@ func (a *compiler) compileExpr(b *block, constant bool, expr ast.Expr) *expr {
// temporary variable, the caller should create a temporary block for
// the compilation of this expression and the evaluation of the
// results.
func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) {
func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) {
// Create "&a" if a is addressable
rhs := a;
if a.evalAddr != nil {
......@@ -1818,10 +1821,10 @@ func (a *expr) extractEffect(b *block, errOp string) (func(f *Frame), *expr) {
log.Crashf("compileAssign type check failed");
}
effect := func(f *Frame) {
effect := func(t *Thread) {
tempVal := tempType.Zero();
f.Vars[tempIdx] = tempVal;
assign(tempVal, f);
t.f.Vars[tempIdx] = tempVal;
assign(tempVal, t);
};
// Generate "temp" or "*temp"
......@@ -1850,6 +1853,8 @@ func (expr *Expr) Type() Type {
}
func (expr *Expr) Eval(f *Frame) (Value, os.Error) {
t := new(Thread);
t.f = f;
switch _ := expr.e.t.(type) {
case *idealIntType:
return &idealIntV{expr.e.asIdealInt()()}, nil;
......@@ -1858,7 +1863,7 @@ func (expr *Expr) Eval(f *Frame) (Value, os.Error) {
}
v := expr.e.t.Zero();
eval := genAssign(expr.e.t, expr.e);
err := Try(func() {eval(v, f)});
err := Try(func() {eval(v, t)});
return v, err;
}
......
// This file is machine generated by gen.go.
// 6g gen.go && 6l gen.6 && 6.out >expr1.go
// 6g gen.go && 6l gen.6 && ./6.out >expr1.go
package eval
......@@ -13,77 +13,77 @@ import (
* "As" functions. These retrieve evaluator functions from an
* expr, panicking if the requested evaluator has the wrong type.
*/
func (a *expr) asBool() (func(*Frame) bool) {
return a.eval.(func(*Frame)(bool))
func (a *expr) asBool() (func(*Thread) bool) {
return a.eval.(func(*Thread)(bool))
}
func (a *expr) asUint() (func(*Frame) uint64) {
return a.eval.(func(*Frame)(uint64))
func (a *expr) asUint() (func(*Thread) uint64) {
return a.eval.(func(*Thread)(uint64))
}
func (a *expr) asInt() (func(*Frame) int64) {
return a.eval.(func(*Frame)(int64))
func (a *expr) asInt() (func(*Thread) int64) {
return a.eval.(func(*Thread)(int64))
}
func (a *expr) asIdealInt() (func() *bignum.Integer) {
return a.eval.(func()(*bignum.Integer))
}
func (a *expr) asFloat() (func(*Frame) float64) {
return a.eval.(func(*Frame)(float64))
func (a *expr) asFloat() (func(*Thread) float64) {
return a.eval.(func(*Thread)(float64))
}
func (a *expr) asIdealFloat() (func() *bignum.Rational) {
return a.eval.(func()(*bignum.Rational))
}
func (a *expr) asString() (func(*Frame) string) {
return a.eval.(func(*Frame)(string))
func (a *expr) asString() (func(*Thread) string) {
return a.eval.(func(*Thread)(string))
}
func (a *expr) asArray() (func(*Frame) ArrayValue) {
return a.eval.(func(*Frame)(ArrayValue))
func (a *expr) asArray() (func(*Thread) ArrayValue) {
return a.eval.(func(*Thread)(ArrayValue))
}
func (a *expr) asStruct() (func(*Frame) StructValue) {
return a.eval.(func(*Frame)(StructValue))
func (a *expr) asStruct() (func(*Thread) StructValue) {
return a.eval.(func(*Thread)(StructValue))
}
func (a *expr) asPtr() (func(*Frame) Value) {
return a.eval.(func(*Frame)(Value))
func (a *expr) asPtr() (func(*Thread) Value) {
return a.eval.(func(*Thread)(Value))
}
func (a *expr) asFunc() (func(*Frame) Func) {
return a.eval.(func(*Frame)(Func))
func (a *expr) asFunc() (func(*Thread) Func) {
return a.eval.(func(*Thread)(Func))
}
func (a *expr) asSlice() (func(*Frame) Slice) {
return a.eval.(func(*Frame)(Slice))
func (a *expr) asSlice() (func(*Thread) Slice) {
return a.eval.(func(*Thread)(Slice))
}
func (a *expr) asMap() (func(*Frame) Map) {
return a.eval.(func(*Frame)(Map))
func (a *expr) asMap() (func(*Thread) Map) {
return a.eval.(func(*Thread)(Map))
}
func (a *expr) asMulti() (func(*Frame) []Value) {
return a.eval.(func(*Frame)[]Value)
func (a *expr) asMulti() (func(*Thread) []Value) {
return a.eval.(func(*Thread)[]Value)
}
func (a *expr) asInterface() (func(*Frame) interface{}) {
func (a *expr) asInterface() (func(*Thread) interface{}) {
switch sf := a.eval.(type) {
case func(*Frame)bool:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)uint64:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)int64:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)*bignum.Integer:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)float64:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)*bignum.Rational:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)string:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)ArrayValue:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)StructValue:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)Value:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)Func:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)Slice:
return func(f *Frame) interface{} { return sf(f) }
case func(*Frame)Map:
return func(f *Frame) interface{} { return sf(f) }
case func(*Thread)bool:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)uint64:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)int64:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)*bignum.Integer:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)float64:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)*bignum.Rational:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)string:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)ArrayValue:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)StructValue:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)Value:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)Func:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)Slice:
return func(t *Thread) interface{} { return sf(t) }
case func(*Thread)Map:
return func(t *Thread) interface{} { return sf(t) }
default:
log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos);
}
......@@ -98,135 +98,135 @@ func (a *expr) genConstant(v Value) {
switch _ := a.t.lit().(type) {
case *boolType:
val := v.(BoolValue).Get();
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *uintType:
val := v.(UintValue).Get();
a.eval = func(f *Frame) uint64 { return val }
a.eval = func(t *Thread) uint64 { return val }
case *intType:
val := v.(IntValue).Get();
a.eval = func(f *Frame) int64 { return val }
a.eval = func(t *Thread) int64 { return val }
case *idealIntType:
val := v.(IdealIntValue).Get();
a.eval = func() *bignum.Integer { return val }
case *floatType:
val := v.(FloatValue).Get();
a.eval = func(f *Frame) float64 { return val }
a.eval = func(t *Thread) float64 { return val }
case *idealFloatType:
val := v.(IdealFloatValue).Get();
a.eval = func() *bignum.Rational { return val }
case *stringType:
val := v.(StringValue).Get();
a.eval = func(f *Frame) string { return val }
a.eval = func(t *Thread) string { return val }
case *ArrayType:
val := v.(ArrayValue).Get();
a.eval = func(f *Frame) ArrayValue { return val }
a.eval = func(t *Thread) ArrayValue { return val }
case *StructType:
val := v.(StructValue).Get();
a.eval = func(f *Frame) StructValue { return val }
a.eval = func(t *Thread) StructValue { return val }
case *PtrType:
val := v.(PtrValue).Get();
a.eval = func(f *Frame) Value { return val }
a.eval = func(t *Thread) Value { return val }
case *FuncType:
val := v.(FuncValue).Get();
a.eval = func(f *Frame) Func { return val }
a.eval = func(t *Thread) Func { return val }
case *SliceType:
val := v.(SliceValue).Get();
a.eval = func(f *Frame) Slice { return val }
a.eval = func(t *Thread) Slice { return val }
case *MapType:
val := v.(MapValue).Get();
a.eval = func(f *Frame) Map { return val }
a.eval = func(t *Thread) Map { return val }
default:
log.Crashf("unexpected constant type %v at %v", a.t, a.pos);
}
}
func (a *expr) genIdentOp(level, index int) {
a.evalAddr = func(f *Frame) Value { return f.Get(level, index) };
a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) };
switch _ := a.t.lit().(type) {
case *boolType:
a.eval = func(f *Frame) bool { return f.Get(level, index).(BoolValue).Get() }
a.eval = func(t *Thread) bool { return t.f.Get(level, index).(BoolValue).Get() }
case *uintType:
a.eval = func(f *Frame) uint64 { return f.Get(level, index).(UintValue).Get() }
a.eval = func(t *Thread) uint64 { return t.f.Get(level, index).(UintValue).Get() }
case *intType:
a.eval = func(f *Frame) int64 { return f.Get(level, index).(IntValue).Get() }
a.eval = func(t *Thread) int64 { return t.f.Get(level, index).(IntValue).Get() }
case *floatType:
a.eval = func(f *Frame) float64 { return f.Get(level, index).(FloatValue).Get() }
a.eval = func(t *Thread) float64 { return t.f.Get(level, index).(FloatValue).Get() }
case *stringType:
a.eval = func(f *Frame) string { return f.Get(level, index).(StringValue).Get() }
a.eval = func(t *Thread) string { return t.f.Get(level, index).(StringValue).Get() }
case *ArrayType:
a.eval = func(f *Frame) ArrayValue { return f.Get(level, index).(ArrayValue).Get() }
a.eval = func(t *Thread) ArrayValue { return t.f.Get(level, index).(ArrayValue).Get() }
case *StructType:
a.eval = func(f *Frame) StructValue { return f.Get(level, index).(StructValue).Get() }
a.eval = func(t *Thread) StructValue { return t.f.Get(level, index).(StructValue).Get() }
case *PtrType:
a.eval = func(f *Frame) Value { return f.Get(level, index).(PtrValue).Get() }
a.eval = func(t *Thread) Value { return t.f.Get(level, index).(PtrValue).Get() }
case *FuncType:
a.eval = func(f *Frame) Func { return f.Get(level, index).(FuncValue).Get() }
a.eval = func(t *Thread) Func { return t.f.Get(level, index).(FuncValue).Get() }
case *SliceType:
a.eval = func(f *Frame) Slice { return f.Get(level, index).(SliceValue).Get() }
a.eval = func(t *Thread) Slice { return t.f.Get(level, index).(SliceValue).Get() }
case *MapType:
a.eval = func(f *Frame) Map { return f.Get(level, index).(MapValue).Get() }
a.eval = func(t *Thread) Map { return t.f.Get(level, index).(MapValue).Get() }
default:
log.Crashf("unexpected identifier type %v at %v", a.t, a.pos);
}
}
func (a *expr) genFuncCall(call func(f *Frame) []Value) {
a.exec = func(f *Frame) { call(f)};
func (a *expr) genFuncCall(call func(t *Thread) []Value) {
a.exec = func(t *Thread) { call(t)};
switch _ := a.t.lit().(type) {
case *boolType:
a.eval = func(f *Frame) bool { return call(f)[0].(BoolValue).Get() }
a.eval = func(t *Thread) bool { return call(t)[0].(BoolValue).Get() }
case *uintType:
a.eval = func(f *Frame) uint64 { return call(f)[0].(UintValue).Get() }
a.eval = func(t *Thread) uint64 { return call(t)[0].(UintValue).Get() }
case *intType:
a.eval = func(f *Frame) int64 { return call(f)[0].(IntValue).Get() }
a.eval = func(t *Thread) int64 { return call(t)[0].(IntValue).Get() }
case *floatType:
a.eval = func(f *Frame) float64 { return call(f)[0].(FloatValue).Get() }
a.eval = func(t *Thread) float64 { return call(t)[0].(FloatValue).Get() }
case *stringType:
a.eval = func(f *Frame) string { return call(f)[0].(StringValue).Get() }
a.eval = func(t *Thread) string { return call(t)[0].(StringValue).Get() }
case *ArrayType:
a.eval = func(f *Frame) ArrayValue { return call(f)[0].(ArrayValue).Get() }
a.eval = func(t *Thread) ArrayValue { return call(t)[0].(ArrayValue).Get() }
case *StructType:
a.eval = func(f *Frame) StructValue { return call(f)[0].(StructValue).Get() }
a.eval = func(t *Thread) StructValue { return call(t)[0].(StructValue).Get() }
case *PtrType:
a.eval = func(f *Frame) Value { return call(f)[0].(PtrValue).Get() }
a.eval = func(t *Thread) Value { return call(t)[0].(PtrValue).Get() }
case *FuncType:
a.eval = func(f *Frame) Func { return call(f)[0].(FuncValue).Get() }
a.eval = func(t *Thread) Func { return call(t)[0].(FuncValue).Get() }
case *SliceType:
a.eval = func(f *Frame) Slice { return call(f)[0].(SliceValue).Get() }
a.eval = func(t *Thread) Slice { return call(t)[0].(SliceValue).Get() }
case *MapType:
a.eval = func(f *Frame) Map { return call(f)[0].(MapValue).Get() }
a.eval = func(t *Thread) Map { return call(t)[0].(MapValue).Get() }
case *MultiType:
a.eval = func(f *Frame) []Value { return call(f) }
a.eval = func(t *Thread) []Value { return call(t) }
default:
log.Crashf("unexpected result type %v at %v", a.t, a.pos);
}
}
func (a *expr) genValue(vf func(*Frame) Value) {
func (a *expr) genValue(vf func(*Thread) Value) {
a.evalAddr = vf;
switch _ := a.t.lit().(type) {
case *boolType:
a.eval = func(f *Frame) bool { return vf(f).(BoolValue).Get() }
a.eval = func(t *Thread) bool { return vf(t).(BoolValue).Get() }
case *uintType:
a.eval = func(f *Frame) uint64 { return vf(f).(UintValue).Get() }
a.eval = func(t *Thread) uint64 { return vf(t).(UintValue).Get() }
case *intType:
a.eval = func(f *Frame) int64 { return vf(f).(IntValue).Get() }
a.eval = func(t *Thread) int64 { return vf(t).(IntValue).Get() }
case *floatType:
a.eval = func(f *Frame) float64 { return vf(f).(FloatValue).Get() }
a.eval = func(t *Thread) float64 { return vf(t).(FloatValue).Get() }
case *stringType:
a.eval = func(f *Frame) string { return vf(f).(StringValue).Get() }
a.eval = func(t *Thread) string { return vf(t).(StringValue).Get() }
case *ArrayType:
a.eval = func(f *Frame) ArrayValue { return vf(f).(ArrayValue).Get() }
a.eval = func(t *Thread) ArrayValue { return vf(t).(ArrayValue).Get() }
case *StructType:
a.eval = func(f *Frame) StructValue { return vf(f).(StructValue).Get() }
a.eval = func(t *Thread) StructValue { return vf(t).(StructValue).Get() }
case *PtrType:
a.eval = func(f *Frame) Value { return vf(f).(PtrValue).Get() }
a.eval = func(t *Thread) Value { return vf(t).(PtrValue).Get() }
case *FuncType:
a.eval = func(f *Frame) Func { return vf(f).(FuncValue).Get() }
a.eval = func(t *Thread) Func { return vf(t).(FuncValue).Get() }
case *SliceType:
a.eval = func(f *Frame) Slice { return vf(f).(SliceValue).Get() }
a.eval = func(t *Thread) Slice { return vf(t).(SliceValue).Get() }
case *MapType:
a.eval = func(f *Frame) Map { return vf(f).(MapValue).Get() }
a.eval = func(t *Thread) Map { return vf(t).(MapValue).Get() }
default:
log.Crashf("unexpected result type %v at %v", a.t, a.pos);
}
......@@ -236,17 +236,17 @@ func (a *expr) genUnaryOpNeg(v *expr) {
switch _ := a.t.lit().(type) {
case *uintType:
vf := v.asUint();
a.eval = func(f *Frame) uint64 { v := vf(f); return -v }
a.eval = func(t *Thread) uint64 { v := vf(t); return -v }
case *intType:
vf := v.asInt();
a.eval = func(f *Frame) int64 { v := vf(f); return -v }
a.eval = func(t *Thread) int64 { v := vf(t); return -v }
case *idealIntType:
v := v.asIdealInt()();
val := v.Neg();
a.eval = func() *bignum.Integer { return val }
case *floatType:
vf := v.asFloat();
a.eval = func(f *Frame) float64 { v := vf(f); return -v }
a.eval = func(t *Thread) float64 { v := vf(t); return -v }
case *idealFloatType:
v := v.asIdealFloat()();
val := v.Neg();
......@@ -260,7 +260,7 @@ func (a *expr) genUnaryOpNot(v *expr) {
switch _ := a.t.lit().(type) {
case *boolType:
vf := v.asBool();
a.eval = func(f *Frame) bool { v := vf(f); return !v }
a.eval = func(t *Thread) bool { v := vf(t); return !v }
default:
log.Crashf("unexpected type %v at %v", a.t, a.pos);
}
......@@ -270,10 +270,10 @@ func (a *expr) genUnaryOpXor(v *expr) {
switch _ := a.t.lit().(type) {
case *uintType:
vf := v.asUint();
a.eval = func(f *Frame) uint64 { v := vf(f); return ^v }
a.eval = func(t *Thread) uint64 { v := vf(t); return ^v }
case *intType:
vf := v.asInt();
a.eval = func(f *Frame) int64 { v := vf(f); return ^v }
a.eval = func(t *Thread) int64 { v := vf(t); return ^v }
case *idealIntType:
v := v.asIdealInt()();
val := v.Neg().Sub(bignum.Int(1));
......@@ -288,11 +288,11 @@ func (a *expr) genBinOpAdd(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l + r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l + r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l + r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l + r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -301,7 +301,7 @@ func (a *expr) genBinOpAdd(l, r *expr) {
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l + r }
a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l + r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
......@@ -310,7 +310,7 @@ func (a *expr) genBinOpAdd(l, r *expr) {
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) string { l, r := lf(f), rf(f); return l + r }
a.eval = func(t *Thread) string { l, r := lf(t), rf(t); return l + r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -321,11 +321,11 @@ func (a *expr) genBinOpSub(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l - r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l - r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l - r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l - r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -334,7 +334,7 @@ func (a *expr) genBinOpSub(l, r *expr) {
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l - r }
a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l - r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
......@@ -350,11 +350,11 @@ func (a *expr) genBinOpMul(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l * r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l * r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l * r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l * r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -363,7 +363,7 @@ func (a *expr) genBinOpMul(l, r *expr) {
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l * r }
a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); return l * r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
......@@ -379,11 +379,11 @@ func (a *expr) genBinOpQuo(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -392,7 +392,7 @@ func (a *expr) genBinOpQuo(l, r *expr) {
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r }
a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l / r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
......@@ -408,11 +408,11 @@ func (a *expr) genBinOpRem(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l % r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l % r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l % r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); if r == 0 { Abort(DivByZeroError{}) } return l % r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -428,11 +428,11 @@ func (a *expr) genBinOpAnd(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l & r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l & r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l & r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l & r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -448,11 +448,11 @@ func (a *expr) genBinOpOr(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l | r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l | r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l | r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l | r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -468,11 +468,11 @@ func (a *expr) genBinOpXor(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l ^ r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l ^ r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l ^ r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l ^ r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -488,11 +488,11 @@ func (a *expr) genBinOpAndNot(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l &^ r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l &^ r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l &^ r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l &^ r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
......@@ -508,11 +508,11 @@ func (a *expr) genBinOpShl(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l << r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l << r }
case *intType:
lf := l.asInt();
rf := r.asUint();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l << r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l << r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -523,11 +523,11 @@ func (a *expr) genBinOpShr(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l >> r }
a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); return l >> r }
case *intType:
lf := l.asInt();
rf := r.asUint();
a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l >> r }
a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); return l >> r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -538,29 +538,29 @@ func (a *expr) genBinOpLss(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) < 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) < 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -571,29 +571,29 @@ func (a *expr) genBinOpGtr(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) > 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) > 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -604,29 +604,29 @@ func (a *expr) genBinOpLeq(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) <= 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) <= 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -637,29 +637,29 @@ func (a *expr) genBinOpGeq(l, r *expr) {
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) >= 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) >= 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -670,45 +670,45 @@ func (a *expr) genBinOpEql(l, r *expr) {
case *boolType:
lf := l.asBool();
rf := r.asBool();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) == 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) == 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *PtrType:
lf := l.asPtr();
rf := r.asPtr();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *FuncType:
lf := l.asFunc();
rf := r.asFunc();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
case *MapType:
lf := l.asMap();
rf := r.asMap();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
......@@ -719,85 +719,85 @@ func (a *expr) genBinOpNeq(l, r *expr) {
case *boolType:
lf := l.asBool();
rf := r.asBool();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *uintType:
lf := l.asUint();
rf := r.asUint();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *intType:
lf := l.asInt();
rf := r.asInt();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *idealIntType:
l := l.asIdealInt()();
r := r.asIdealInt()();
val := l.Cmp(r) != 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *floatType:
lf := l.asFloat();
rf := r.asFloat();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *idealFloatType:
l := l.asIdealFloat()();
r := r.asIdealFloat()();
val := l.Cmp(r) != 0;
a.eval = func(f *Frame) bool { return val }
a.eval = func(t *Thread) bool { return val }
case *stringType:
lf := l.asString();
rf := r.asString();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *PtrType:
lf := l.asPtr();
rf := r.asPtr();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *FuncType:
lf := l.asFunc();
rf := r.asFunc();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
case *MapType:
lf := l.asMap();
rf := r.asMap();
a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r }
a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r }
default:
log.Crashf("unexpected type %v at %v", l.t, a.pos);
}
}
func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) {
func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) {
switch _ := lt.lit().(type) {
case *boolType:
rf := r.asBool();
return func(lv Value, f *Frame) { lv.(BoolValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(BoolValue).Set(rf(t)) }
case *uintType:
rf := r.asUint();
return func(lv Value, f *Frame) { lv.(UintValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(UintValue).Set(rf(t)) }
case *intType:
rf := r.asInt();
return func(lv Value, f *Frame) { lv.(IntValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(IntValue).Set(rf(t)) }
case *floatType:
rf := r.asFloat();
return func(lv Value, f *Frame) { lv.(FloatValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(FloatValue).Set(rf(t)) }
case *stringType:
rf := r.asString();
return func(lv Value, f *Frame) { lv.(StringValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(StringValue).Set(rf(t)) }
case *ArrayType:
rf := r.asArray();
return func(lv Value, f *Frame) { lv.Assign(rf(f)) }
return func(lv Value, t *Thread) { lv.Assign(rf(t)) }
case *StructType:
rf := r.asStruct();
return func(lv Value, f *Frame) { lv.Assign(rf(f)) }
return func(lv Value, t *Thread) { lv.Assign(rf(t)) }
case *PtrType:
rf := r.asPtr();
return func(lv Value, f *Frame) { lv.(PtrValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(PtrValue).Set(rf(t)) }
case *FuncType:
rf := r.asFunc();
return func(lv Value, f *Frame) { lv.(FuncValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(FuncValue).Set(rf(t)) }
case *SliceType:
rf := r.asSlice();
return func(lv Value, f *Frame) { lv.(SliceValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(SliceValue).Set(rf(t)) }
case *MapType:
rf := r.asMap();
return func(lv Value, f *Frame) { lv.(MapValue).Set(rf(f)) }
return func(lv Value, t *Thread) { lv.(MapValue).Set(rf(t)) }
default:
log.Crashf("unexpected left operand type %v at %v", lt, r.pos);
}
......
......@@ -8,18 +8,17 @@ package eval
* Virtual machine
*/
type vm struct {
type Thread struct {
pc uint;
// The execution frame of this function. This remains the
// same throughout a function invocation.
f *Frame;
}
type code []func(*vm)
func (i code) exec(fr *Frame) {
v := vm{0, fr};
type code []func(*Thread)
func (i code) exec(t *Thread) {
v := Thread{0, t.f}; // TODO: reuse t
l := uint(len(i));
for v.pc < l {
pc := v.pc;
......@@ -40,7 +39,7 @@ func newCodeBuf() *codeBuf {
return &codeBuf{make(code, 0, 16)};
}
func (b *codeBuf) push(instr func(*vm)) {
func (b *codeBuf) push(instr func(*Thread)) {
n := len(b.instrs);
if n >= cap(b.instrs) {
a := make(code, n, n*2);
......@@ -80,6 +79,6 @@ func (f *evalFunc) NewFrame() *Frame {
return f.outer.child(f.frameSize);
}
func (f *evalFunc) Call(fr *Frame) {
f.code.exec(fr);
func (f *evalFunc) Call(t *Thread) {
f.code.exec(t);
}
......@@ -91,12 +91,12 @@ var binOps = []Op{
Op{ Name: "Sub", Expr: "l - r", ConstExpr: "l.Sub(r)", Types: numbers },
Op{ Name: "Mul", Expr: "l * r", ConstExpr: "l.Mul(r)", Types: numbers },
Op{ Name: "Quo",
Body: "if r == 0 { Abort(DivByZero{}) } return l / r",
Body: "if r == 0 { Abort(DivByZeroError{}) } return l / r",
ConstExpr: "l.Quo(r)",
Types: numbers,
},
Op{ Name: "Rem",
Body: "if r == 0 { Abort(DivByZero{}) } return l % r",
Body: "if r == 0 { Abort(DivByZeroError{}) } return l % r",
ConstExpr: "l.Rem(r)",
Types: integers,
},
......@@ -151,23 +151,23 @@ func (a *expr) «As»() (func() «Native») {
return a.eval.(func()(«Native»))
}
«.or»
func (a *expr) «As»() (func(*Frame) «Native») {
return a.eval.(func(*Frame)(«Native»))
func (a *expr) «As»() (func(*Thread) «Native») {
return a.eval.(func(*Thread)(«Native»))
}
«.end»
«.end»
func (a *expr) asMulti() (func(*Frame) []Value) {
return a.eval.(func(*Frame)[]Value)
func (a *expr) asMulti() (func(*Thread) []Value) {
return a.eval.(func(*Thread)[]Value)
}
func (a *expr) asInterface() (func(*Frame) interface{}) {
func (a *expr) asInterface() (func(*Thread) interface{}) {
switch sf := a.eval.(type) {
«.repeated section Types»
case func(*Frame)«Native»:
case func(*Thread)«Native»:
«.section IsIdeal»
return func(f *Frame) interface{} { return sf(f) }
return func(t *Thread) interface{} { return sf(t) }
«.or»
return func(f *Frame) interface{} { return sf(f) }
return func(t *Thread) interface{} { return sf(t) }
«.end»
«.end»
default:
......@@ -188,7 +188,7 @@ func (a *expr) genConstant(v Value) {
«.section IsIdeal»
a.eval = func() «Native» { return val }
«.or»
a.eval = func(f *Frame) «Native» { return val }
a.eval = func(t *Thread) «Native» { return val }
«.end»
«.end»
default:
......@@ -197,13 +197,13 @@ func (a *expr) genConstant(v Value) {
}
func (a *expr) genIdentOp(level, index int) {
a.evalAddr = func(f *Frame) Value { return f.Get(level, index) };
a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) };
switch _ := a.t.lit().(type) {
«.repeated section Types»
«.section IsIdeal»
«.or»
case «Repr»:
a.eval = func(f *Frame) «Native» { return f.Get(level, index).(«Value»).Get() }
a.eval = func(t *Thread) «Native» { return t.f.Get(level, index).(«Value»).Get() }
«.end»
«.end»
default:
......@@ -211,31 +211,31 @@ func (a *expr) genIdentOp(level, index int) {
}
}
func (a *expr) genFuncCall(call func(f *Frame) []Value) {
a.exec = func(f *Frame) { call(f)};
func (a *expr) genFuncCall(call func(t *Thread) []Value) {
a.exec = func(t *Thread) { call(t)};
switch _ := a.t.lit().(type) {
«.repeated section Types»
«.section IsIdeal»
«.or»
case «Repr»:
a.eval = func(f *Frame) «Native» { return call(f)[0].(«Value»).Get() }
a.eval = func(t *Thread) «Native» { return call(t)[0].(«Value»).Get() }
«.end»
«.end»
case *MultiType:
a.eval = func(f *Frame) []Value { return call(f) }
a.eval = func(t *Thread) []Value { return call(t) }
default:
log.Crashf("unexpected result type %v at %v", a.t, a.pos);
}
}
func (a *expr) genValue(vf func(*Frame) Value) {
func (a *expr) genValue(vf func(*Thread) Value) {
a.evalAddr = vf;
switch _ := a.t.lit().(type) {
«.repeated section Types»
«.section IsIdeal»
«.or»
case «Repr»:
a.eval = func(f *Frame) «Native» { return vf(f).(«Value»).Get() }
a.eval = func(t *Thread) «Native» { return vf(t).(«Value»).Get() }
«.end»
«.end»
default:
......@@ -254,7 +254,7 @@ func (a *expr) genUnaryOp«Name»(v *expr) {
a.eval = func() «Native» { return val }
«.or»
vf := v.«As»();
a.eval = func(f *Frame) «Native» { v := vf(f); return «Expr» }
a.eval = func(t *Thread) «Native» { v := vf(t); return «Expr» }
«.end»
«.end»
default:
......@@ -273,14 +273,14 @@ func (a *expr) genBinOp«Name»(l, r *expr) {
r := r.«As»()();
val := «ConstExpr»;
«.section ReturnType»
a.eval = func(f *Frame) «ReturnType» { return val }
a.eval = func(t *Thread) «ReturnType» { return val }
«.or»
a.eval = func() «Native» { return val }
«.end»
«.or»
lf := l.«As»();
rf := r.«.section AsRightName»«@»«.or»«As»«.end»();
a.eval = func(f *Frame) «.section ReturnType»«@»«.or»«Native»«.end» { l, r := lf(f), rf(f); «.section Body»«Body»«.or»return «Expr»«.end» }
a.eval = func(t *Thread) «.section ReturnType»«@»«.or»«Native»«.end» { l, r := lf(t), rf(t); «.section Body»«Body»«.or»return «Expr»«.end» }
«.end»
«.end»
default:
......@@ -289,14 +289,14 @@ func (a *expr) genBinOp«Name»(l, r *expr) {
}
«.end»
func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) {
func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) {
switch _ := lt.lit().(type) {
«.repeated section Types»
«.section IsIdeal»
«.or»
case «Repr»:
rf := r.«As»();
return func(lv Value, f *Frame) { «.section HasAssign»lv.Assign(rf(f))«.or»lv.(«Value»).Set(rf(f))«.end» }
return func(lv Value, t *Thread) { «.section HasAssign»lv.Assign(rf(t))«.or»lv.(«Value»).Set(rf(t))«.end» }
«.end»
«.end»
default:
......
......@@ -230,7 +230,7 @@ func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable {
// Initialize the variable
index := v.Index;
a.push(func(v *vm) {
a.push(func(v *Thread) {
v.f.Vars[index] = t.Zero();
});
return v;
......@@ -416,10 +416,7 @@ func (a *stmtCompiler) compileExprStmt(s *ast.ExprStmt) {
return;
}
exec := e.exec;
a.push(func(v *vm) {
exec(v.f);
});
a.push(e.exec);
}
func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) {
......@@ -471,9 +468,9 @@ func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) {
}
lf := l.evalAddr;
a.push(func(v *vm) {
effect(v.f);
assign(lf(v.f), v.f);
a.push(func(v *Thread) {
effect(v);
assign(lf(v), v);
});
}
......@@ -605,8 +602,8 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token,
ls[i].evalMapValue = sub.evalMapValue;
mvf := sub.evalMapValue;
et := sub.t;
ls[i].evalAddr = func(f *Frame) Value {
m, k := mvf(f);
ls[i].evalAddr = func(t *Thread) Value {
m, k := mvf(t);
e := m.Elem(k);
if e == nil {
e = et.Zero();
......@@ -666,35 +663,35 @@ func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token,
if n == 1 {
// Don't need temporaries and can avoid []Value.
lf := ls[0].evalAddr;
a.push(func(v *vm) { assign(lf(v.f), v.f) });
a.push(func(t *Thread) { assign(lf(t), t) });
} else if tok == token.VAR || (tok == token.DEFINE && nDefs == n) {
// Don't need temporaries
lfs := make([]func(*Frame) Value, n);
lfs := make([]func(*Thread) Value, n);
for i, l := range ls {
lfs[i] = l.evalAddr;
}
a.push(func(v *vm) {
a.push(func(t *Thread) {
dest := make([]Value, n);
for i, lf := range lfs {
dest[i] = lf(v.f);
dest[i] = lf(t);
}
assign(multiV(dest), v.f);
assign(multiV(dest), t);
});
} else {
// Need temporaries
lmt := lt.(*MultiType);
lfs := make([]func(*Frame) Value, n);
lfs := make([]func(*Thread) Value, n);
for i, l := range ls {
lfs[i] = l.evalAddr;
}
a.push(func(v *vm) {
a.push(func(t *Thread) {
temp := lmt.Zero().(multiV);
assign(temp, v.f);
assign(temp, t);
// Copy to destination
for i := 0; i < n; i ++ {
// TODO(austin) Need to evaluate LHS
// before RHS
lfs[i](v.f).Assign(temp[i]);
lfs[i](t).Assign(temp[i]);
}
});
}
......@@ -749,9 +746,9 @@ func (a *stmtCompiler) doAssignOp(s *ast.AssignStmt) {
}
lf := l.evalAddr;
a.push(func(v *vm) {
effect(v.f);
assign(lf(v.f), v.f);
a.push(func(t *Thread) {
effect(t);
assign(lf(t), t);
});
}
......@@ -774,7 +771,7 @@ func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) {
if len(s.Results) == 0 && (len(a.fnType.Out) == 0 || a.outVarsNamed) {
// Simple case. Simply exit from the function.
a.flow.putTerm();
a.push(func(v *vm) { v.pc = returnPC });
a.push(func(v *Thread) { v.pc = returnPC });
return;
}
......@@ -810,9 +807,9 @@ func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) {
start := len(a.fnType.In);
nout := len(a.fnType.Out);
a.flow.putTerm();
a.push(func(v *vm) {
assign(multiV(v.f.Vars[start:start+nout]), v.f);
v.pc = returnPC;
a.push(func(t *Thread) {
assign(multiV(t.f.Vars[start:start+nout]), t);
t.pc = returnPC;
});
}
......@@ -880,7 +877,7 @@ func (a *stmtCompiler) compileBranchStmt(s *ast.BranchStmt) {
}
a.flow.put1(false, pc);
a.push(func(v *vm) { v.pc = *pc });
a.push(func(v *Thread) { v.pc = *pc });
}
func (a *stmtCompiler) compileBlockStmt(s *ast.BlockStmt) {
......@@ -923,9 +920,9 @@ func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) {
default:
eval := e.asBool();
a.flow.put1(true, &elsePC);
a.push(func(v *vm) {
if !eval(v.f) {
v.pc = elsePC;
a.push(func(t *Thread) {
if !eval(t) {
t.pc = elsePC;
}
});
}
......@@ -940,7 +937,7 @@ func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) {
if s.Else != nil {
// Skip over else if we executed the body
a.flow.put1(false, &endPC);
a.push(func(v *vm) {
a.push(func(v *Thread) {
v.pc = endPC;
});
elsePC = a.nextPC();
......@@ -967,9 +964,9 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
if s.Tag != nil {
e := condbc.compileExpr(condbc.block, false, s.Tag);
if e != nil {
var effect func(f *Frame);
var effect func(*Thread);
effect, cond = e.extractEffect(condbc.block, "switch");
a.push(func(v *vm) { effect(v.f) });
a.push(effect);
}
}
......@@ -993,7 +990,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
}
// Compile case expressions
cases := make([]func(f *Frame) bool, ncases);
cases := make([]func(*Thread) bool, ncases);
i := 0;
for _, c := range s.Body.List {
clause, ok := c.(*ast.CaseClause);
......@@ -1026,14 +1023,14 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
endPC := badPC;
a.flow.put(false, false, casePCs);
a.push(func(v *vm) {
a.push(func(t *Thread) {
for i, c := range cases {
if c(v.f) {
v.pc = *casePCs[i];
if c(t) {
t.pc = *casePCs[i];
return;
}
}
v.pc = *casePCs[ncases];
t.pc = *casePCs[ncases];
});
condbc.exit();
......@@ -1083,7 +1080,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
// Jump out of switch, unless there was a fallthrough
if !fall {
a.flow.put1(false, &endPC);
a.push(func(v *vm) { v.pc = endPC });
a.push(func(v *Thread) { v.pc = endPC });
}
}
......@@ -1112,7 +1109,7 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) {
// Jump to condition check. We generate slightly less code by
// placing the condition check after the body.
a.flow.put1(false, &checkPC);
a.push(func(v *vm) { v.pc = checkPC });
a.push(func(v *Thread) { v.pc = checkPC });
// Compile body
bodyPC = a.nextPC();
......@@ -1141,7 +1138,7 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) {
if s.Cond == nil {
// If the condition is absent, it is equivalent to true.
a.flow.put1(false, &bodyPC);
a.push(func(v *vm) { v.pc = bodyPC });
a.push(func(v *Thread) { v.pc = bodyPC });
} else {
e := bc.compileExpr(bc.block, false, s.Cond);
switch {
......@@ -1152,9 +1149,9 @@ func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) {
default:
eval := e.asBool();
a.flow.put1(true, &bodyPC);
a.push(func(v *vm) {
if eval(v.f) {
v.pc = bodyPC;
a.push(func(t *Thread) {
if eval(t) {
t.pc = bodyPC;
}
});
}
......@@ -1195,7 +1192,7 @@ func (a *blockCompiler) exit() {
* Function compiler
*/
func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (f *Frame) Func) {
func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func (*Thread) Func) {
// Create body scope
//
// The scope of a parameter or result is the body of the
......@@ -1250,7 +1247,7 @@ func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (f
code := fc.get();
maxVars := bodyScope.maxVars;
return func(f *Frame) Func { return &evalFunc{f, maxVars, code} };
return func(t *Thread) Func { return &evalFunc{t.f, maxVars, code} };
}
// Checks that labels were resolved and that all jumps obey scoping
......@@ -1282,7 +1279,9 @@ type Stmt struct {
}
func (s *Stmt) Exec(f *Frame) os.Error {
return Try(func() {s.code.exec(f)});
t := new(Thread);
t.f = f;
return Try(func() {s.code.exec(t)});
}
func CompileStmts(scope *Scope, stmts []ast.Stmt) (*Stmt, os.Error) {
......
......@@ -87,7 +87,7 @@ type PtrValue interface {
type Func interface {
NewFrame() *Frame;
Call(*Frame);
Call(*Thread);
}
type FuncValue interface {
......
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