浏览代码

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

kpmy 10 年之前
父节点
当前提交
f35c5d4cab
共有 10 个文件被更改,包括 136 次插入66 次删除
  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) }