ソースを参照

выработал решение для создания ссылки-параметра
постепенно подбираюсь к прежней функциональности фреймворка

kpmy 10 年 前
コミット
8090f650f3

+ 2 - 0
domain.go

@@ -39,6 +39,8 @@ func (d *stdDomain) Discover(name string) (ret context.ContextAware) {
 			ret = d.global.Discover(name)
 		case name == context.SCOPE && !d.god:
 			ret = d.global.Discover(name)
+		case name == context.CALL && !d.god:
+			ret = d.global.Discover(name)
 		}
 	}
 	assert.For(ret != nil, 60) //все плохо

+ 3 - 2
fw.go

@@ -36,8 +36,8 @@ func main() {
 	flag.Parse()
 	utils.Debug(debug)
 	if name == "" {
-		name = "XevDemo1"
-		utils.Debug(true)
+		name = "XevDemo7"
+		utils.Debug(false)
 	}
 	global := &stdDomain{god: true}
 	global.global = global
@@ -46,6 +46,7 @@ func main() {
 	global.Attach(context.DIGEST, context.Data(cp.Init()))
 	global.Attach(context.HEAP, scope.New(context.HEAP))
 	global.Attach(context.SCOPE, scope.New(context.SCOPE))
+	global.Attach(context.CALL, scope.New(context.CALL))
 	t0 := time.Now()
 	var init []*cpm.Module
 	_, err := modList.Load(name, func(m *cpm.Module) {

+ 11 - 10
rt2/context/ctx.go

@@ -1,16 +1,17 @@
 package context
 
 const (
-	STACK    = "fw/rt2/frame"
-	SCOPE    = "fw/rt2/scope"
-	MOD      = "fw/rt2/module"
-	UNIVERSE = "fw/rt2/ctx"
-	HEAP     = "fw/rt2/scope,heap"
-	MT       = "fw/rt2/table,flow"
-	DIGEST   = "fw/cp"
-
-	RETURN = "RETURN"
-	KEY    = "KEY"
+	UNIVERSE = "ctx"
+	STACK    = "stack"
+	MOD      = "mt"
+	MT       = "flow"
+	DIGEST   = "cp"
+	HEAP     = "heap"
+	SCOPE    = "mod"
+	CALL     = "call"
+	RETURN   = "return"
+	KEY      = "key"
+	META     = "meta"
 )
 
 type Factory interface {

+ 62 - 2
rt2/rules2/wrap/data/items/items.go

@@ -38,7 +38,13 @@ type Item interface {
 type Data interface {
 	Set(Key, Item)
 	Get(Key, ...Opts) Item
+
 	Hold(Key)
+	Link(Key, ID)
+	Put(Key, Item)
+
+	Exists(Key) bool
+	ForEach(func(Value) bool)
 	Begin()
 	End()
 	Drop()
@@ -74,6 +80,11 @@ func (d *data) find(k Key, from *list.Element) (ret Value, elem *list.Element) {
 	return
 }
 
+func (d *data) Exists(k Key) bool {
+	r, _ := d.find(k, nil)
+	return r != nil
+}
+
 func (d *data) Set(k Key, v Item) {
 	assert.For(v != nil, 20)
 	assert.For(v.KeyOf() == nil, 21)
@@ -86,6 +97,16 @@ func (d *data) Set(k Key, v Item) {
 	}
 }
 
+func (d *data) ForEach(f func(Value) bool) {
+	ok := false
+	for x := d.x.Front(); x != nil && !ok; {
+		if v, da := x.Value.(Value); da {
+			ok = f(v)
+		}
+		x = x.Next()
+	}
+}
+
 func (d *data) Get(k Key, opts ...Opts) (ret Item) {
 	if len(opts) == 0 {
 		d.check()
@@ -119,6 +140,43 @@ func (d *data) Hold(key Key) {
 	d.x.PushFront(&dummy{k: key})
 }
 
+func (d *data) Link(key Key, to ID) {
+	assert.For(key != nil, 20)
+	var this *list.Element
+	for x := d.x.Front(); x != nil && this == nil; {
+		if _, ok := x.Value.(*dummy); ok {
+			this = x
+		}
+		x = x.Next()
+		if x != nil {
+			if _, ok := x.Value.(*limit); ok {
+				x = nil
+			}
+		}
+	}
+	assert.For(this != nil, 60)
+	this.Value = &link{k: key, id: to}
+}
+
+func (d *data) Put(key Key, item Item) {
+	assert.For(key != nil, 20)
+	var this *list.Element
+	for x := d.x.Front(); x != nil && this == nil; {
+		if _, ok := x.Value.(*dummy); ok {
+			this = x
+		}
+		x = x.Next()
+		if x != nil {
+			if _, ok := x.Value.(*limit); ok {
+				x = nil
+			}
+		}
+	}
+	assert.For(this != nil, 60)
+	this.Value = item
+	item.KeyOf(key)
+}
+
 type link struct {
 	k  Key
 	id ID
@@ -178,8 +236,10 @@ func (d *data) Drop() {
 	for x := d.x.Front(); x != nil; {
 		d.x.Remove(x)
 		x = d.x.Front()
-		if _, ok := x.Value.(*limit); ok {
-			x = nil
+		if x != nil {
+			if _, ok := x.Value.(*limit); ok {
+				x = nil
+			}
 		}
 	}
 }

+ 65 - 10
rt2/rules2/wrap/data/stack.go

@@ -79,6 +79,11 @@ func (a *area) Select(this cp.ID, val scope.ValueOf) {
 	val(d.Value())
 }
 
+func (a *area) Exists(this cp.ID) bool {
+	utils.PrintScope("SEARCH", this)
+	return a.il.Exists(&key{id: this})
+}
+
 func (a *salloc) push(_o object.Object) {
 	switch o := _o.(type) {
 	case object.VariableObject:
@@ -88,6 +93,11 @@ func (a *salloc) push(_o object.Object) {
 			d := &item{}
 			d.Data(x)
 			a.area.il.Set(&key{id: o.Adr()}, d)
+		case object.ArrayType, object.DynArrayType:
+			x := newData(o)
+			d := &item{}
+			d.Data(x)
+			a.area.il.Set(&key{id: o.Adr()}, d)
 		default:
 			halt.As(100, reflect.TypeOf(t))
 		}
@@ -142,7 +152,7 @@ func (a *salloc) Allocate(n node.Node, final bool) {
 	a.area.il.Begin()
 	for _, o := range ol {
 		if skip[o.Adr()] == nil {
-			fmt.Println(o.Adr(), o.Name())
+			utils.PrintScope(o.Adr(), o.Name())
 			a.push(o)
 		}
 	}
@@ -158,13 +168,13 @@ func (a *salloc) Dispose(n node.Node) {
 func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object, tail eval.Do, in eval.IN) eval.Do {
 	utils.PrintScope("INITIALIZE")
 	const link = "initialize:par"
-	end := func(eval.IN) eval.OUT {
+	end := func(in eval.IN) eval.OUT {
 		a.area.il.End()
 		return eval.Later(tail)
 	}
 	var next eval.Do
 	do := func(val node.Node, par object.Object) (out eval.OUT) {
-		fmt.Println(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
+		utils.PrintScope(par.Adr(), par.Name(), ":=", reflect.TypeOf(val))
 		out = eval.Now(next)
 		switch par.(type) {
 		case object.VariableObject:
@@ -178,9 +188,27 @@ func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object,
 		case object.ParameterObject:
 			switch val.(type) {
 			case node.Designator:
-				fmt.Println("design")
-			case node.Expression:
-				fmt.Println("expr")
+				out = eval.GetDesignator(in, link, val, func(in eval.IN) eval.OUT {
+					mt := rt2.RegOf(in.Frame)[context.META].(*eval.Meta)
+					fa := mt.Scope.(*area).il
+					a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
+					return eval.Later(next)
+				})
+			case node.Expression: //array заменяем ссылку на переменную
+				out = eval.GetExpression(in, link, val, func(in eval.IN) eval.OUT {
+					d := &item{}
+					data := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
+					switch data.(type) {
+					case STRING, SHORTSTRING:
+						val := &dynarr{link: par}
+						val.Set(data)
+						d.Data(val)
+					default:
+						halt.As(100, reflect.TypeOf(data))
+					}
+					a.area.il.Put(&key{id: par.Adr()}, d)
+					return eval.Later(next)
+				})
 			default:
 				halt.As(100, reflect.TypeOf(val))
 			}
@@ -249,17 +277,44 @@ func (a *area) Domain() context.Domain { return a.d }
 func (a *area) Handle(msg interface{}) {}
 
 func nn(role string) scope.Manager {
-	if role == context.SCOPE {
+	switch role {
+	case context.SCOPE, context.CALL:
 		return &area{all: &salloc{}, il: items.New()}
-	} else if role == context.HEAP {
+	case context.HEAP:
 		return &area{all: nil}
 		//return &area{all: &halloc{}}
-	} else {
+	default:
 		panic(0)
 	}
 }
 
+func fn(mgr scope.Manager, name string) (ret object.Object) {
+	utils.PrintScope("FIND", name)
+	a, ok := mgr.(*area)
+	assert.For(ok, 20)
+	assert.For(name != "", 21)
+	a.il.ForEach(func(in items.Value) (ok bool) {
+		var v scope.Value
+		switch val := in.(type) {
+		case *item:
+			v = val.Value()
+		}
+		switch vv := v.(type) {
+		case *data:
+			utils.PrintScope(vv.link.Name())
+			if vv.link.Name() == name {
+				ret = vv.link
+				ok = true
+			}
+		default:
+			utils.PrintScope(reflect.TypeOf(vv))
+		}
+		return
+	})
+	return ret
+}
+
 func init() {
 	scope.New = nn
-	//scope.FindObjByName = fn
+	scope.FindObjByName = fn
 }

+ 2 - 0
rt2/rules2/wrap/data/val.go

@@ -772,6 +772,8 @@ func gfrom(v scope.Value) interface{} {
 		return bool(n)
 	case STRING:
 		return string(n)
+	case SHORTSTRING:
+		return string(n)
 	case CHAR:
 		return rune(n)
 	default:

+ 2 - 2
rt2/rules2/wrap/eval/call.go

@@ -46,7 +46,7 @@ func callHandler(f frame.Frame, obj object.Object, data interface{}) {
 
 func go_process(in IN, par node.Node) OUT {
 	assert.For(par != nil, 20)
-	sm := rt2.ThisScope(in.Frame)
+	sm := rt2.CallScope(in.Frame)
 	do := func(val string) {
 		if val != "" {
 			msg := &Msg{}
@@ -86,7 +86,7 @@ func go_math(in IN, par node.Node) OUT {
 		EXP  = 3.0
 	)
 	assert.For(par != nil, 20)
-	sm := rt2.ThisScope(in.Frame)
+	sm := rt2.CallScope(in.Frame)
 	res := math.NaN()
 	switch p := par.(type) {
 	case node.VariableNode:

+ 5 - 2
rt2/rules2/wrap/eval/do.go

@@ -104,9 +104,12 @@ func GetDesignator(in IN, key interface{}, design node.Node, next Do) OUT {
 	rt2.Push(nf, in.Frame)
 	rt2.RegOf(in.Frame)[context.KEY] = key
 	rt2.RegOf(in.Frame)[key] = nil
+	rt2.RegOf(in.Frame)[context.META] = nil
 	rt2.Assert(in.Frame, func(f frame.Frame, do frame.Condition) {
 		v := rt2.RegOf(f)[key]
-		do(v != nil, 1957, key)
+		m := rt2.RegOf(f)[context.META]
+		do(v != nil, 1957, " no data for ", key)
+		do(m != nil, 1480, " no meta")
 	})
 	return Later(func(IN) OUT {
 		return Now(next)
@@ -190,7 +193,7 @@ func EndStatement(in IN) (out OUT) {
 	case node.EnterNode:
 		out = Now(func(in IN) OUT {
 			if n.Enter() == enter.PROCEDURE {
-				rt2.ThisScope(in.Frame).Target().(scope.ScopeAllocator).Dispose(n)
+				rt2.CallScope(in.Frame).Target().(scope.ScopeAllocator).Dispose(n)
 			}
 			if in.Parent != nil {
 				par := rt2.RegOf(in.Parent)

+ 13 - 3
rt2/rules2/wrap/eval/expr.go

@@ -7,6 +7,7 @@ import (
 	"fw/cp/object"
 	"fw/cp/traps"
 	"fw/rt2"
+	"fw/rt2/context"
 	"fw/rt2/scope"
 	"math/big"
 	"reflect"
@@ -16,7 +17,7 @@ import (
 
 func getConst(in IN) OUT {
 	c := in.IR.(node.ConstantNode)
-	sc := rt2.ThisScope(in.Frame)
+	sc := rt2.ModScope(in.Frame)
 	fn := sc.Provide(c)
 	assert.For(fn != nil, 40)
 	rt2.ValueOf(in.Parent)[c.Adr()] = fn
@@ -26,10 +27,11 @@ func getConst(in IN) OUT {
 
 func getVar(in IN) OUT {
 	v := in.IR.(node.VariableNode)
-	rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
+	sc := rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
 		rt2.ValueOf(in.Parent)[v.Adr()] = val
 		rt2.RegOf(in.Parent)[in.Key] = v.Adr()
 	})
+	rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: sc, Id: v.Object().Adr()}
 	return End()
 }
 
@@ -38,6 +40,7 @@ func getVarPar(in IN) OUT {
 	rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
 		rt2.ValueOf(in.Parent)[v.Adr()] = val
 		rt2.RegOf(in.Parent)[in.Key] = v.Adr()
+		rt2.RegOf(in.Parent)[context.META] = &Meta{}
 	})
 	return End()
 }
@@ -52,6 +55,7 @@ func getField(in IN) OUT {
 			fld := v.Get(f.Object().Adr())
 			rt2.ValueOf(in.Parent)[f.Adr()] = fld
 			rt2.RegOf(in.Parent)[in.Key] = f.Adr()
+			rt2.RegOf(in.Parent)[context.META] = &Meta{}
 			return End()
 		default:
 			halt.As(100, reflect.TypeOf(v))
@@ -76,6 +80,7 @@ func getIndex(in IN) OUT {
 			case scope.Array:
 				rt2.ValueOf(in.Parent)[i.Adr()] = a.Get(idx)
 				rt2.RegOf(in.Parent)[in.Key] = i.Adr()
+				rt2.RegOf(in.Parent)[context.META] = &Meta{}
 				return End()
 			default:
 				halt.As(100, reflect.TypeOf(a))
@@ -87,11 +92,12 @@ func getIndex(in IN) OUT {
 
 func getProc(in IN) OUT {
 	p := in.IR.(node.ProcedureNode)
-	sc := rt2.ThisScope(in.Frame)
+	sc := rt2.ModScope(in.Frame)
 	fn := sc.Provide(p.Object())
 	assert.For(fn != nil, 40)
 	rt2.ValueOf(in.Parent)[p.Adr()] = fn
 	rt2.RegOf(in.Parent)[in.Key] = p.Adr()
+	rt2.RegOf(in.Parent)[context.META] = &Meta{}
 	return End()
 }
 
@@ -109,11 +115,13 @@ func getDeref(in IN) OUT {
 				assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
 				rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
 				rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+				rt2.RegOf(in.Parent)[context.META] = &Meta{}
 				return End()
 			case object.DynArrayType:
 				assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
 				rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
 				rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+				rt2.RegOf(in.Parent)[context.META] = &Meta{}
 				return End()
 			default:
 				halt.As(100, t, reflect.TypeOf(cc))
@@ -123,6 +131,7 @@ func getDeref(in IN) OUT {
 			rec := v.Get()
 			rt2.ValueOf(in.Parent)[d.Adr()] = rec
 			rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+			rt2.RegOf(in.Parent)[context.META] = &Meta{}
 			if scope.GoTypeFrom(rec) == nil {
 				out = makeTrap(in.Frame, traps.NILderef)
 			} else {
@@ -281,6 +290,7 @@ func getGuard(in IN) OUT {
 		if scope.GoTypeFrom(scope.Ops.Is(v, g.Type())).(bool) {
 			rt2.ValueOf(in.Parent)[g.Adr()] = v
 			rt2.RegOf(in.Parent)[in.Key] = g.Adr()
+			rt2.RegOf(in.Parent)[context.META] = &Meta{}
 			return End()
 		} else {
 			return makeTrap(in.Frame, 0)

+ 15 - 5
rt2/rules2/wrap/eval/stmt.go

@@ -3,6 +3,7 @@ package eval
 import (
 	"fw/cp"
 	"fw/cp/constant"
+	"fw/cp/constant/enter"
 	"fw/cp/constant/operation"
 	"fw/cp/constant/statement"
 	"fw/cp/node"
@@ -56,7 +57,13 @@ func doEnter(in IN) OUT {
 		}
 		return
 	}
-	sm := rt2.ThisScope(in.Frame)
+	var sm scope.Manager
+	switch e.Enter() {
+	case enter.MODULE:
+		sm = rt2.ModScope(in.Frame)
+	case enter.PROCEDURE:
+		sm = rt2.CallScope(in.Frame)
+	}
 	if e.Object() != nil { //параметры процедуры
 		par, ok := rt2.RegOf(in.Frame)[e.Object()].(node.Node)
 		//fmt.Println(rt2.DataOf(f)[n.Object()])
@@ -344,10 +351,13 @@ func doCall(in IN) (out OUT) {
 						val = rv
 					}
 				}
-				assert.For(val != nil, 40, in.Key, rt2.RegOf(in.Frame), rt2.ValueOf(in.Frame), rt2.RegOf(in.Parent), rt2.ValueOf(in.Parent))
-				id := cp.ID(cp.Some())
-				rt2.ValueOf(in.Parent)[id] = val
-				rt2.RegOf(in.Parent)[in.Key] = id
+				if val != nil {
+					id := cp.ID(cp.Some())
+					rt2.ValueOf(in.Parent)[id] = val
+					rt2.RegOf(in.Parent)[in.Key] = id
+				} else {
+					utils.PrintFrame("possibly no return", in.Key, rt2.RegOf(in.Frame), rt2.ValueOf(in.Frame), rt2.RegOf(in.Parent), rt2.ValueOf(in.Parent))
+				}
 			}
 			return End()
 		})

+ 7 - 0
rt2/rules2/wrap/eval/utils.go

@@ -3,6 +3,7 @@ package eval
 import (
 	"fw/cp"
 	"fw/rt2"
+	"fw/rt2/context"
 	"ypk/assert"
 )
 
@@ -11,3 +12,9 @@ func KeyOf(in IN, key interface{}) cp.ID {
 	assert.For(ok, 40)
 	return id
 }
+
+func MetaOf(in IN) (ret *Meta) {
+	ret, ok := rt2.RegOf(in.Frame)[context.META].(*Meta)
+	assert.For(ok, 60)
+	return
+}

+ 7 - 0
rt2/rules2/wrap/eval/x.go

@@ -1,8 +1,10 @@
 package eval
 
 import (
+	"fw/cp"
 	"fw/cp/node"
 	"fw/rt2/frame"
+	"fw/rt2/scope"
 )
 
 type WAIT int
@@ -16,6 +18,11 @@ const (
 	END
 )
 
+type Meta struct {
+	Id    cp.ID
+	Scope scope.Manager
+}
+
 var Propose func(Do) frame.Sequence
 var Expose func(frame.Sequence) Do
 

+ 1 - 0
rt2/scope/area.go

@@ -23,6 +23,7 @@ type Manager interface {
 	Target(...Allocator) Allocator
 	Provide(interface{}) Value
 	String() string
+	Exists(cp.ID) bool
 }
 
 type Allocator interface {

+ 20 - 2
rt2/utils.go

@@ -19,12 +19,30 @@ func NodeOf(f frame.Frame) node.Node                  { return utils.NodeOf(f) }
 func Push(f, p frame.Frame)                           { utils.Push(f, p) }
 func New(n node.Node) frame.Frame                     { return utils.New(n) }
 
-func ThisScope(f frame.Frame) scope.Manager {
+func CallScope(f frame.Frame) scope.Manager {
+	return f.Domain().Discover(context.CALL).(scope.Manager)
+}
+
+func ModScope(f frame.Frame) scope.Manager {
 	return f.Domain().Discover(context.SCOPE).(scope.Manager)
 }
 
+func Heap(f frame.Frame) scope.Manager {
+	return f.Domain().Discover(context.HEAP).(scope.Manager)
+}
+
 func ScopeFor(f frame.Frame, id cp.ID, fn ...scope.ValueOf) (ret scope.Manager) {
-	ret = f.Domain().Global().Discover(context.SCOPE).(scope.Manager)
+	mr := f.Domain().Global().Discover(context.SCOPE).(scope.Manager)
+	cr := f.Domain().Global().Discover(context.CALL).(scope.Manager)
+	hr := f.Domain().Global().Discover(context.HEAP).(scope.Manager)
+	switch {
+	case mr.Exists(id):
+		ret = mr
+	case cr.Exists(id):
+		ret = cr
+	case hr.Exists(id):
+		ret = hr
+	}
 	assert.For(ret != nil, 60, id)
 	if len(fn) == 1 {
 		ret.Select(id, fn[0])