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