Browse Source

перевел scope менеджер на адресацию по имени, нужно для адресации полей рекордов

kpmy 10 years ago
parent
commit
f35c5d4cab
10 changed files with 136 additions and 66 deletions
  1. 1 1
      cp/node/class.go
  2. 28 0
      cp/object/object.go
  3. 6 6
      rt2/rules/assign.go
  4. 2 2
      rt2/rules/call.go
  5. 4 1
      rt2/rules/deref.go
  6. 6 3
      rt2/rules/enter.go
  7. 3 3
      rt2/rules/op.go
  8. 1 1
      rt2/rules/return.go
  9. 7 6
      rt2/scope/area.go
  10. 78 43
      rt2/scope/stdScope.go

+ 1 - 1
cp/node/class.go

@@ -71,7 +71,7 @@ func (nf *nodeFields) SetRight(n Node) { nf.right = n }
 
 func (nf *nodeFields) SetLink(n Node) { nf.link = n }
 
-func (nf *nodeFields) SetObject(o object.Object) { nf.obj = o }
+func (nf *nodeFields) SetObject(o object.Object) { nf.obj = o; o.SetRef(nf) }
 
 func (nf *nodeFields) Left() Node { return nf.left }
 

+ 28 - 0
cp/object/object.go

@@ -1,5 +1,9 @@
 package object
 
