// 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. */ func (a *expr) asBool() (func(*Thread) bool) { return a.eval.(func(*Thread) bool) } func (a *expr) asUint() (func(*Thread) uint64) { return a.eval.(func(*Thread) uint64) } func (a *expr) asInt() (func(*Thread) int64) { return a.eval.(func(*Thread) int64) } func (a *expr) asIdealInt() (func() *bignum.Integer) { return a.eval.(func() *bignum.Integer) } func (a *expr) asFloat() (func(*Thread) float64) { return a.eval.(func(*Thread) float64) } func (a *expr) asIdealFloat() (func() *bignum.Rational) { return a.eval.(func() *bignum.Rational) } func (a *expr) asString() (func(*Thread) string) { return a.eval.(func(*Thread) string) } func (a *expr) asArray() (func(*Thread) ArrayValue) { return a.eval.(func(*Thread) ArrayValue) } func (a *expr) asStruct() (func(*Thread) StructValue) { return a.eval.(func(*Thread) StructValue) } func (a *expr) asPtr() (func(*Thread) Value) { return a.eval.(func(*Thread) Value) } func (a *expr) asFunc() (func(*Thread) Func) { return a.eval.(func(*Thread) Func) } func (a *expr) asSlice() (func(*Thread) Slice) { return a.eval.(func(*Thread) Slice) } func (a *expr) asMap() (func(*Thread) Map) { return a.eval.(func(*Thread) Map) } func (a *expr) asMulti() (func(*Thread) []Value) { return a.eval.(func(*Thread) []Value) } func (a *expr) asInterface() (func(*Thread) interface{}) { switch sf := a.eval.(type) { case func(t *Thread) bool: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) uint64: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) int64: return func(t *Thread) interface{} { return sf(t) } case func() *bignum.Integer: return func(*Thread) interface{} { return sf() } case func(t *Thread) float64: return func(t *Thread) interface{} { return sf(t) } case func() *bignum.Rational: return func(*Thread) interface{} { return sf() } case func(t *Thread) string: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) ArrayValue: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) StructValue: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) Value: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) Func: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) Slice: return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) Map: return func(t *Thread) interface{} { return sf(t) } 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: a.eval = func(t *Thread) bool { return v.(BoolValue).Get(t) } case *uintType: a.eval = func(t *Thread) uint64 { return v.(UintValue).Get(t) } case *intType: a.eval = func(t *Thread) int64 { return v.(IntValue).Get(t) } case *idealIntType: val := v.(IdealIntValue).Get(); a.eval = func() *bignum.Integer { return val }; case *floatType: a.eval = func(t *Thread) float64 { return v.(FloatValue).Get(t) } case *idealFloatType: val := v.(IdealFloatValue).Get(); a.eval = func() *bignum.Rational { return val }; case *stringType: a.eval = func(t *Thread) string { return v.(StringValue).Get(t) } case *ArrayType: a.eval = func(t *Thread) ArrayValue { return v.(ArrayValue).Get(t) } case *StructType: a.eval = func(t *Thread) StructValue { return v.(StructValue).Get(t) } case *PtrType: a.eval = func(t *Thread) Value { return v.(PtrValue).Get(t) } case *FuncType: a.eval = func(t *Thread) Func { return v.(FuncValue).Get(t) } case *SliceType: a.eval = func(t *Thread) Slice { return v.(SliceValue).Get(t) } case *MapType: a.eval = func(t *Thread) Map { return v.(MapValue).Get(t) } default: log.Crashf("unexpected constant type %v at %v", a.t, a.pos) } } func (a *expr) genIdentOp(level, index int) { a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) }; switch a.t.lit().(type) { case *boolType: a.eval = func(t *Thread) bool { return t.f.Get(level, index).(BoolValue).Get(t) } case *uintType: a.eval = func(t *Thread) uint64 { return t.f.Get(level, index).(UintValue).Get(t) } case *intType: a.eval = func(t *Thread) int64 { return t.f.Get(level, index).(IntValue).Get(t) } case *floatType: a.eval = func(t *Thread) float64 { return t.f.Get(level, index).(FloatValue).Get(t) } case *stringType: a.eval = func(t *Thread) string { return t.f.Get(level, index).(StringValue).Get(t) } case *ArrayType: a.eval = func(t *Thread) ArrayValue { return t.f.Get(level, index).(ArrayValue).Get(t) } case *StructType: a.eval = func(t *Thread) StructValue { return t.f.Get(level, index).(StructValue).Get(t) } case *PtrType: a.eval = func(t *Thread) Value { return t.f.Get(level, index).(PtrValue).Get(t) } case *FuncType: a.eval = func(t *Thread) Func { return t.f.Get(level, index).(FuncValue).Get(t) } case *SliceType: a.eval = func(t *Thread) Slice { return t.f.Get(level, index).(SliceValue).Get(t) } case *MapType: a.eval = func(t *Thread) Map { return t.f.Get(level, index).(MapValue).Get(t) } default: log.Crashf("unexpected identifier type %v at %v", a.t, a.pos) } } func (a *expr) genFuncCall(call func(t *Thread) []Value) { a.exec = func(t *Thread) { call(t) }; switch a.t.lit().(type) { case *boolType: a.eval = func(t *Thread) bool { return call(t)[0].(BoolValue).Get(t) } case *uintType: a.eval = func(t *Thread) uint64 { return call(t)[0].(UintValue).Get(t) } case *intType: a.eval = func(t *Thread) int64 { return call(t)[0].(IntValue).Get(t) } case *floatType: a.eval = func(t *Thread) float64 { return call(t)[0].(FloatValue).Get(t) } case *stringType: a.eval = func(t *Thread) string { return call(t)[0].(StringValue).Get(t) } case *ArrayType: a.eval = func(t *Thread) ArrayValue { return call(t)[0].(ArrayValue).Get(t) } case *StructType: a.eval = func(t *Thread) StructValue { return call(t)[0].(StructValue).Get(t) } case *PtrType: a.eval = func(t *Thread) Value { return call(t)[0].(PtrValue).Get(t) } case *FuncType: a.eval = func(t *Thread) Func { return call(t)[0].(FuncValue).Get(t) } case *SliceType: a.eval = func(t *Thread) Slice { return call(t)[0].(SliceValue).Get(t) } case *MapType: a.eval = func(t *Thread) Map { return call(t)[0].(MapValue).Get(t) } case *MultiType: a.eval = func(t *Thread) []Value { return call(t) } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos) } } func (a *expr) genValue(vf func(*Thread) Value) { a.evalAddr = vf; switch a.t.lit().(type) { case *boolType: a.eval = func(t *Thread) bool { return vf(t).(BoolValue).Get(t) } case *uintType: a.eval = func(t *Thread) uint64 { return vf(t).(UintValue).Get(t) } case *intType: a.eval = func(t *Thread) int64 { return vf(t).(IntValue).Get(t) } case *floatType: a.eval = func(t *Thread) float64 { return vf(t).(FloatValue).Get(t) } case *stringType: a.eval = func(t *Thread) string { return vf(t).(StringValue).Get(t) } case *ArrayType: a.eval = func(t *Thread) ArrayValue { return vf(t).(ArrayValue).Get(t) } case *StructType: a.eval = func(t *Thread) StructValue { return vf(t).(StructValue).Get(t) } case *PtrType: a.eval = func(t *Thread) Value { return vf(t).(PtrValue).Get(t) } case *FuncType: a.eval = func(t *Thread) Func { return vf(t).(FuncValue).Get(t) } case *SliceType: a.eval = func(t *Thread) Slice { return vf(t).(SliceValue).Get(t) } case *MapType: a.eval = func(t *Thread) Map { return vf(t).(MapValue).Get(t) } default: log.Crashf("unexpected result type %v at %v", a.t, a.pos) } } func (a *expr) genUnaryOpNeg(v *expr) { switch a.t.lit().(type) { case *uintType: vf := v.asUint(); a.eval = func(t *Thread) uint64 { v := vf(t); return -v; }; case *intType: vf := v.asInt(); a.eval = func(t *Thread) int64 { v := vf(t); return -v; }; case *idealIntType: v := v.asIdealInt()(); val := v.Neg(); a.eval = func() *bignum.Integer { return val }; case *floatType: vf := v.asFloat(); a.eval = func(t *Thread) float64 { v := vf(t); return -v; }; case *idealFloatType: v := v.asIdealFloat()(); val := v.Neg(); a.eval = func() *bignum.Rational { return val }; default: log.Crashf("unexpected type %v at %v", a.t, a.pos) } } func (a *expr) genUnaryOpNot(v *expr) { switch a.t.lit().(type) { case *boolType: vf := v.asBool(); a.eval = func(t *Thread) bool { v := vf(t); return !v; }; default: log.Crashf("unexpected type %v at %v", a.t, a.pos) } } func (a *expr) genUnaryOpXor(v *expr) { switch a.t.lit().(type) { case *uintType: vf := v.asUint(); a.eval = func(t *Thread) uint64 { v := vf(t); return ^v; }; case *intType: vf := v.asInt(); a.eval = func(t *Thread) int64 { v := vf(t); return ^v; }; case *idealIntType: v := v.asIdealInt()(); val := v.Neg().Sub(bignum.Int(1)); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", a.t, a.pos) } } func (a *expr) genBinOpLogAnd(l, r *expr) { lf := l.asBool(); rf := r.asBool(); a.eval = func(t *Thread) bool { return lf(t) && rf(t) }; } func (a *expr) genBinOpLogOr(l, r *expr) { lf := l.asBool(); rf := r.asBool(); a.eval = func(t *Thread) bool { return lf(t) || rf(t) }; } func (a *expr) genBinOpAdd(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l + r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l + r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l + r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l + r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l + r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l + r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l + r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l + r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l + r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l + r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: 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(); switch t.Bits { case 32: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l + r; return float64(float32(ret)); } case 64: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l + r; return float64(float64(ret)); } case 0: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l + r; return float64(float(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealFloatType: 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(t *Thread) string { l, r := lf(t), rf(t); return l + r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpSub(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l - r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l - r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l - r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l - r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l - r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l - r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l - r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l - r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l - r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l - r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: 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(); switch t.Bits { case 32: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l - r; return float64(float32(ret)); } case 64: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l - r; return float64(float64(ret)); } case 0: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l - r; return float64(float(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Sub(r); a.eval = func() *bignum.Rational { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpMul(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l * r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l * r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l * r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l * r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l * r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l * r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l * r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l * r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l * r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l * r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: 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(); switch t.Bits { case 32: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l * r; return float64(float32(ret)); } case 64: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l * r; return float64(float64(ret)); } case 0: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; ret = l * r; return float64(float(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Mul(r); a.eval = func() *bignum.Rational { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpQuo(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: 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(); switch t.Bits { case 32: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return float64(float32(ret)); } case 64: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return float64(float64(ret)); } case 0: a.eval = func(t *Thread) float64 { l, r := lf(t), rf(t); var ret float64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l / r; return float64(float(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Quo(r); a.eval = func() *bignum.Rational { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpRem(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; if r == 0 { t.Abort(DivByZeroError{}) } ret = l % r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Rem(r); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpAnd(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l & r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l & r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l & r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l & r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l & r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l & r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l & r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l & r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l & r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l & r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.And(r); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpOr(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l | r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l | r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l | r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l | r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l | r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l | r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l | r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l | r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l | r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l | r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Or(r); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpXor(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l ^ r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l ^ r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l ^ r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l ^ r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l ^ r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l ^ r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l ^ r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l ^ r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l ^ r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l ^ r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Xor(r); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpAndNot(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l &^ r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l &^ r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l &^ r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l &^ r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l &^ r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asInt(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l &^ r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l &^ r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l &^ r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l &^ r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l &^ r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.AndNot(r); a.eval = func() *bignum.Integer { return val }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpShl(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l << r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l << r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l << r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l << r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l << r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l << r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l << r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l << r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l << r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l << r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpShr(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l >> r; return uint64(uint8(ret)); } case 16: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l >> r; return uint64(uint16(ret)); } case 32: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l >> r; return uint64(uint32(ret)); } case 64: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l >> r; return uint64(uint64(ret)); } case 0: a.eval = func(t *Thread) uint64 { l, r := lf(t), rf(t); var ret uint64; ret = l >> r; return uint64(uint(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } case *intType: lf := l.asInt(); rf := r.asUint(); switch t.Bits { case 8: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l >> r; return int64(int8(ret)); } case 16: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l >> r; return int64(int16(ret)); } case 32: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l >> r; return int64(int32(ret)); } case 64: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l >> r; return int64(int64(ret)); } case 0: a.eval = func(t *Thread) int64 { l, r := lf(t), rf(t); var ret int64; ret = l >> r; return int64(int(ret)); } default: log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpLss(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) < 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) < 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l < r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpGtr(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) > 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) > 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l > r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpLeq(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) <= 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) <= 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l <= r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpGeq(l, r *expr) { switch t := l.t.lit().(type) { case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) >= 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) >= 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l >= r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpEql(l, r *expr) { switch t := l.t.lit().(type) { case *boolType: lf := l.asBool(); rf := r.asBool(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) == 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) == 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *PtrType: lf := l.asPtr(); rf := r.asPtr(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *FuncType: lf := l.asFunc(); rf := r.asFunc(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; case *MapType: lf := l.asMap(); rf := r.asMap(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l == r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func (a *expr) genBinOpNeq(l, r *expr) { switch t := l.t.lit().(type) { case *boolType: lf := l.asBool(); rf := r.asBool(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *uintType: lf := l.asUint(); rf := r.asUint(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *intType: lf := l.asInt(); rf := r.asInt(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *idealIntType: l := l.asIdealInt()(); r := r.asIdealInt()(); val := l.Cmp(r) != 0; a.eval = func(t *Thread) bool { return val }; case *floatType: lf := l.asFloat(); rf := r.asFloat(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *idealFloatType: l := l.asIdealFloat()(); r := r.asIdealFloat()(); val := l.Cmp(r) != 0; a.eval = func(t *Thread) bool { return val }; case *stringType: lf := l.asString(); rf := r.asString(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *PtrType: lf := l.asPtr(); rf := r.asPtr(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *FuncType: lf := l.asFunc(); rf := r.asFunc(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; case *MapType: lf := l.asMap(); rf := r.asMap(); a.eval = func(t *Thread) bool { l, r := lf(t), rf(t); return l != r; }; default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } } func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) { switch lt.lit().(type) { case *boolType: rf := r.asBool(); return func(lv Value, t *Thread) { lv.(BoolValue).Set(t, rf(t)) }; case *uintType: rf := r.asUint(); return func(lv Value, t *Thread) { lv.(UintValue).Set(t, rf(t)) }; case *intType: rf := r.asInt(); return func(lv Value, t *Thread) { lv.(IntValue).Set(t, rf(t)) }; case *floatType: rf := r.asFloat(); return func(lv Value, t *Thread) { lv.(FloatValue).Set(t, rf(t)) }; case *stringType: rf := r.asString(); return func(lv Value, t *Thread) { lv.(StringValue).Set(t, rf(t)) }; case *ArrayType: rf := r.asArray(); return func(lv Value, t *Thread) { lv.Assign(t, rf(t)) }; case *StructType: rf := r.asStruct(); return func(lv Value, t *Thread) { lv.Assign(t, rf(t)) }; case *PtrType: rf := r.asPtr(); return func(lv Value, t *Thread) { lv.(PtrValue).Set(t, rf(t)) }; case *FuncType: rf := r.asFunc(); return func(lv Value, t *Thread) { lv.(FuncValue).Set(t, rf(t)) }; case *SliceType: rf := r.asSlice(); return func(lv Value, t *Thread) { lv.(SliceValue).Set(t, rf(t)) }; case *MapType: rf := r.asMap(); return func(lv Value, t *Thread) { lv.(MapValue).Set(t, rf(t)) }; default: log.Crashf("unexpected left operand type %v at %v", lt, r.pos) } panic(); }