|
@@ -17,12 +17,27 @@ type manager struct {
|
|
|
areas *list.List
|
|
|
}
|
|
|
|
|
|
+type KVarea interface {
|
|
|
+ set(scope.ID, interface{})
|
|
|
+ get(scope.ID) interface{}
|
|
|
+}
|
|
|
+
|
|
|
type area struct {
|
|
|
root node.Node
|
|
|
- data map[scope.ID]interface{}
|
|
|
+ x map[scope.ID]interface{}
|
|
|
ready bool
|
|
|
}
|
|
|
|
|
|
+func (a *area) set(k scope.ID, v interface{}) {
|
|
|
+ key := scope.ID{Name: k.Name}
|
|
|
+ a.x[key] = v
|
|
|
+}
|
|
|
+
|
|
|
+func (a *area) get(k scope.ID) interface{} {
|
|
|
+ key := scope.ID{Name: k.Name}
|
|
|
+ return a.x[key]
|
|
|
+}
|
|
|
+
|
|
|
type value interface {
|
|
|
set(x interface{})
|
|
|
get() interface{}
|
|
@@ -45,9 +60,9 @@ type basic struct {
|
|
|
}
|
|
|
|
|
|
type record interface {
|
|
|
- set(field string, x interface{})
|
|
|
- get(field string) interface{}
|
|
|
- init(heap *area)
|
|
|
+ setField(field string, x interface{})
|
|
|
+ getField(field string) interface{}
|
|
|
+ init(root node.Node)
|
|
|
}
|
|
|
|
|
|
func (b *basic) set(i interface{}) { b.data = i }
|
|
@@ -67,9 +82,19 @@ type arr struct {
|
|
|
data []interface{}
|
|
|
}
|
|
|
|
|
|
-func (a *arr) get(i int64) interface{} { return a.data[i] }
|
|
|
+func (a *arr) get(i int64) interface{} {
|
|
|
+ if len(a.data) == 0 {
|
|
|
+ a.data = make([]interface{}, a.par)
|
|
|
+ }
|
|
|
+ return a.data[i]
|
|
|
+}
|
|
|
|
|
|
-func (a *arr) set(i int64, x interface{}) { a.data[i] = x }
|
|
|
+func (a *arr) set(i int64, x interface{}) {
|
|
|
+ if len(a.data) == 0 {
|
|
|
+ a.data = make([]interface{}, a.par)
|
|
|
+ }
|
|
|
+ a.data[i] = x
|
|
|
+}
|
|
|
|
|
|
func (a *arr) sel() []interface{} { return a.data }
|
|
|
|
|
@@ -77,16 +102,22 @@ func (a *arr) upd(x []interface{}) { a.data = x }
|
|
|
|
|
|
type rec struct {
|
|
|
link object.Object
|
|
|
- heap *area
|
|
|
+ root node.Node
|
|
|
+ x map[scope.ID]interface{}
|
|
|
}
|
|
|
|
|
|
-func (r *rec) set(f string, x interface{}) {
|
|
|
- panic(0)
|
|
|
+func (r *rec) setField(f string, x interface{}) { r.set(scope.ID{Name: f}, x) }
|
|
|
+
|
|
|
+func (r *rec) getField(f string) interface{} { return r.get(scope.ID{Name: f}) }
|
|
|
+
|
|
|
+func (r *rec) init(n node.Node) {
|
|
|
+ r.root = n
|
|
|
+ r.x = make(map[scope.ID]interface{})
|
|
|
}
|
|
|
|
|
|
-func (r *rec) get(f string) interface{} { return nil }
|
|
|
+func (a *rec) set(k scope.ID, v interface{}) { fmt.Println(k); a.x[k] = v }
|
|
|
|
|
|
-func (r *rec) init(h *area) { r.heap = h }
|
|
|
+func (a *rec) get(k scope.ID) interface{} { fmt.Println(k); return a.x[k] }
|
|
|
|
|
|
func nm() scope.Manager {
|
|
|
m := &manager{areas: list.New()}
|
|
@@ -104,8 +135,9 @@ func design(n node.Node) (id scope.ID) {
|
|
|
case node.VariableNode, node.ParameterNode:
|
|
|
id = scope.ID{Name: x.Object().Name()}
|
|
|
case node.FieldNode:
|
|
|
- panic(0)
|
|
|
- //id = scope.ID{Name: x.Left().Object().Name(), Field: x.Object().Name()}
|
|
|
+ id = scope.ID{Name: x.Left().Object().Name(), Path: [scope.DEPTH]string{x.Object().Name()}}
|
|
|
+ case node.IndexNode:
|
|
|
+ id = scope.ID{Name: x.Left().Object().Name()}
|
|
|
default:
|
|
|
panic(fmt.Sprintln("unsupported", reflect.TypeOf(n)))
|
|
|
}
|
|
@@ -153,22 +185,21 @@ func obj(o object.Object) (key scope.ID, val interface{}) {
|
|
|
}
|
|
|
|
|
|
func (m *manager) Allocate(n node.Node, final bool) {
|
|
|
- h := &area{ready: final, root: n, data: make(map[scope.ID]interface{})}
|
|
|
+ h := &area{ready: final, root: n, x: make(map[scope.ID]interface{})}
|
|
|
mod := rt_mod.DomainModule(m.Domain())
|
|
|
- var alloc func(h *area, o object.Object)
|
|
|
- alloc = func(h *area, o object.Object) {
|
|
|
+ var alloc func(h KVarea, o object.Object)
|
|
|
+ alloc = func(h KVarea, o object.Object) {
|
|
|
if k, v := obj(o); v != nil {
|
|
|
- h.data[k] = v
|
|
|
- switch rec := v.(type) {
|
|
|
+ h.set(k, v)
|
|
|
+ switch rv := v.(type) {
|
|
|
case record:
|
|
|
- hh := &area{ready: final, root: n, data: make(map[scope.ID]interface{})}
|
|
|
- rec.init(hh)
|
|
|
+ rv.init(n)
|
|
|
switch t := o.Complex().(type) {
|
|
|
case object.RecordType:
|
|
|
for rec := t; rec != nil; {
|
|
|
for x := rec.Link(); x != nil; x = x.Link() {
|
|
|
fmt.Println(o.Name(), ".", x.Name())
|
|
|
- alloc(hh, x)
|
|
|
+ alloc(v.(KVarea), x)
|
|
|
}
|
|
|
if rec.Base() != "" {
|
|
|
rec = mod.TypeByName(n, rec.Base()).(object.RecordType)
|
|
@@ -210,7 +241,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
|
|
|
})
|
|
|
case object.ParameterObject:
|
|
|
k, v := scope.ID{Name: next.Name()}, &basic{link: o}
|
|
|
- h.data[k] = v
|
|
|
+ h.set(k, v)
|
|
|
m.Update(odesign(next), func(old interface{}) interface{} {
|
|
|
return ov.Data()
|
|
|
})
|
|
@@ -224,7 +255,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
|
|
|
return m.Select(odesign(ov.Object()))
|
|
|
})
|
|
|
case object.ParameterObject:
|
|
|
- h.data[scope.ID{Name: next.Name()}].(*ref).ref = design(ov)
|
|
|
+ h.get(scope.ID{Name: next.Name()}).(*ref).ref = design(ov)
|
|
|
}
|
|
|
default:
|
|
|
panic("unknown value")
|
|
@@ -244,30 +275,53 @@ func (m *manager) Dispose(n node.Node) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (m *manager) Select(i scope.ID) (ret interface{}) {
|
|
|
+func (m *manager) Select(i scope.ID) interface{} {
|
|
|
fmt.Println("select", i)
|
|
|
- for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
|
|
|
+ depth := 0
|
|
|
+ type result struct {
|
|
|
+ x interface{}
|
|
|
+ }
|
|
|
+ var res *result
|
|
|
+ var sel func(interface{}) *result
|
|
|
+
|
|
|
+ sel = func(x interface{}) (ret *result) {
|
|
|
+ switch x := x.(type) {
|
|
|
+ case value:
|
|
|
+ ret = &result{x: x.get()}
|
|
|
+ case reference:
|
|
|
+ i = x.id()
|
|
|
+ ret = nil
|
|
|
+ case array:
|
|
|
+ if i.Index != nil {
|
|
|
+ ret = &result{x: x.get(*i.Index)}
|
|
|
+ } else {
|
|
|
+ ret = &result{x: x.sel()}
|
|
|
+ }
|
|
|
+ case record:
|
|
|
+ if i.Path[depth] == "" {
|
|
|
+ ret = &result{x: x.(*rec).link}
|
|
|
+ } else {
|
|
|
+ z := x.getField(i.Path[depth])
|
|
|
+ depth++
|
|
|
+ ret = sel(z)
|
|
|
+ }
|
|
|
+ case nil:
|
|
|
+ //do nothing
|
|
|
+ default:
|
|
|
+ panic(0)
|
|
|
+ }
|
|
|
+ return ret
|
|
|
+ }
|
|
|
+ for e := m.areas.Front(); (e != nil) && (res == nil); e = e.Next() {
|
|
|
h := e.Value.(*area)
|
|
|
if h.ready {
|
|
|
- ret = h.data[i]
|
|
|
- switch x := ret.(type) {
|
|
|
- case value:
|
|
|
- ret = x.get()
|
|
|
- case reference:
|
|
|
- i = x.id()
|
|
|
- ret = nil
|
|
|
- case array:
|
|
|
- ret = x.sel()
|
|
|
- case nil:
|
|
|
- //do nothing
|
|
|
- default:
|
|
|
- panic(0)
|
|
|
- }
|
|
|
+ depth = 0
|
|
|
+ res = sel(h.get(i))
|
|
|
}
|
|
|
}
|
|
|
- // assert.For(ret != nil, 40)
|
|
|
- fmt.Println(ret)
|
|
|
- return ret
|
|
|
+ assert.For(res != nil, 40)
|
|
|
+ fmt.Println(res.x)
|
|
|
+ return res.x
|
|
|
}
|
|
|
|
|
|
func arrConv(x interface{}) []interface{} {
|
|
@@ -290,9 +344,9 @@ func (m *manager) Update(i scope.ID, val scope.ValueFor) {
|
|
|
assert.For(val != nil, 21)
|
|
|
var x interface{}
|
|
|
fmt.Println("update", i)
|
|
|
- for e := m.areas.Front(); (e != nil) && (x == nil); e = e.Next() {
|
|
|
- h := e.Value.(*area)
|
|
|
- x = h.data[i]
|
|
|
+ depth := 0
|
|
|
+ var upd func(x interface{}) (ret interface{})
|
|
|
+ upd = func(x interface{}) (ret interface{}) {
|
|
|
switch x := x.(type) {
|
|
|
case value:
|
|
|
old := x.get()
|
|
@@ -300,22 +354,46 @@ func (m *manager) Update(i scope.ID, val scope.ValueFor) {
|
|
|
assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
|
|
|
fmt.Println(tmp)
|
|
|
x.set(tmp)
|
|
|
+ ret = x
|
|
|
case reference:
|
|
|
- i = x.id()
|
|
|
- x = nil
|
|
|
+ i.Name = x.id().Name
|
|
|
+ ret = nil
|
|
|
case array:
|
|
|
- old := x.sel()
|
|
|
- tmp := val(old)
|
|
|
- assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
|
|
|
- fmt.Println(tmp)
|
|
|
- x.upd(arrConv(tmp))
|
|
|
+ if i.Index != nil {
|
|
|
+ old := x.get(*i.Index)
|
|
|
+ tmp := val(old)
|
|
|
+ assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
|
|
|
+ fmt.Println(tmp)
|
|
|
+ x.set(*i.Index, tmp)
|
|
|
+ } else {
|
|
|
+ old := x.sel()
|
|
|
+ tmp := val(old)
|
|
|
+ assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
|
|
|
+ fmt.Println(tmp)
|
|
|
+ x.upd(arrConv(tmp))
|
|
|
+ }
|
|
|
+ ret = x
|
|
|
case record:
|
|
|
-
|
|
|
+ if i.Path[depth] == "" {
|
|
|
+ fmt.Println(i, depth)
|
|
|
+ panic(0) //случай выбора всей записи целиком
|
|
|
+ } else {
|
|
|
+ z := x.getField(i.Path[depth])
|
|
|
+ depth++
|
|
|
+ ret = upd(z)
|
|
|
+ }
|
|
|
case nil:
|
|
|
//do nothing
|
|
|
+ ret = x
|
|
|
default:
|
|
|
panic(fmt.Sprintln("unhandled", reflect.TypeOf(x)))
|
|
|
}
|
|
|
+ return ret
|
|
|
+ }
|
|
|
+ for e := m.areas.Front(); (e != nil) && (x == nil); e = e.Next() {
|
|
|
+ h := e.Value.(*area)
|
|
|
+ depth = 0
|
|
|
+ x = upd(h.get(i))
|
|
|
}
|
|
|
assert.For(x != nil, 40)
|
|
|
}
|
|
@@ -331,7 +409,7 @@ func FindObjByName(mgr scope.Manager, name string) (ret object.Object) {
|
|
|
m := mgr.(*manager)
|
|
|
for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
|
|
|
h := e.Value.(*area)
|
|
|
- x := h.data[scope.ID{Name: name}]
|
|
|
+ x := h.get(scope.ID{Name: name})
|
|
|
switch x.(type) {
|
|
|
case *basic:
|
|
|
ret = x.(*basic).link
|