123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- package eval
- import (
- "fw/cp/constant/operation"
- "fw/cp/node"
- "fw/cp/object"
- "fw/cp/traps"
- "fw/rt2"
- "fw/rt2/context"
- rtm "fw/rt2/module"
- "fw/rt2/scope"
- "math/big"
- "reflect"
- "ypk/assert"
- "ypk/halt"
- )
- func getConst(in IN) OUT {
- c := in.IR.(node.ConstantNode)
- sc := rt2.ModScope(in.Frame)
- fn := sc.Provide(c)
- assert.For(fn != nil, 40)
- rt2.ValueOf(in.Parent)[c.Adr()] = fn
- rt2.RegOf(in.Parent)[in.Key] = c.Adr()
- return End()
- }
- func getVar(in IN) OUT {
- v := in.IR.(node.VariableNode)
- obj := rtm.MapImportObject(in.Frame.Domain(), v.Object())
- sc := rt2.ScopeFor(in.Frame, obj.Adr(), func(val scope.Value) {
- rt2.ValueOf(in.Parent)[v.Adr()] = val
- rt2.RegOf(in.Parent)[in.Key] = v.Adr()
- })
- rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: sc, Id: obj.Adr()}
- return End()
- }
- func getVarPar(in IN) OUT {
- v := in.IR.(node.ParameterNode)
- sc := rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
- rt2.ValueOf(in.Parent)[v.Adr()] = val
- rt2.RegOf(in.Parent)[in.Key] = v.Adr()
- rt2.RegOf(in.Parent)[context.META] = &Meta{}
- })
- rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: sc, Id: v.Object().Adr()}
- return End()
- }
- func getField(in IN) OUT {
- const left = "field:left"
- f := in.IR.(node.FieldNode)
- return GetDesignator(in, left, f.Left(), func(in IN) OUT {
- _v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- switch v := _v.(type) {
- case scope.Record:
- _fo := f.Object()
- switch fo := _fo.(type) {
- case object.FieldObject:
- tc := in.Frame.Domain().Global().Discover(context.MOD).(rtm.List).NewTypeCalc()
- tc.ConnectTo(fo.TypeOf())
- if _, ft := tc.ForeignBase(); ft != nil {
- for x := ft.Link(); x != nil; x = x.Link() {
- switch fx := x.(type) {
- case object.FieldObject:
- if fx.Name() == fo.Name() {
- _fo = fx
- }
- }
- }
- }
- default:
- halt.As(100, reflect.TypeOf(fo))
- }
- fld := v.Get(_fo.Adr()).(scope.Variable)
- rt2.ValueOf(in.Parent)[f.Adr()] = fld
- rt2.RegOf(in.Parent)[in.Key] = f.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: nil, Rec: v, Id: fld.Id()}
- return End()
- default:
- halt.As(100, reflect.TypeOf(v))
- }
- panic(0)
- })
- }
- func getIndex(in IN) OUT {
- const (
- left = "index:left"
- right = "index:right"
- )
- i := in.IR.(node.IndexNode)
- return GetExpression(in, right, i.Right(), func(IN) OUT {
- idx := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
- assert.For(idx != nil, 40)
- return GetDesignator(in, left, i.Left(), func(IN) OUT {
- arr := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- assert.For(arr != nil, 41)
- switch a := arr.(type) {
- case scope.Array:
- rt2.ValueOf(in.Parent)[i.Adr()] = a.Get(idx)
- rt2.RegOf(in.Parent)[in.Key] = i.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Arr: a, Id: a.Id()}
- return End()
- default:
- halt.As(100, reflect.TypeOf(a))
- }
- panic(890)
- })
- })
- }
- func getProc(in IN) OUT {
- p := in.IR.(node.ProcedureNode)
- sc := rt2.ModScope(in.Frame)
- fn := sc.Provide(p.Object())
- assert.For(fn != nil, 40)
- rt2.ValueOf(in.Parent)[p.Adr()] = fn
- rt2.RegOf(in.Parent)[in.Key] = p.Adr()
- rt2.RegOf(in.Parent)[context.META] = &Meta{}
- return End()
- }
- const nullSafeFlag = "deref:null"
- func getDeref(in IN) OUT {
- const left = "design:left"
- d := in.IR.(node.DerefNode)
- //nullSafe, _ := rt2.RegOf(in.Parent)[nullSafeFlag].(bool)
- //fmt.Println(reflect.TypeOf(rt2.NodeOf(in.Parent)), nullSafe)
- return GetDesignator(in, left, d.Left(), func(in IN) (out OUT) {
- _v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- switch v := _v.(type) {
- case scope.Array:
- assert.For(!d.Ptr(), 40)
- t, c := scope.Ops.TypeOf(v)
- switch cc := c.(type) {
- case object.ArrayType:
- assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
- rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- rt2.RegOf(in.Parent)[context.META] = nil
- return End()
- case object.DynArrayType:
- assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
- rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- rt2.RegOf(in.Parent)[context.META] = nil
- return End()
- default:
- halt.As(100, t, reflect.TypeOf(cc))
- }
- case scope.Pointer:
- switch {
- case scope.GoTypeFrom(v.Get()) == nil:
- out = makeTrap(in.Frame, traps.NILderef)
- case d.Ptr():
- out = End()
- switch r := v.Get().(type) {
- case scope.Record:
- rec := r.(scope.Record)
- rt2.ValueOf(in.Parent)[d.Adr()] = rec
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: rt2.ScopeFor(in.Frame, rec.Id()), Id: rec.Id()}
- case scope.Array:
- arr := r.(scope.Array)
- rt2.ValueOf(in.Parent)[d.Adr()] = arr
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: rt2.ScopeFor(in.Frame, arr.Id()), Id: arr.Id()}
- default:
- halt.As(100, reflect.TypeOf(r))
- }
- case !d.Ptr():
- out = End()
- switch r := v.Get().(type) {
- case scope.Array:
- arr := r.(scope.Array)
- rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(arr))
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Arr: arr, Id: arr.Id()}
- default:
- halt.As(100, reflect.TypeOf(r))
- }
- default:
- halt.As(100, d.Adr(), d.Ptr(), v, v.Get())
- }
- return out
- case scope.Index:
- switch {
- case scope.GoTypeFrom(v.Get()) == nil:
- out = makeTrap(in.Frame, traps.NILderef)
- case !d.Ptr():
- out = End()
- switch r := v.Get().(type) {
- case scope.Array:
- arr := r.(scope.Array)
- rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(arr))
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Arr: arr, Id: arr.Id()}
- default:
- halt.As(100, reflect.TypeOf(r))
- }
- case d.Ptr():
- out = End()
- switch r := v.Get().(type) {
- case scope.Pointer:
- if scope.GoTypeFrom(v.Get()) == nil {
- out = makeTrap(in.Frame, traps.NILderef)
- } else {
- switch vr := r.Get().(type) {
- case scope.Record:
- rec := vr.(scope.Record)
- rt2.ValueOf(in.Parent)[d.Adr()] = rec
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: rt2.ScopeFor(in.Frame, rec.Id()), Id: rec.Id()}
- case scope.Array:
- arr := vr.(scope.Array)
- rt2.ValueOf(in.Parent)[d.Adr()] = arr
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- //rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: rt2.ScopeFor(in.Frame, arr.Id()), Id: arr.Id()}
- default:
- halt.As(100, reflect.TypeOf(r))
- }
- }
- default:
- halt.As(100, reflect.TypeOf(r))
- }
- default:
- halt.As(100, d.Adr(), d.Ptr(), v, v.Get())
- }
- return out
- case scope.Value:
- rt2.ValueOf(in.Parent)[d.Adr()] = v
- rt2.RegOf(in.Parent)[in.Key] = d.Adr()
- rt2.RegOf(in.Parent)[context.META] = nil
- return End()
- default:
- halt.As(100, reflect.TypeOf(v))
- }
- panic(0)
- })
- }
- func getDop(in IN) OUT {
- const (
- left = "dop:left"
- right = "dop:right"
- )
- op := in.IR.(node.DyadicNode)
- do := func(in IN) OUT {
- var (
- res scope.Value
- )
- l := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- r := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
- switch op.Operation() {
- case operation.PLUS:
- res = scope.Ops.Sum(l, r)
- case operation.MINUS:
- res = scope.Ops.Sub(l, r)
- case operation.EQUAL:
- res = scope.Ops.Eq(l, r)
- case operation.LESSER:
- res = scope.Ops.Lss(l, r)
- case operation.LESS_EQUAL:
- res = scope.Ops.Leq(l, r)
- case operation.LEN:
- res = scope.Ops.Len(op.Left().Object(), l, r)
- case operation.NOT_EQUAL:
- res = scope.Ops.Neq(l, r)
- case operation.GREATER:
- res = scope.Ops.Gtr(l, r)
- case operation.MAX:
- res = scope.Ops.Max(l, r)
- case operation.MIN:
- res = scope.Ops.Min(l, r)
- case operation.DIV:
- res = scope.Ops.Div(l, r)
- case operation.MOD:
- res = scope.Ops.Mod(l, r)
- case operation.ALIEN_MSK:
- res = scope.Ops.Msk(l, r)
- case operation.TIMES:
- res = scope.Ops.Mult(l, r)
- case operation.SLASH:
- res = scope.Ops.Divide(l, r)
- case operation.IN:
- res = scope.Ops.In(l, r)
- case operation.ASH:
- res = scope.Ops.Ash(l, r)
- case operation.AND:
- res = scope.Ops.And(l, r)
- case operation.OR:
- res = scope.Ops.Or(l, r)
- case operation.GREAT_EQUAL:
- res = scope.Ops.Geq(l, r)
- default:
- halt.As(100, op.Operation())
- }
- assert.For(res != nil, 40)
- rt2.ValueOf(in.Parent)[op.Adr()] = res
- rt2.RegOf(in.Parent)[in.Key] = op.Adr()
- return End()
- }
- next := func(IN) OUT {
- return GetExpression(in, right, op.Right(), do)
- }
- short := func(IN) OUT {
- id := KeyOf(in, left)
- lv := rt2.ValueOf(in.Frame)[id]
- switch op.Operation() {
- case operation.AND:
- val := scope.GoTypeFrom(lv).(bool)
- if val {
- return Now(next)
- } else {
- rt2.ValueOf(in.Parent)[op.Adr()] = scope.TypeFromGo(false)
- rt2.RegOf(in.Parent)[in.Key] = op.Adr()
- return End()
- }
- case operation.OR:
- val := scope.GoTypeFrom(lv).(bool)
- if !val {
- return Now(next)
- } else {
- rt2.ValueOf(in.Parent)[op.Adr()] = scope.TypeFromGo(true)
- rt2.RegOf(in.Parent)[in.Key] = op.Adr()
- return End()
- }
- default:
- return Now(next)
- }
- }
- return GetExpression(in, left, op.Left(), short)
- }
- func getMop(in IN) OUT {
- const left = "mop:left"
- op := in.IR.(node.MonadicNode)
- do := func(in IN) OUT {
- lv := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- var res scope.Value
- switch op.Operation() {
- case operation.ALIEN_CONV:
- if op.Type() != object.NOTYPE {
- res = scope.Ops.Conv(lv, op.Type())
- } else {
- res = scope.Ops.Conv(lv, op.Type(), op.Complex())
- }
- case operation.NOT:
- res = scope.Ops.Not(lv)
- case operation.IS:
- res = scope.Ops.Is(lv, op.Object().Complex())
- case operation.ABS:
- res = scope.Ops.Abs(lv)
- case operation.ODD:
- res = scope.Ops.Odd(lv)
- case operation.CAP:
- res = scope.Ops.Cap(lv)
- case operation.BITS:
- res = scope.Ops.Bits(lv)
- case operation.MINUS:
- res = scope.Ops.Minus(lv)
- default:
- halt.As(100, "unknown op", op.Operation())
- }
- assert.For(res != nil, 60)
- rt2.ValueOf(in.Parent)[op.Adr()] = res
- rt2.RegOf(in.Parent)[in.Key] = op.Adr()
- return End()
- }
- return GetExpression(in, left, op.Left(), do)
- }
- func narrowValue(in scope.Value) scope.Value {
- //fmt.Println(reflect.TypeOf(in))
- switch v := in.(type) {
- case scope.Pointer:
- return narrowValue(v.Get())
- case scope.Index:
- return narrowValue(v.Get())
- default:
- return v
- }
- }
- func getGuard(in IN) OUT {
- const left = "guard:left"
- g := in.IR.(node.GuardNode)
- return GetDesignator(in, left, g.Left(), func(IN) OUT {
- v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- assert.For(v != nil, 20)
- if scope.GoTypeFrom(scope.Ops.Is(narrowValue(v), g.Type())).(bool) {
- rt2.ValueOf(in.Parent)[g.Adr()] = v
- rt2.RegOf(in.Parent)[in.Key] = g.Adr()
- rt2.RegOf(in.Parent)[context.META] = rt2.RegOf(in.Frame)[context.META] //&Meta{Id: vv.Id(), }
- return End()
- } else if scope.GoTypeFrom(v) == nil {
- return makeTrap(in.Frame, traps.NILderef)
- } else {
- return makeTrap(in.Frame, traps.GUARDfail)
- }
- })
- }
- func bit_range(_f scope.Value, _t scope.Value) scope.Value {
- f := scope.GoTypeFrom(_f).(int32)
- t := scope.GoTypeFrom(_t).(int32)
- ret := big.NewInt(0)
- for i := f; i <= t; i++ {
- ret = ret.SetBit(ret, int(i), 1)
- }
- //fmt.Println("bits", ret)
- return scope.TypeFromGo(ret)
- }
- func getRange(in IN) OUT {
- const (
- left = "range:left"
- right = "range:right"
- )
- r := in.IR.(node.RangeNode)
- return GetExpression(in, left, r.Left(), func(IN) OUT {
- return GetExpression(in, right, r.Right(), func(in IN) OUT {
- lv := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
- rv := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
- res := bit_range(lv, rv)
- rt2.ValueOf(in.Parent)[r.Adr()] = res
- rt2.RegOf(in.Parent)[in.Key] = r.Adr()
- return End()
- })
- })
- }
|