Преглед изворни кода

уточнен переход в секцию CLOSE
улучшена работа с параметрами процедуры, теперь данные точно уходят в параменную

p.kushnir пре 10 година
родитељ
комит
9e96c6dffa
7 измењених фајлова са 115 додато и 69 уклоњено
  1. 5 2
      cp/object/object.go
  2. 1 0
      fw/XevDemo3.oxf
  3. 2 2
      fw/fw.go
  4. 45 0
      rt2/rules/enter.go
  5. 1 35
      rt2/rules/table.go
  6. 2 2
      rt2/scope/area.go
  7. 59 28
      rt2/scope/stdScope.go

+ 5 - 2
cp/object/object.go

@@ -36,7 +36,7 @@ type Object interface {
 
 type VariableObject interface {
 	Object
-	This() VariableObject
+	self() VariableObject
 }
 
 type ConstantObject interface {
@@ -47,6 +47,7 @@ type ConstantObject interface {
 
 type ParameterObject interface {
 	Object
+	self() ParameterObject
 }
 
 func New(mode Mode) Object {
@@ -91,7 +92,7 @@ type localProcedureObject struct {
 	objectFields
 }
 
-func (v *variableObject) This() VariableObject { return v }
+func (v *variableObject) self() VariableObject { return v }
 
 type constantObject struct {
 	objectFields
@@ -108,6 +109,8 @@ type parameterObject struct {
 	objectFields
 }
 
+func (v *parameterObject) self() ParameterObject { return v }
+
 func (t Type) String() string {
 	switch t {
 	case NOTYPE:

Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
fw/XevDemo3.oxf


+ 2 - 2
fw/fw.go

@@ -15,12 +15,12 @@ func main() {
 	global := new(stdDomain)
 	modList := module.New()
 	global.ConnectTo(context.MOD, modList)
-	ret, err := modList.Load("XevDemo2")
+	ret, err := modList.Load("XevDemo3")
 	assert.For(ret != nil, 40)
 	assert.For(err == nil, 41)
 	{
 		domain := new(stdDomain)
-		global.ConnectTo("XevDemo2", domain)
+		global.ConnectTo("XevDemo3", domain)
 		root := frame.NewRoot()
 		domain.ConnectTo(context.STACK, root)
 		domain.ConnectTo(context.SCOPE, scope.New())

+ 45 - 0
rt2/rules/enter.go

@@ -0,0 +1,45 @@
+package rules
+
+import (
+	"cp/node"
+	"rt2/context"
+	"rt2/frame"
+	"rt2/nodeframe"
+	"rt2/scope"
+	"ypk/assert"
+)
+
+func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	var fu nodeframe.FrameUtils
+	n := fu.NodeOf(f)
+	body := fu.NodeOf(f).Right()
+	assert.For(body != nil, 40)
+	sm := scope.This(f.Domain().Discover(context.SCOPE))
+	sm.Allocate(n)
+	if n.Object() != nil {
+		par, ok := fu.DataOf(f)[n.Object()].(node.Node)
+		if ok {
+			sm.Initialize(n, n.Object().Link(), par)
+		}
+	}
+	if f.Parent() != nil {
+		//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя
+		fu.Push(fu.New(body), f.Parent())
+		return frame.Tail(frame.STOP), frame.SKIP
+	} 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.SKIP
+			}
+		} else {
+			seq = frame.Tail(frame.STOP)
+		}
+		return seq, frame.SKIP
+
+	}
+}

+ 1 - 35
rt2/rules/table.go

@@ -10,47 +10,13 @@ import (
 	"rt2/frame"
 	"rt2/nodeframe"
 	"rt2/scope"
-	"ypk/assert"
 )
 
 func prologue(n node.Node) frame.Sequence {
-	var fu nodeframe.FrameUtils
 	//fmt.Println(reflect.TypeOf(n))
 	switch n.(type) {
 	case node.EnterNode:
-		return func(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)
-			if n.Object() != nil {
-				par, ok := fu.DataOf(f)[n.Object()].(node.Node)
-				if ok {
-					sm.Initialize(n, n.Object().Link(), par)
-				}
-			}
-			if f.Parent() != nil {
-				//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя
-				fu.Push(fu.New(body), f.Parent())
-			} else {
-				//Особый случай, вход в модуль
-				fu.Push(fu.New(body), f)
-			}
-			next := n.Link()
-			if next != nil {
-				seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
-					if f.Parent() != nil {
-						f.Root().PushFor(fu.New(next), f.Parent())
-					} else {
-						f.Root().PushFor(fu.New(next), f)
-					}
-					return frame.Tail(frame.STOP), frame.SKIP
-				}
-				return seq, frame.SKIP
-			} else {
-				return frame.Tail(frame.STOP), frame.SKIP
-			}
-		}
+		return enterSeq
 	case node.AssignNode:
 		return assignSeq
 	case node.OperationNode:

+ 2 - 2
rt2/scope/area.go

@@ -9,7 +9,7 @@ import (
 //менеджер зон видимости, зоны видимости динамические, создаются в момент входа в EnterNode
 type Manager interface {
 	context.ContextAware
-	Update(o object.Object, val Value)
+	Update(o object.Object, val ValueFor)
 	Select(o object.Object) interface{}
 	Allocate(n node.Node)
 	Dispose(n node.Node)
@@ -17,4 +17,4 @@ type Manager interface {
 }
 
 //средство обновления значения
-type Value func(in interface{}) (out interface{})
+type ValueFor func(in interface{}) (out interface{})

+ 59 - 28
rt2/scope/stdScope.go

@@ -26,15 +26,50 @@ type manager struct {
 }
 
 type area struct {
-	heap map[object.Object]interface{}
+	heap map[object.Object]value
 	root node.Node
 }
 
-type undefined struct{}
-type param struct{}
+type value interface {
+	Set(x interface{})
+	Get() interface{}
+}
+
+type direct struct {
+	value
+	data interface{}
+}
+
+type indirect struct {
+	value
+	ref object.Object
+	mgr Manager
+}
+
+type dummy struct{}
 
-var undef *undefined = new(undefined)
-var par *param = new(param)
+var def *dummy = &dummy{}
+
+func (v *direct) Set(x interface{}) {
+	assert.For(x != nil, 20)
+	v.data = x
+	fmt.Println("set", x, reflect.TypeOf(x))
+}
+
+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.Update(v.ref, func(old interface{}) interface{} {
+		return x
+	})
+}
+
+func (v *indirect) Get() interface{} {
+	assert.For(v.ref != nil, 20)
+	return v.mgr.Select(v.ref)
+}
 
 func (m *manager) init() *manager {
 	m.areas = list.New()
@@ -44,15 +79,15 @@ func (m *manager) init() *manager {
 func (m *manager) Allocate(n node.Node) {
 	mod := rt_mod.DomainModule(m.Domain())
 	h := new(area)
-	h.heap = make(map[object.Object]interface{})
+	h.heap = make(map[object.Object]value)
 	h.root = n
 	for _, o := range mod.Objects[n] {
 		//fmt.Println(reflect.TypeOf(o))
 		switch o.(type) {
 		case object.VariableObject:
-			h.heap[o] = undef
+			h.heap[o] = &direct{data: def}
 		case object.ParameterObject:
-			h.heap[o] = par
+			h.heap[o] = &indirect{mgr: m}
 		}
 	}
 	m.areas.PushFront(h)
@@ -66,9 +101,14 @@ func (m *manager) set(a *area, o object.Object, val node.Node) {
 			return val.(node.ConstantNode).Data()
 		})
 	case node.VariableNode, node.ParameterNode:
-		m.Update(o, func(old interface{}) interface{} {
-			return m.Select(val.Object())
-		})
+		switch o.(type) {
+		case object.VariableObject:
+			m.Update(o, func(old interface{}) interface{} {
+				return m.Select(val.Object())
+			})
+		case object.ParameterObject:
+			a.heap[o].(*indirect).ref = val.Object()
+		}
 	default:
 		panic("unknown value")
 	}
@@ -80,6 +120,7 @@ func (m *manager) Initialize(n node.Node, o object.Object, _val node.Node) {
 	h := e.Value.(*area)
 	assert.For(h.root == n, 21)
 	val := _val
+	fmt.Println("initialize")
 	for next := o; next != nil; next = next.Link() {
 		assert.For(val != nil, 40)
 		fmt.Println(reflect.TypeOf(next), next.Name(), ":", next.Type())
@@ -105,15 +146,10 @@ func (m *manager) Select(o object.Object) (ret interface{}) {
 		ret = h.heap[o]
 	}
 	assert.For(ret != nil, 40)
-	if ret == undef {
-		ret = nil
-	} else if ret == par {
-		panic("")
-	}
-	return ret
+	return ret.(value).Get()
 }
 
-func (m *manager) Update(o object.Object, val Value) {
+func (m *manager) Update(o object.Object, val ValueFor) {
 	assert.For(o != nil, 20)
 	assert.For(val != nil, 21)
 	var x *area
@@ -124,18 +160,13 @@ func (m *manager) Update(o object.Object, val Value) {
 		}
 	}
 	assert.For(x != nil, 40)
-	tmp := x.heap[o]
-	if tmp == undef {
-		tmp = val(nil)
-	} else {
-		tmp = val(tmp)
+	old := x.heap[o].Get()
+	if old == def {
+		old = nil
 	}
+	tmp := val(old)
 	assert.For(tmp != nil, 40) //если устанавливают значение NIL, значит делают что-то неверно
-	if tmp == nil {
-		tmp = undef
-	}
-	x.heap[o] = tmp
-	fmt.Println("set", x.heap[o], reflect.TypeOf(x.heap[o]))
+	x.heap[o].Set(tmp)
 }
 
 func (m *manager) Init(d context.Domain) {

Неке датотеке нису приказане због велике количине промена