+import (
+	"ypk/assert"
+)
+
 type Mode int
 
 const (
@@ -21,6 +25,12 @@ type Object interface {
 	Link() Object
 	SetLink(o Object)
 	Name() string
+	SetRef(n Ref)
+	Ref() []Ref
+}
+
+type Ref interface {
+	Object() Object
 }
 
 type VariableObject interface {
@@ -75,6 +85,7 @@ type objectFields struct {
 	typ  Type
 	link Object
 	comp ComplexType
+	ref  []Ref
 }
 
 func (of *objectFields) SetType(typ Type)         { of.typ = typ }
@@ -86,6 +97,23 @@ func (of *objectFields) SetLink(o Object)         { of.link = o }
 func (of *objectFields) SetComplex(t ComplexType) { of.comp = t }
 func (of *objectFields) Complex() ComplexType     { return of.comp }
 
+func (of *objectFields) SetRef(n Ref) {
+	assert.For(n != nil, 20)
+	exists := func() bool {
+		for _, v := range of.ref {
+			if v == n {
+				return true
+			}
+		}
+		return false
+	}
+	if !exists() {
+		of.ref = append(of.ref, n)
+	}
+}
+
+func (of *objectFields) Ref() []Ref { return of.ref }
+
 type variableObject struct {
 	objectFields
 }

+ 6 - 6
rt2/rules/assign.go

@@ -23,7 +23,7 @@ func incSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	rt2.Utils.Push(rt2.Utils.New(op), f)
 	seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-		sc.UpdateObj(n.Left().Object(), func(interface{}) interface{} {
+		sc.Update(scope.Id(n.Left().Object()), func(interface{}) interface{} {
 			return rt2.Utils.DataOf(f)[op]
 		})
 		return frame.End()
@@ -41,7 +41,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.ConstantNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				sc.UpdateObj(a.Left().Object(), func(interface{}) interface{} {
+				sc.Update(scope.Id(a.Left().Object()), func(interface{}) interface{} {
 					return a.Right().(node.ConstantNode).Data()
 				})
 				return frame.End()
@@ -50,8 +50,8 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.VariableNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				sc.UpdateObj(a.Left().Object(), func(interface{}) interface{} {
-					return sc.SelectObj(a.Right().Object())
+				sc.Update(scope.Id(a.Left().Object()), func(interface{}) interface{} {
+					return sc.Select(scope.Id(a.Right().Object()))
 				})
 				return frame.End()
 			}
@@ -60,7 +60,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			fu.Push(fu.New(a.Right()), f)
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				sc.UpdateObj(a.Left().Object(), func(interface{}) interface{} {
+				sc.Update(scope.Id(a.Left().Object()), func(interface{}) interface{} {
 					return fu.DataOf(f)[a.Right()]
 				})
 				return frame.End()
@@ -68,7 +68,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			ret = frame.LATER
 		case node.ProcedureNode:
 			sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-			sc.UpdateObj(a.Left().Object(), func(interface{}) interface{} {
+			sc.Update(scope.Id(a.Left().Object()), func(interface{}) interface{} {
 				return a.Right().Object()
 			})
 			return frame.End()

+ 2 - 2
rt2/rules/call.go

@@ -57,7 +57,7 @@ func process(f frame.Frame, par node.Node) {
 			switch msg.Type {
 			case "log":
 				fmt.Println(msg.Data)
-				callHandler(f, sm.FindObjByName("go_handler"), `{"type":"log"}`)
+				callHandler(f, scope.FindObjByName(sm, "go_handler"), `{"type":"log"}`)
 			default:
 				panic(40)
 			}
@@ -107,7 +107,7 @@ func callSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	case node.VariableNode:
 		m := mod.DomainModule(f.Domain())
 		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-		obj := sc.SelectObj(n.Left().Object())
+		obj := sc.Select(scope.Id(n.Left().Object()))
 
 		if obj, ok := obj.(object.Object); ok {
 			proc := m.NodeByObject(obj)

+ 4 - 1
rt2/rules/deref.go

@@ -5,11 +5,14 @@ import (
 	"fw/rt2/context"
 	"fw/rt2/frame"
 	"fw/rt2/scope"
+	"ypk/assert"
 )
 
 func derefSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	n := rt2.Utils.NodeOf(f)
 	sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-	rt2.Utils.DataOf(f.Parent())[n] = sc.SelectObj(n.Left().Object())
+	data := sc.Select(scope.Id(n.Left().Object()))
+	assert.For(data != nil, 40)
+	rt2.Utils.DataOf(f.Parent())[n] = data
 	return frame.End()
 }

+ 6 - 3
rt2/rules/enter.go

@@ -1,7 +1,6 @@
 package rules
 
 import (
-	"fmt"
 	"fw/cp/node"
 	"fw/rt2/context"
 	"fw/rt2/frame"
@@ -16,15 +15,19 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	body := fu.NodeOf(f).Right()
 	assert.For(body != nil, 40)
 	sm := scope.This(f.Domain().Discover(context.SCOPE))
-	sm.Allocate(n)
-	fmt.Println(n.Object())
+	//fmt.Println(n.Object())
 	if n.Object() != nil {
 		par, ok := fu.DataOf(f)[n.Object()].(node.Node)
 		//fmt.Println(fu.DataOf(f)[n.Object()])
 		//fmt.Println(ok)
 		if ok {
+			sm.Allocate(n, false)
 			sm.Initialize(n, n.Object().Link(), par)
+		} else {
+			sm.Allocate(n, true)
 		}
+	} else {
+		sm.Allocate(n, true)
 	}
 	if f.Parent() != nil {
 		//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя

+ 3 - 3
rt2/rules/op.go

@@ -108,7 +108,7 @@ func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 		switch n.Left().(type) {
 		case node.VariableNode, node.ParameterNode:
-			x := sc.SelectObj(n.Left().Object())
+			x := sc.Select(scope.Id(n.Left().Object()))
 			assert.For(x != nil, 40)
 			switch n.Type() {
 			case object.INTEGER:
@@ -170,7 +170,7 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.VariableNode, node.ParameterNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				fu.DataOf(f)[n.Right()] = sc.SelectObj(n.Right().Object())
+				fu.DataOf(f)[n.Right()] = sc.Select(scope.Id(n.Right().Object()))
 				//fmt.Println(n.Right().Object(), reflect.TypeOf(n.Right().Object()))
 				assert.For(fu.DataOf(f)[n.Right()] != nil, 60)
 				return op, frame.NOW
@@ -199,7 +199,7 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.VariableNode, node.ParameterNode, node.FieldNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				fu.DataOf(f)[n.Left()] = sc.SelectObj(n.Left().Object())
+				fu.DataOf(f)[n.Left()] = sc.Select(scope.Id(n.Left().Object()))
 				return right, frame.NOW
 			}
 			ret = frame.NOW

+ 1 - 1
rt2/rules/return.go

@@ -25,7 +25,7 @@ func returnSeq(f frame.Frame) (frame.Sequence, frame.WAIT) {
 		case node.VariableNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-				fu.DataOf(f.Parent())[a.Object()] = sc.SelectObj(a.Left().Object())
+				fu.DataOf(f.Parent())[a.Object()] = sc.Select(scope.Id(a.Left().Object()))
 				return frame.End()
 			}
 			ret = frame.NOW

+ 7 - 6
rt2/scope/area.go

@@ -9,12 +9,13 @@ import (
 //менеджер зон видимости, зоны видимости динамические, создаются в момент входа в EnterNode
 type Manager interface {
 	context.ContextAware
-	UpdateObj(o object.Object, val ValueFor)
-	SelectObj(o object.Object) interface{}
-	UpdateNode(n node.Node, val ValueFor)
-	SelectNode(n node.Node) interface{}
-	FindObjByName(name string) object.Object
-	Allocate(n node.Node)
+	//	UpdateObj(o object.Object, val ValueFor)
+	//	SelectObj(o object.Object) interface{}
+	//UpdateNode(n node.Node, val ValueFor)
+	//SelectNode(n node.Node) interface{}
+	Update(id string, val ValueFor)
+	Select(id string) interface{}
+	Allocate(n node.Node, final bool)
 	Dispose(n node.Node)
 	Initialize(n node.Node, o object.Object, val node.Node)
 }

+ 78 - 43
rt2/scope/stdScope.go

@@ -8,10 +8,27 @@ import (
 	"fw/rt2/context"
 	rt_mod "fw/rt2/module"
 	"fw/utils"
+	"math/rand"
 	"reflect"
+	"strconv"
 	"ypk/assert"
 )
 
+func Id(of interface{}) (ret string) {
+	assert.For(of != nil, 20)
+	switch of.(type) {
+	case object.Object:
+		fmt.Println("id", of.(object.Object).Name(), reflect.TypeOf(of))
+		//panic("fuck objects, use nodes")
+		ret = of.(object.Object).Name()
+	default:
+		fmt.Println(reflect.TypeOf(of))
+		panic("cannot identify")
+	}
+	assert.For(ret != "", 60)
+	return ret
+}
+
 func This(i interface{}) Manager {
 	assert.For(i != nil, 20)
 	return i.(Manager)
@@ -24,11 +41,16 @@ func New() Manager {
 type manager struct {
 	d     context.Domain
 	areas *list.List
+	opts  struct {
+		startFromArea *area
+	}
 }
 
 type area struct {
-	heap map[object.Object]value
-	root node.Node
+	heap  map[string]value
+	cache map[string]object.Object
+	root  node.Node
+	ready bool
 }
 
 type value interface {
@@ -43,12 +65,19 @@ type direct struct {
 
 type indirect struct {
 	value
-	ref object.Object
-	mgr Manager
+	ref  object.Object
+	mgr  *manager
+	area *area
 }
 
+// маскирует объект-параметр
 type mask struct {
 	object.Object
+	id int
+}
+
+func nextMask() int {
+	return rand.Int()
 }
 
 type dummy struct{}
@@ -66,14 +95,20 @@ func (v *direct) Get() interface{} { return v.data }
 func (v *indirect) Set(x interface{}) {
 	assert.For(x != nil, 20)
 	assert.For(v.ref != nil, 21)
-	v.mgr.UpdateObj(v.ref, func(old interface{}) interface{} {
+	v.mgr.Update(Id(v.ref), func(old interface{}) interface{} {
 		return x
 	})
 }
 
-func (v *indirect) Get() interface{} {
+func (v *indirect) Get() (ret interface{}) {
 	assert.For(v.ref != nil, 20)
-	return v.mgr.SelectObj(v.ref)
+	_, ok := v.ref.(*mask)
+	if !ok {
+		v.mgr.opts.startFromArea = v.area
+	}
+	ret = v.mgr.Select(Id(v.ref))
+	v.mgr.opts.startFromArea = nil
+	return ret
 }
 
 func (m *manager) init() *manager {
@@ -81,10 +116,12 @@ func (m *manager) init() *manager {
 	return m
 }
 
-func (m *manager) Allocate(n node.Node) {
+func (m *manager) Allocate(n node.Node, final bool) {
 	mod := rt_mod.DomainModule(m.Domain())
 	h := new(area)
-	h.heap = make(map[object.Object]value)
+	h.ready = final
+	h.heap = make(map[string]value)
+	h.cache = make(map[string]object.Object)
 	h.root = n
 	for _, o := range mod.Objects[n] {
 		//fmt.Println(reflect.TypeOf(o))
@@ -105,13 +142,16 @@ func (m *manager) Allocate(n node.Node) {
 						}
 					}
 				default:
-					h.heap[o] = &direct{data: def}
+					h.heap[Id(o)] = &direct{data: def}
+					h.cache[Id(o)] = o
 				}
 			default:
-				h.heap[o] = &direct{data: def}
+				h.heap[Id(o)] = &direct{data: def}
+				h.cache[Id(o)] = o
 			}
 		case object.ParameterObject:
-			h.heap[o] = &indirect{mgr: m}
+			h.heap[Id(o)] = &indirect{mgr: m, area: h}
+			h.cache[Id(o)] = o
 		default:
 			fmt.Println("wrong object type", reflect.TypeOf(o))
 		}
@@ -125,25 +165,26 @@ func (m *manager) set(a *area, o object.Object, val node.Node) {
 	case node.ConstantNode:
 		switch o.(type) {
 		case object.VariableObject:
-			m.UpdateObj(o, func(old interface{}) interface{} {
+			m.Update(Id(o), func(old interface{}) interface{} {
 				return val.(node.ConstantNode).Data()
 			})
 		case object.ParameterObject:
-			assert.For(a.heap[o].(*indirect).ref == nil, 40)
-			m := &mask{}
-			a.heap[o].(*indirect).ref = m
-			a.heap[m] = &direct{data: val.(node.ConstantNode).Data()}
+			assert.For(a.heap[Id(o)].(*indirect).ref == nil, 40)
+			m := &mask{id: nextMask()}
+			a.heap[Id(o)].(*indirect).ref = m
+			a.heap[Id(m)] = &direct{data: val.(node.ConstantNode).Data()}
 		default:
 			panic("unknown value")
 		}
-	case node.VariableNode, node.ParameterNode, node.FieldNode:
+	case node.VariableNode, node.ParameterNode:
 		switch o.(type) {
 		case object.VariableObject:
-			m.UpdateObj(o, func(old interface{}) interface{} {
-				return m.SelectObj(val.Object())
+			m.Update(Id(o), func(old interface{}) interface{} {
+				return m.Select(Id(val.Object()))
 			})
 		case object.ParameterObject:
-			a.heap[o].(*indirect).ref = val.Object()
+			a.heap[Id(o)].(*indirect).ref = val.Object()
+			fmt.Println(val.Object())
 		}
 	default:
 		panic("unknown value")
@@ -155,6 +196,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 	assert.For(e != nil, 20)
 	h := e.Value.(*area)
 	assert.For(h.root == n, 21)
+	assert.For(!h.ready, 22)
 	val := _val
 	fmt.Println("initialize")
 	for next := o; next != nil; next = next.Link() {
@@ -164,6 +206,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 		m.set(h, next, val)
 		val = val.Link()
 	}
+	h.ready = true
 }
 
 func (m *manager) Dispose(n node.Node) {
@@ -175,24 +218,23 @@ func (m *manager) Dispose(n node.Node) {
 	fmt.Println("dispose")
 }
 
-func (m *manager) FindObjByName(name string) (ret object.Object) {
+func FindObjByName(mgr Manager, name string) (ret object.Object) {
 	assert.For(name != "", 20)
+	m := mgr.(*manager)
 	for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
 		h := e.Value.(*area)
-		for k, _ := range h.heap {
-			if k.Name() == name {
-				ret = k
-			}
-		}
+		ret = h.cache[name]
 	}
 	return ret
 }
 
-func (m *manager) SelectObj(o object.Object) (ret interface{}) {
-	assert.For(o != nil, 20)
+func (m *manager) Select(id string) (ret interface{}) {
+	assert.For(id != "", 20)
 	for e := m.areas.Front(); (e != nil) && (ret == nil); e = e.Next() {
 		h := e.Value.(*area)
-		ret = h.heap[o]
+		if (h != m.opts.startFromArea) && h.ready {
+			ret = h.heap[id]
+		}
 	}
 	assert.For(ret != nil, 40)
 	ret = ret.(value).Get()
@@ -202,33 +244,26 @@ func (m *manager) SelectObj(o object.Object) (ret interface{}) {
 	return ret
 }
 
-func (m *manager) UpdateObj(o object.Object, val ValueFor) {
-	assert.For(o != nil, 20)
+func (m *manager) Update(id string, val ValueFor) {
+	assert.For(id != "", 20)
 	assert.For(val != nil, 21)
 	var x *area
 	for e := m.areas.Front(); (e != nil) && (x == nil); e = e.Next() {
 		h := e.Value.(*area)
-		if h.heap[o] != nil {
+		if h.heap[id] != nil {
 			x = h
 		}
 	}
 	assert.For(x != nil, 40)
-	old := x.heap[o].Get()
+	old := x.heap[id].Get()
 	if old == def {
 		old = nil
 	}
 	tmp := val(old)
 	assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
-	x.heap[o].Set(tmp)
+	x.heap[id].Set(tmp)
 }
 
-func (m *manager) SelectNode(n node.Node) interface{} {
-	return nil
-}
-
-func (m *manager) UpdateNode(n node.Node, val ValueFor) {
-
-}
 func (m *manager) Init(d context.Domain) {
 	m.d = d
 }
@@ -239,4 +274,4 @@ func (m *manager) Domain() context.Domain {
 
 func (m *manager) Handle(msg interface{}) {}
 
-func (m *mask) Name() string { return "" }
+func (m *mask) Name() string { return strconv.Itoa(m.id) }