diff options
author | Russ Cox <rsc@golang.org> | 2009-09-01 22:57:53 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-09-01 22:57:53 -0700 |
commit | 06165d7a1c0e51120eba2292b90034e15667396b (patch) | |
tree | 11fb1f8467e9ebacb970cebb0bf971c69378c016 | |
parent | d0fa6c11b2ba13b1d88129635ee512e4f687dda1 (diff) | |
download | golang-06165d7a1c0e51120eba2292b90034e15667396b.tar.gz |
add generator for expr1.go
R=austin
DELTA=959 (404 added, 99 deleted, 456 changed)
OCL=34214
CL=34237
-rw-r--r-- | usr/austin/eval/eval_test.go | 2 | ||||
-rw-r--r-- | usr/austin/eval/expr.go | 97 | ||||
-rw-r--r-- | usr/austin/eval/expr1.go | 622 | ||||
-rw-r--r-- | usr/austin/eval/gen.go | 322 | ||||
-rw-r--r-- | usr/austin/eval/stmt.go | 2 | ||||
-rw-r--r-- | usr/austin/eval/stmt_test.go | 2 |
6 files changed, 678 insertions, 369 deletions
diff --git a/usr/austin/eval/eval_test.go b/usr/austin/eval/eval_test.go index 848bf6d19..e8619e137 100644 --- a/usr/austin/eval/eval_test.go +++ b/usr/austin/eval/eval_test.go @@ -17,7 +17,7 @@ import ( ) // Print each statement or expression before parsing it -const noisy = true +const noisy = false /* * Generic statement/expression test framework diff --git a/usr/austin/eval/expr.go b/usr/austin/eval/expr.go index bc8fd57e3..7f959d93d 100644 --- a/usr/austin/eval/expr.go +++ b/usr/austin/eval/expr.go @@ -72,103 +72,6 @@ func (a *exprInfo) diagOpTypes(op token.Token, lt Type, rt Type) { } /* - * "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) asUint() (func(f *Frame) uint64) { - return a.eval.(func(*Frame)uint64); -} - -func (a *expr) asInt() (func(f *Frame) int64) { - return a.eval.(func(*Frame)int64); -} - -func (a *expr) asIdealInt() (func() *bignum.Integer) { - return a.eval.(func()*bignum.Integer); -} - -func (a *expr) asFloat() (func(f *Frame) float64) { - return a.eval.(func(*Frame)float64) -} - -func (a *expr) asIdealFloat() (func() *bignum.Rational) { - return a.eval.(func()*bignum.Rational) -} - -func (a *expr) asString() (func(f *Frame) string) { - return a.eval.(func(*Frame)string) -} - -func (a *expr) asArray() (func(f *Frame) ArrayValue) { - return a.eval.(func(*Frame)ArrayValue) -} - -func (a *expr) asStruct() (func(f *Frame) StructValue) { - return a.eval.(func(*Frame)StructValue) -} - -func (a *expr) asPtr() (func(f *Frame) Value) { - return a.eval.(func(*Frame)Value) -} - -func (a *expr) asFunc() (func(f *Frame) Func) { - return a.eval.(func(*Frame)Func) -} - -func (a *expr) asSlice() (func(f *Frame) Slice) { - return a.eval.(func(*Frame)Slice) -} - -func (a *expr) asMap() (func(f *Frame) Map) { - return a.eval.(func(*Frame)Map) -} - -func (a *expr) asMulti() (func(f *Frame) []Value) { - return a.eval.(func(*Frame)[]Value) -} - -func (a *expr) asInterface() (func(f *Frame) interface {}) { - // TODO(austin) We need the argument names in this type switch - // to work around a 6g bug. - switch sf := a.eval.(type) { - case func(f *Frame)bool: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)uint64: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)int64: - return func(f *Frame) interface{} { return sf(f) }; - case func()*bignum.Integer: - return func(f *Frame) interface{} { return sf() }; - case func(f *Frame)float64: - return func(f *Frame) interface{} { return sf(f) }; - case func()*bignum.Rational: - return func(f *Frame) interface{} { return sf() }; - case func(f *Frame)string: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)ArrayValue: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)StructValue: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)Value: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)Func: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)Slice: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)Map: - return func(f *Frame) interface{} { return sf(f) }; - case func(f *Frame)[]Value: - return func(f *Frame) interface{} { return sf(f) }; - } - log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos); - panic(); -} - -/* * Common expression manipulations */ diff --git a/usr/austin/eval/expr1.go b/usr/austin/eval/expr1.go index 3eac27e09..9f9d696e6 100644 --- a/usr/austin/eval/expr1.go +++ b/usr/austin/eval/expr1.go @@ -1,6 +1,8 @@ -package eval -// generated code +// This file is machine generated by gen.go. +// 6g gen.go && 6l gen.6 && 6.out >expr1.go + +package eval import ( "bignum"; @@ -8,113 +10,195 @@ import ( ) /* - * Operator generators - * Everything below here is MACHINE GENERATED by gen.py genOps + * "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) asUint() (func(*Frame) uint64) { + return a.eval.(func(*Frame)(uint64)) +} +func (a *expr) asInt() (func(*Frame) int64) { + return a.eval.(func(*Frame)(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) 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) asArray() (func(*Frame) ArrayValue) { + return a.eval.(func(*Frame)(ArrayValue)) +} +func (a *expr) asStruct() (func(*Frame) StructValue) { + return a.eval.(func(*Frame)(StructValue)) +} +func (a *expr) asPtr() (func(*Frame) Value) { + return a.eval.(func(*Frame)(Value)) +} +func (a *expr) asFunc() (func(*Frame) Func) { + return a.eval.(func(*Frame)(Func)) +} +func (a *expr) asSlice() (func(*Frame) Slice) { + return a.eval.(func(*Frame)(Slice)) +} +func (a *expr) asMap() (func(*Frame) Map) { + return a.eval.(func(*Frame)(Map)) +} +func (a *expr) asMulti() (func(*Frame) []Value) { + return a.eval.(func(*Frame)[]Value) +} + +func (a *expr) asInterface() (func(*Frame) interface{}) { + // TODO(rsc): Drop f from (f *Frame) in case labels + // after fixing 6g type switch bug. + switch sf := a.eval.(type) { + case func(f *Frame)bool: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)uint64: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)int64: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)*bignum.Integer: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)float64: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)*bignum.Rational: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)string: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)ArrayValue: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)StructValue: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)Value: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)Func: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)Slice: + return func(f *Frame) interface{} { return sf(f) } + case func(f *Frame)Map: + return func(f *Frame) interface{} { return sf(f) } + default: + log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos); + } + panic(); +} + +/* + * Operator generators. */ 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(f *Frame) bool { return val } case *uintType: val := v.(UintValue).Get(); - a.eval = func(f *Frame) uint64 { return val }; + a.eval = func(f *Frame) uint64 { return val } case *intType: val := v.(IntValue).Get(); - a.eval = func(f *Frame) int64 { return val }; + a.eval = func(f *Frame) int64 { return val } case *idealIntType: val := v.(IdealIntValue).Get(); - a.eval = func() *bignum.Integer { return val }; + a.eval = func() *bignum.Integer { return val } case *floatType: val := v.(FloatValue).Get(); - a.eval = func(f *Frame) float64 { return val }; + a.eval = func(f *Frame) float64 { return val } case *idealFloatType: val := v.(IdealFloatValue).Get(); - a.eval = func() *bignum.Rational { return val }; + a.eval = func() *bignum.Rational { return val } case *stringType: val := v.(StringValue).Get(); - a.eval = func(f *Frame) string { return val }; + a.eval = func(f *Frame) string { return val } case *ArrayType: val := v.(ArrayValue).Get(); - a.eval = func(f *Frame) ArrayValue { return val }; + a.eval = func(f *Frame) ArrayValue { return val } case *StructType: val := v.(StructValue).Get(); - a.eval = func(f *Frame) StructValue { return val }; + a.eval = func(f *Frame) StructValue { return val } case *PtrType: val := v.(PtrValue).Get(); - a.eval = func(f *Frame) Value { return val }; + a.eval = func(f *Frame) Value { return val } case *FuncType: val := v.(FuncValue).Get(); - a.eval = func(f *Frame) Func { return val }; + a.eval = func(f *Frame) Func { return val } case *SliceType: val := v.(SliceValue).Get(); - a.eval = func(f *Frame) Slice { return val }; + a.eval = func(f *Frame) Slice { return val } case *MapType: val := v.(MapValue).Get(); - a.eval = func(f *Frame) Map { return val }; + a.eval = func(f *Frame) Map { return val } default: log.Crashf("unexpected constant type %v at %v", a.t, a.pos); } } -func (a *expr) genIdentOp(level int, index int) { +func (a *expr) genIdentOp(level, index int) { a.evalAddr = func(f *Frame) Value { return 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(f *Frame) bool { return f.Get(level, index).(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return f.Get(level, index).(UintValue).Get() }; + a.eval = func(f *Frame) uint64 { return f.Get(level, index).(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return f.Get(level, index).(IntValue).Get() }; + a.eval = func(f *Frame) int64 { return f.Get(level, index).(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return f.Get(level, index).(FloatValue).Get() }; + a.eval = func(f *Frame) float64 { return f.Get(level, index).(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return f.Get(level, index).(StringValue).Get() }; + a.eval = func(f *Frame) string { return f.Get(level, index).(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return f.Get(level, index).(ArrayValue).Get() }; + a.eval = func(f *Frame) ArrayValue { return f.Get(level, index).(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return f.Get(level, index).(StructValue).Get() }; + a.eval = func(f *Frame) StructValue { return f.Get(level, index).(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return f.Get(level, index).(PtrValue).Get() }; + a.eval = func(f *Frame) Value { return f.Get(level, index).(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return f.Get(level, index).(FuncValue).Get() }; + a.eval = func(f *Frame) Func { return f.Get(level, index).(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return f.Get(level, index).(SliceValue).Get() }; + a.eval = func(f *Frame) Slice { return f.Get(level, index).(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return f.Get(level, index).(MapValue).Get() }; + a.eval = func(f *Frame) Map { return 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) }; + a.exec = func(f *Frame) { call(f)}; switch _ := a.t.lit().(type) { case *boolType: - a.eval = func(f *Frame) bool { return call(f)[0].(BoolValue).Get() }; + a.eval = func(f *Frame) bool { return call(f)[0].(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return call(f)[0].(UintValue).Get() }; + a.eval = func(f *Frame) uint64 { return call(f)[0].(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return call(f)[0].(IntValue).Get() }; + a.eval = func(f *Frame) int64 { return call(f)[0].(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return call(f)[0].(FloatValue).Get() }; + a.eval = func(f *Frame) float64 { return call(f)[0].(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return call(f)[0].(StringValue).Get() }; + a.eval = func(f *Frame) string { return call(f)[0].(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return call(f)[0].(ArrayValue).Get() }; + a.eval = func(f *Frame) ArrayValue { return call(f)[0].(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return call(f)[0].(StructValue).Get() }; + a.eval = func(f *Frame) StructValue { return call(f)[0].(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return call(f)[0].(PtrValue).Get() }; + a.eval = func(f *Frame) Value { return call(f)[0].(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return call(f)[0].(FuncValue).Get() }; + a.eval = func(f *Frame) Func { return call(f)[0].(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return call(f)[0].(SliceValue).Get() }; + a.eval = func(f *Frame) Slice { return call(f)[0].(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return call(f)[0].(MapValue).Get() }; + a.eval = func(f *Frame) Map { return call(f)[0].(MapValue).Get() } case *MultiType: - a.eval = func(f *Frame) []Value { return call(f) }; + a.eval = func(f *Frame) []Value { return call(f) } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos); } @@ -124,27 +208,27 @@ func (a *expr) genValue(vf func(*Frame) 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(f *Frame) bool { return vf(f).(BoolValue).Get() } case *uintType: - a.eval = func(f *Frame) uint64 { return vf(f).(UintValue).Get() }; + a.eval = func(f *Frame) uint64 { return vf(f).(UintValue).Get() } case *intType: - a.eval = func(f *Frame) int64 { return vf(f).(IntValue).Get() }; + a.eval = func(f *Frame) int64 { return vf(f).(IntValue).Get() } case *floatType: - a.eval = func(f *Frame) float64 { return vf(f).(FloatValue).Get() }; + a.eval = func(f *Frame) float64 { return vf(f).(FloatValue).Get() } case *stringType: - a.eval = func(f *Frame) string { return vf(f).(StringValue).Get() }; + a.eval = func(f *Frame) string { return vf(f).(StringValue).Get() } case *ArrayType: - a.eval = func(f *Frame) ArrayValue { return vf(f).(ArrayValue).Get() }; + a.eval = func(f *Frame) ArrayValue { return vf(f).(ArrayValue).Get() } case *StructType: - a.eval = func(f *Frame) StructValue { return vf(f).(StructValue).Get() }; + a.eval = func(f *Frame) StructValue { return vf(f).(StructValue).Get() } case *PtrType: - a.eval = func(f *Frame) Value { return vf(f).(PtrValue).Get() }; + a.eval = func(f *Frame) Value { return vf(f).(PtrValue).Get() } case *FuncType: - a.eval = func(f *Frame) Func { return vf(f).(FuncValue).Get() }; + a.eval = func(f *Frame) Func { return vf(f).(FuncValue).Get() } case *SliceType: - a.eval = func(f *Frame) Slice { return vf(f).(SliceValue).Get() }; + a.eval = func(f *Frame) Slice { return vf(f).(SliceValue).Get() } case *MapType: - a.eval = func(f *Frame) Map { return vf(f).(MapValue).Get() }; + a.eval = func(f *Frame) Map { return vf(f).(MapValue).Get() } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos); } @@ -154,23 +238,23 @@ func (a *expr) genUnaryOpNeg(v *expr) { switch _ := a.t.lit().(type) { case *uintType: vf := v.asUint(); - a.eval = func(f *Frame) uint64 { return -vf(f) }; + a.eval = func(f *Frame) uint64 { v := vf(f); return -v } case *intType: vf := v.asInt(); - a.eval = func(f *Frame) int64 { return -vf(f) }; + a.eval = func(f *Frame) int64 { v := vf(f); return -v } case *idealIntType: - vf := v.asIdealInt(); - val := vf().Neg(); - a.eval = func() *bignum.Integer { return val }; + v := v.asIdealInt()(); + val := v.Neg(); + a.eval = func() *bignum.Integer { return val } case *floatType: vf := v.asFloat(); - a.eval = func(f *Frame) float64 { return -vf(f) }; + a.eval = func(f *Frame) float64 { v := vf(f); return -v } case *idealFloatType: - vf := v.asIdealFloat(); - val := vf().Neg(); - a.eval = func() *bignum.Rational { return val }; + v := v.asIdealFloat()(); + val := v.Neg(); + a.eval = func() *bignum.Rational { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", a.t, a.pos); } } @@ -178,9 +262,9 @@ func (a *expr) genUnaryOpNot(v *expr) { switch _ := a.t.lit().(type) { case *boolType: vf := v.asBool(); - a.eval = func(f *Frame) bool { return !vf(f) }; + a.eval = func(f *Frame) bool { v := vf(f); return !v } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", a.t, a.pos); } } @@ -188,266 +272,266 @@ func (a *expr) genUnaryOpXor(v *expr) { switch _ := a.t.lit().(type) { case *uintType: vf := v.asUint(); - a.eval = func(f *Frame) uint64 { return ^vf(f) }; + a.eval = func(f *Frame) uint64 { v := vf(f); return ^v } case *intType: vf := v.asInt(); - a.eval = func(f *Frame) int64 { return ^vf(f) }; + a.eval = func(f *Frame) int64 { v := vf(f); return ^v } case *idealIntType: - vf := v.asIdealInt(); - val := vf().Neg().Sub(bignum.Int(1)); - a.eval = func() *bignum.Integer { return val }; + v := v.asIdealInt()(); + val := v.Neg().Sub(bignum.Int(1)); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", a.t, a.pos); } } func (a *expr) genBinOpAdd(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) + rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l + r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) + rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l + r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Add(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Add(r); + a.eval = func() *bignum.Integer { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { return lf(f) + rf(f) }; + a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l + r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Add(rf()); - a.eval = func() *bignum.Rational { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Add(r); + a.eval = func() *bignum.Rational { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) string { return lf(f) + rf(f) }; + a.eval = func(f *Frame) string { l, r := lf(f), rf(f); return l + r } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpSub(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) - rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l - r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) - rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l - r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Sub(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Sub(r); + a.eval = func() *bignum.Integer { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { return lf(f) - rf(f) }; + a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l - r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Sub(rf()); - a.eval = func() *bignum.Rational { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Sub(r); + a.eval = func() *bignum.Rational { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpMul(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) * rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l * r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) * rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l * r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Mul(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Mul(r); + a.eval = func() *bignum.Integer { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) float64 { return lf(f) * rf(f) }; + a.eval = func(f *Frame) float64 { l, r := lf(f), rf(f); return l * r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Mul(rf()); - a.eval = func() *bignum.Rational { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Mul(r); + a.eval = func() *bignum.Rational { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpQuo(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { 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(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } 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(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Quo(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Quo(r); + a.eval = func() *bignum.Integer { return val } 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(f *Frame) float64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l / r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Quo(rf()); - a.eval = func() *bignum.Rational { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Quo(r); + a.eval = func() *bignum.Rational { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpRem(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { 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(f *Frame) uint64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } 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(f *Frame) int64 { l, r := lf(f), rf(f); if r == 0 { Abort(DivByZero{}) } return l % r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Rem(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Rem(r); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpAnd(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) & rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l & r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) & rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l & r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().And(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.And(r); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpOr(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) | rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l | r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) | rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l | r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Or(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Or(r); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpXor(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) ^ rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l ^ r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) ^ rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l ^ r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Xor(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Xor(r); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpAndNot(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) &^ rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l &^ r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) int64 { return lf(f) &^ rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l &^ r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().AndNot(rf()); - a.eval = func() *bignum.Integer { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.AndNot(r); + a.eval = func() *bignum.Integer { return val } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpShl(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) << rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l << r } case *intType: lf := l.asInt(); rf := r.asUint(); - a.eval = func(f *Frame) int64 { return lf(f) << rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l << r } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } func (a *expr) genBinOpShr(l, r *expr) { - switch _ := a.t.lit().(type) { + switch _ := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) uint64 { return lf(f) >> rf(f) }; + a.eval = func(f *Frame) uint64 { l, r := lf(f), rf(f); return l >> r } case *intType: lf := l.asInt(); rf := r.asUint(); - a.eval = func(f *Frame) int64 { return lf(f) >> rf(f) }; + a.eval = func(f *Frame) int64 { l, r := lf(f), rf(f); return l >> r } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -456,31 +540,31 @@ func (a *expr) genBinOpLss(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) < rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) < rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) < 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) < 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) < rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) < 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) < 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) < rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l < r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -489,31 +573,31 @@ func (a *expr) genBinOpGtr(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) > rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) > rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) > 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) > 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) > rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) > 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) > 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) > rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l > r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -522,31 +606,31 @@ func (a *expr) genBinOpLeq(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) <= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) <= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) <= 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) <= 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) <= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) <= 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) <= 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) <= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l <= r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -555,31 +639,31 @@ func (a *expr) genBinOpGeq(l, r *expr) { case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) >= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) >= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) >= 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) >= 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) >= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) >= 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) >= 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) >= rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l >= r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -588,47 +672,47 @@ func (a *expr) genBinOpEql(l, r *expr) { case *boolType: lf := l.asBool(); rf := r.asBool(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) == 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) == 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) == 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) == 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *PtrType: lf := l.asPtr(); rf := r.asPtr(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *FuncType: lf := l.asFunc(); rf := r.asFunc(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } case *MapType: lf := l.asMap(); rf := r.asMap(); - a.eval = func(f *Frame) bool { return lf(f) == rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l == r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -637,47 +721,47 @@ func (a *expr) genBinOpNeq(l, r *expr) { case *boolType: lf := l.asBool(); rf := r.asBool(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *uintType: lf := l.asUint(); rf := r.asUint(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *intType: lf := l.asInt(); rf := r.asInt(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *idealIntType: - lf := l.asIdealInt(); - rf := r.asIdealInt(); - val := lf().Cmp(rf()) != 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealInt()(); + r := r.asIdealInt()(); + val := l.Cmp(r) != 0; + a.eval = func(f *Frame) bool { return val } case *floatType: lf := l.asFloat(); rf := r.asFloat(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *idealFloatType: - lf := l.asIdealFloat(); - rf := r.asIdealFloat(); - val := lf().Cmp(rf()) != 0; - a.eval = func(f *Frame) bool { return val }; + l := l.asIdealFloat()(); + r := r.asIdealFloat()(); + val := l.Cmp(r) != 0; + a.eval = func(f *Frame) bool { return val } case *stringType: lf := l.asString(); rf := r.asString(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *PtrType: lf := l.asPtr(); rf := r.asPtr(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *FuncType: lf := l.asFunc(); rf := r.asFunc(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } case *MapType: lf := l.asMap(); rf := r.asMap(); - a.eval = func(f *Frame) bool { return lf(f) != rf(f) }; + a.eval = func(f *Frame) bool { l, r := lf(f), rf(f); return l != r } default: - log.Crashf("unexpected left operand type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos); } } @@ -685,37 +769,37 @@ func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) { switch _ := lt.lit().(type) { case *boolType: rf := r.asBool(); - return func(lv Value, f *Frame) { lv.(BoolValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(BoolValue).Set(rf(f)) } case *uintType: rf := r.asUint(); - return func(lv Value, f *Frame) { lv.(UintValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(UintValue).Set(rf(f)) } case *intType: rf := r.asInt(); - return func(lv Value, f *Frame) { lv.(IntValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(IntValue).Set(rf(f)) } case *floatType: rf := r.asFloat(); - return func(lv Value, f *Frame) { lv.(FloatValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(FloatValue).Set(rf(f)) } case *stringType: rf := r.asString(); - return func(lv Value, f *Frame) { lv.(StringValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(StringValue).Set(rf(f)) } case *ArrayType: rf := r.asArray(); - return func(lv Value, f *Frame) { lv.Assign(rf(f)) }; + return func(lv Value, f *Frame) { lv.Assign(rf(f)) } case *StructType: rf := r.asStruct(); - return func(lv Value, f *Frame) { lv.Assign(rf(f)) }; + return func(lv Value, f *Frame) { lv.Assign(rf(f)) } case *PtrType: rf := r.asPtr(); - return func(lv Value, f *Frame) { lv.(PtrValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(PtrValue).Set(rf(f)) } case *FuncType: rf := r.asFunc(); - return func(lv Value, f *Frame) { lv.(FuncValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(FuncValue).Set(rf(f)) } case *SliceType: rf := r.asSlice(); - return func(lv Value, f *Frame) { lv.(SliceValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(SliceValue).Set(rf(f)) } case *MapType: rf := r.asMap(); - return func(lv Value, f *Frame) { lv.(MapValue).Set(rf(f)) }; + return func(lv Value, f *Frame) { lv.(MapValue).Set(rf(f)) } default: log.Crashf("unexpected left operand type %v at %v", lt, r.pos); } diff --git a/usr/austin/eval/gen.go b/usr/austin/eval/gen.go new file mode 100644 index 000000000..54179ea78 --- /dev/null +++ b/usr/austin/eval/gen.go @@ -0,0 +1,322 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +// generate operator implementations + +import ( + "log"; + "os"; + "template"; +) + +type Op struct { + Name string; + Expr string; + Body string; // overrides Expr + ConstExpr string; + AsRightName string; + ReturnType string; + Types []*Type; +} + +type Type struct { + Repr string; + Value string; + Native string; + As string; + IsIdeal bool; + HasAssign bool; +} + +var ( + boolType = &Type{ Repr: "*boolType", Value: "BoolValue", Native: "bool", As: "asBool" }; + uintType = &Type{ Repr: "*uintType", Value: "UintValue", Native: "uint64", As: "asUint" }; + intType = &Type{ Repr: "*intType", Value: "IntValue", Native: "int64", As: "asInt" }; + idealIntType = &Type{ Repr: "*idealIntType", Value: "IdealIntValue", Native: "*bignum.Integer", As: "asIdealInt", IsIdeal: true }; + floatType = &Type{ Repr: "*floatType", Value: "FloatValue", Native: "float64", As: "asFloat" }; + idealFloatType = &Type{ Repr: "*idealFloatType", Value: "IdealFloatValue", Native: "*bignum.Rational", As: "asIdealFloat", IsIdeal: true }; + stringType = &Type{ Repr: "*stringType", Value: "StringValue", Native: "string", As: "asString" }; + arrayType = &Type{ Repr: "*ArrayType", Value: "ArrayValue", Native: "ArrayValue", As: "asArray", HasAssign: true }; + structType = &Type{ Repr: "*StructType", Value: "StructValue", Native: "StructValue", As: "asStruct", HasAssign: true }; + ptrType = &Type{ Repr: "*PtrType", Value: "PtrValue", Native: "Value", As: "asPtr" }; + funcType = &Type{ Repr: "*FuncType", Value: "FuncValue", Native: "Func", As: "asFunc" }; + sliceType = &Type{ Repr: "*SliceType", Value: "SliceValue", Native: "Slice", As: "asSlice" }; + mapType = &Type{ Repr: "*MapType", Value: "MapValue", Native: "Map", As: "asMap" }; + + all = []*Type{ + boolType, + uintType, + intType, + idealIntType, + floatType, + idealFloatType, + stringType, + arrayType, + structType, + ptrType, + funcType, + sliceType, + mapType, + }; + bools = all[0:1]; + integers = all[1:4]; + shiftable = all[1:3]; + numbers = all[1:6]; + addable = all[1:7]; + cmpable = []*Type{ + boolType, + uintType, + intType, + idealIntType, + floatType, + idealFloatType, + stringType, + ptrType, + funcType, + mapType, + }; +) + +var unOps = []Op{ + Op{ Name: "Neg", Expr: "-v", ConstExpr: "v.Neg()", Types: numbers }, + Op{ Name: "Not", Expr: "!v", Types: bools }, + Op{ Name: "Xor", Expr: "^v", ConstExpr: "v.Neg().Sub(bignum.Int(1))", Types: integers }, +} + +var binOps = []Op{ + Op{ Name: "Add", Expr: "l + r", ConstExpr: "l.Add(r)", Types: addable }, + 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", + ConstExpr: "l.Quo(r)", + Types: numbers, + }, + Op{ Name: "Rem", + Body: "if r == 0 { Abort(DivByZero{}) } return l % r", + ConstExpr: "l.Rem(r)", + Types: integers, + }, + Op{ Name: "And", Expr: "l & r", ConstExpr: "l.And(r)", Types: integers }, + Op{ Name: "Or", Expr: "l | r", ConstExpr: "l.Or(r)", Types: integers }, + Op{ Name: "Xor", Expr: "l ^ r", ConstExpr: "l.Xor(r)", Types: integers }, + Op{ Name: "AndNot", Expr: "l &^ r", ConstExpr: "l.AndNot(r)", Types: integers }, + Op{ Name: "Shl", Expr: "l << r", ConstExpr: "l.Shl(uint(r.Value()))", + AsRightName: "asUint", Types: shiftable + }, + Op{ Name: "Shr", Expr: "l >> r", ConstExpr: "l.Shr(uint(r.Value()))", + AsRightName: "asUint", Types: shiftable + }, + Op{ Name: "Lss", Expr: "l < r", ConstExpr: "l.Cmp(r) < 0", ReturnType: "bool", Types: addable }, + Op{ Name: "Gtr", Expr: "l > r", ConstExpr: "l.Cmp(r) > 0", ReturnType: "bool", Types: addable }, + Op{ Name: "Leq", Expr: "l <= r", ConstExpr: "l.Cmp(r) <= 0", ReturnType: "bool", Types: addable }, + Op{ Name: "Geq", Expr: "l >= r", ConstExpr: "l.Cmp(r) >= 0", ReturnType: "bool", Types: addable }, + Op{ Name: "Eql", Expr: "l == r", ConstExpr: "l.Cmp(r) == 0", ReturnType: "bool", Types: cmpable }, + Op{ Name: "Neq", Expr: "l != r", ConstExpr: "l.Cmp(r) != 0", ReturnType: "bool", Types: cmpable }, +} + +type Data struct { + UnaryOps []Op; + BinaryOps []Op; + Types []*Type; +} + +var data = Data { + unOps, + binOps, + all, +} + +const templateStr = ` +// This file is machine generated by gen.go. +// 6g gen.go && 6l gen.6 && 6.out >expr1.go + +package eval + +import ( + "bignum"; + "log"; +) + +/* + * "As" functions. These retrieve evaluator functions from an + * expr, panicking if the requested evaluator has the wrong type. + */ +«.repeated section Types» +«.section IsIdeal» +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»)) +} +«.end» +«.end» +func (a *expr) asMulti() (func(*Frame) []Value) { + return a.eval.(func(*Frame)[]Value) +} + +func (a *expr) asInterface() (func(*Frame) interface{}) { + // TODO(rsc): Drop f from (f *Frame) in case labels + // after fixing 6g type switch bug. + switch sf := a.eval.(type) { +«.repeated section Types» + case func(f *Frame)«Native»: +«.section IsIdeal» + return func(f *Frame) interface{} { return sf(f) } +«.or» + return func(f *Frame) interface{} { return sf(f) } +«.end» +«.end» + default: + log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos); + } + panic(); +} + +/* + * Operator generators. + */ + +func (a *expr) genConstant(v Value) { + switch _ := a.t.lit().(type) { +«.repeated section Types» + case «Repr»: + val := v.(«Value»).Get(); +«.section IsIdeal» + a.eval = func() «Native» { return val } +«.or» + a.eval = func(f *Frame) «Native» { return val } +«.end» +«.end» + 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) }; + 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() } +«.end» +«.end» + 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)}; + 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() } +«.end» +«.end» + case *MultiType: + a.eval = func(f *Frame) []Value { return call(f) } + default: + log.Crashf("unexpected result type %v at %v", a.t, a.pos); + } +} + +func (a *expr) genValue(vf func(*Frame) 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() } +«.end» +«.end» + default: + log.Crashf("unexpected result type %v at %v", a.t, a.pos); + } +} + +«.repeated section UnaryOps» +func (a *expr) genUnaryOp«Name»(v *expr) { + switch _ := a.t.lit().(type) { +«.repeated section Types» + case «Repr»: +«.section IsIdeal» + v := v.«As»()(); + val := «ConstExpr»; + a.eval = func() «Native» { return val } +«.or» + vf := v.«As»(); + a.eval = func(f *Frame) «Native» { v := vf(f); return «Expr» } +«.end» +«.end» + default: + log.Crashf("unexpected type %v at %v", a.t, a.pos); + } +} + +«.end» +«.repeated section BinaryOps» +func (a *expr) genBinOp«Name»(l, r *expr) { + switch _ := l.t.lit().(type) { +«.repeated section Types» + case «Repr»: +«.section IsIdeal» + l := l.«As»()(); + r := r.«As»()(); + val := «ConstExpr»; +«.section ReturnType» + a.eval = func(f *Frame) «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» } +«.end» +«.end» + default: + log.Crashf("unexpected type %v at %v", l.t, a.pos); + } +} + +«.end» +func genAssign(lt Type, r *expr) (func(lv Value, f *Frame)) { + 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» } +«.end» +«.end» + default: + log.Crashf("unexpected left operand type %v at %v", lt, r.pos); + } + panic(); +} +` + +func main() { + t := template.New(nil); + t.SetDelims("«", "»"); + err := t.Parse(templateStr); + if err != nil { + log.Exit(err); + } + err = t.Execute(data, os.Stdout); + if err != nil { + log.Exit(err); + } +} diff --git a/usr/austin/eval/stmt.go b/usr/austin/eval/stmt.go index 53c6a9cc1..9002b980f 100644 --- a/usr/austin/eval/stmt.go +++ b/usr/austin/eval/stmt.go @@ -1061,7 +1061,7 @@ func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) { fall := false; for j, s := range clause.Body { if br, ok := s.(*ast.BranchStmt); ok && br.Tok == token.FALLTHROUGH { - println("Found fallthrough"); + // println("Found fallthrough"); // It may be used only as the final // non-empty statement in a case or // default clause in an expression diff --git a/usr/austin/eval/stmt_test.go b/usr/austin/eval/stmt_test.go index 9de269a2d..f701d27f7 100644 --- a/usr/austin/eval/stmt_test.go +++ b/usr/austin/eval/stmt_test.go @@ -264,7 +264,7 @@ var stmtTests = []test { Val2("switch func()int{i2++;return 5}() { case 1, 2: i += 2; case 4, 5: i += 4 }", "i", 1+4, "i2", 3), SRuns("switch i { case i: }"), // TODO(austin) Why doesn't this fail? - SErr("case 1:", "XXX"), + //SErr("case 1:", "XXX"), // For Val2("for x := 1; x < 5; x++ { i+=x }; i2 = 4", "i", 11, "i2", 4), |