Преглед на файлове

теперь инициализация параметров тоже может выполняться итеративно в стеке

p.kushnir преди 10 години
родител
ревизия
3b755acc3d
променени са 3 файла, в които са добавени 70 реда и са изтрити 35 реда
  1. 32 25
      rt2/rules/enter.go
  2. 10 1
      rt2/scope/area.go
  3. 28 9
      rt2/scope/std/scope.go

+ 32 - 25
rt2/rules/enter.go

@@ -12,6 +12,32 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	var fu nodeframe.FrameUtils
 	n := fu.NodeOf(f)
 	body := fu.NodeOf(f).Right()
+	tail := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		if body == nil {
+			//случай пустого тела процедуры/секции BEGIN
+			return frame.End()
+		} else if f.Parent() != nil {
+			//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя
+			fu.Push(fu.New(body), f.Parent())
+			return frame.Tail(frame.STOP), frame.LATER
+		} else {
+			//Особый случай, вход в модуль, секция BEGIN
+			fu.Push(fu.New(body), f)
+
+			//Выход из модуля, секция CLOSE
+			next := n.Link()
+			if next != nil {
+				seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+					f.Root().PushFor(fu.New(next), f)
+					return frame.Tail(frame.STOP), frame.LATER
+				}
+			} else {
+				seq = frame.Tail(frame.STOP)
+			}
+			return seq, frame.LATER
+
+		}
+	}
 	sm := scope.This(f.Domain().Discover(context.SCOPE))
 	//fmt.Println(n.Object())
 	if n.Object() != nil {
@@ -20,35 +46,16 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		//fmt.Println(ok)
 		if ok {
 			sm.Allocate(n, false)
-			sm.Initialize(n, n.Object().Link(), par)
+			seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+				return sm.Initialize(n, scope.PARAM{Objects: n.Object().Link(), Values: par, Frame: f, Tail: tail})
+			}
 		} else {
 			sm.Allocate(n, true)
+			seq = tail
 		}
 	} else {
 		sm.Allocate(n, true)
+		seq = tail
 	}
-	if body == nil {
-		//случай пустого тела процедуры/секции BEGIN
-		return frame.End()
-	} else if f.Parent() != nil {
-		//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя
-		fu.Push(fu.New(body), f.Parent())
-		return frame.Tail(frame.STOP), frame.LATER
-	} else {
-		//Особый случай, вход в модуль, секция BEGIN
-		fu.Push(fu.New(body), f)
-
-		//Выход из модуля, секция CLOSE
-		next := n.Link()
-		if next != nil {
-			seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
-				f.Root().PushFor(fu.New(next), f)
-				return frame.Tail(frame.STOP), frame.LATER
-			}
-		} else {
-			seq = frame.Tail(frame.STOP)
-		}
-		return seq, frame.LATER
-
-	}
+	return seq, frame.NOW
 }

+ 10 - 1
rt2/scope/area.go

@@ -4,6 +4,7 @@ import (
 	"fw/cp/node"
 	"fw/cp/object"
 	"fw/rt2/context"
+	"fw/rt2/frame"
 	"strconv"
 )
 
@@ -30,14 +31,22 @@ func (i ID) String() string {
 	}
 }
 
+type PARAM struct {
+	Objects object.Object
+	Values  node.Node
+	Frame   frame.Frame
+	Tail    frame.Sequence
+}
+
 //менеджер зон видимости, зоны видимости динамические, создаются в момент входа в EnterNode
+// pk, 20150112, инициализация параметров теперь происходит как и обычный frame.Sequence, с использованием стека
 type Manager interface {
 	context.ContextAware
 	Update(id ID, val ValueFor)
 	Select(id ID) interface{}
 	Allocate(n node.Node, final bool)
 	Dispose(n node.Node)
-	Initialize(n node.Node, o object.Object, val node.Node)
+	Initialize(n node.Node, par PARAM) (frame.Sequence, frame.WAIT)
 }
 
 //средство обновления значения

+ 28 - 9
rt2/scope/std/scope.go

@@ -5,7 +5,9 @@ import (
 	"fmt"
 	"fw/cp/node"
 	"fw/cp/object"
+	"fw/rt2"
 	"fw/rt2/context"
+	"fw/rt2/frame"
 	rt_mod "fw/rt2/module"
 	"fw/rt2/scope"
 	"reflect"
@@ -230,18 +232,29 @@ func (m *manager) Allocate(n node.Node, final bool) {
 	//fmt.Println("allocate")
 }
 
-func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
+func (m *manager) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence, ret frame.WAIT) {
 	e := m.areas.Front()
 	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() {
+	val := par.Values
+	fmt.Println("initialize")
+	f := par.Frame
+	end := func(frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		h.ready = true
+		if par.Tail != nil {
+			return par.Tail(f)
+		} else {
+			return frame.End()
+		}
+	}
+	seq = end
+	ret = frame.NOW
+	for next := par.Objects; next != nil; next = next.Link() {
 		assert.For(val != nil, 40)
-		//fmt.Println(reflect.TypeOf(next), next.Name(), ":", next.Type())
-		//fmt.Println(reflect.TypeOf(val))
+		fmt.Println(reflect.TypeOf(next), next.Name(), ":", next.Type())
+		fmt.Println(reflect.TypeOf(val))
 		switch ov := val.(type) {
 		case node.ConstantNode:
 			switch next.(type) {
@@ -250,7 +263,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 					return ov.Data()
 				})
 			case object.ParameterObject:
-				k, v := scope.ID{Name: next.Name()}, &basic{link: o}
+				k, v := scope.ID{Name: next.Name()}, &basic{link: next}
 				h.set(k, v)
 				m.Update(odesign(next), func(old interface{}) interface{} {
 					return ov.Data()
@@ -267,13 +280,19 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 			case object.ParameterObject:
 				h.get(scope.ID{Name: next.Name()}).(*ref).ref = design(ov)
 			}
-
+		case node.DerefNode:
+			rt2.Push(rt2.New(ov), f)
+			seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+				fmt.Println(rt2.DataOf(f)[ov])
+				return frame.End()
+			}
+			ret = frame.LATER
 		default:
 			panic(fmt.Sprintln("unknown value", reflect.TypeOf(val)))
 		}
 		val = val.Link()
 	}
-	h.ready = true
+	return seq, ret
 }
 
 func (m *manager) Dispose(n node.Node) {