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

добрался до проблем с NEW и моделью идентификации данных, надо избавляться от поля link, все равно оно используется в основном для вывода типа данных

kpmy пре 10 година
родитељ
комит
f3f3eb3228

+ 2 - 2
fw.go

@@ -33,11 +33,11 @@ func close() {
 }
 
 func main() {
+	utils.Debug2(false, false)
 	flag.Parse()
 	utils.Debug(debug)
 	if name == "" {
-		name = "Start"
-		utils.Debug2(false, false)
+		name = "Start3"
 	}
 	global := &stdDomain{god: true}
 	global.global = global

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

@@ -158,13 +158,13 @@ func fin(x interface{}) {
 	switch p := x.(type) {
 	case *ptrValue:
 		defer func() {
-			mod := rtm.ModuleOfType(p.scope.Domain(), p.link.Complex())
+			mod := rtm.ModuleOfType(p.scope.Domain(), p.ct)
 			ol := mod.Objects[mod.Enter]
 			var fn object.ProcedureObject
 			for _, _po := range ol {
 				switch po := _po.(type) {
 				case object.ProcedureObject:
-					if po.Name() == "FINALIZE" && po.Link().Complex().Equals(p.link.Complex()) {
+					if po.Name() == "FINALIZE" && po.Link().Complex().Equals(p.ct) {
 						fn = po
 						break
 					}
@@ -190,11 +190,10 @@ func fin(x interface{}) {
 	}
 }
 
-func (h *halloc) Allocate(o object.Object, t object.PointerType, par ...interface{}) scope.Value {
+func (h *halloc) Allocate(name string, t object.PointerType, par ...interface{}) scope.Value {
 	utils.PrintScope("HEAP ALLOCATE")
 	//mod := rtm.ModuleOfType(h.area.d, t)
 	assert.For(t != nil, 20)
-	assert.For(o != nil, 21)
 	var res scope.Value
 	var talloc func(t object.PointerType)
 	talloc = func(t object.PointerType) {
@@ -203,9 +202,9 @@ func (h *halloc) Allocate(o object.Object, t object.PointerType, par ...interfac
 			fake := object.New(object.VARIABLE, cp.Some())
 			fake.SetComplex(bt)
 			fake.SetType(object.COMPLEX)
-			fake.SetName("{" + o.Name() + "}")
+			fake.SetName("{" + "}")
 			push(h.area.d, h.area.il, fake)
-			res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
+			res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
 		case object.DynArrayType:
 			assert.For(len(par) > 0, 20)
 			fake := object.New(object.VARIABLE, cp.Some())
@@ -218,7 +217,7 @@ func (h *halloc) Allocate(o object.Object, t object.PointerType, par ...interfac
 				assert.For(ok, 60)
 				arr.Set(par[0].(scope.Value))
 			})
-			res = &ptrValue{scope: h.area, id: fake.Adr(), link: o}
+			res = &ptrValue{scope: h.area, id: fake.Adr(), ct: t}
 		default:
 			halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
 		}
@@ -327,9 +326,15 @@ func (a *salloc) proper_init(root node.Node, _val node.Node, _par object.Object,
 			switch val.(type) {
 			case node.Designator:
 				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}})
+					if mt, _ := rt2.RegOf(in.Frame)[context.META].(*eval.Meta); mt != nil && mt.Scope != nil {
+						fa := mt.Scope.(*area).il
+						a.area.il.Link(&key{id: par.Adr()}, items.ID{In: fa, This: &key{id: mt.Id}})
+					} else { //поля, элементы массива, некоторые результаты разыменований
+						d := &item{}
+						v := rt2.ValueOf(in.Frame)[eval.KeyOf(in, link)]
+						d.Data(v)
+						a.area.il.Put(&key{id: par.Adr()}, d)
+					}
 					return eval.Later(next)
 				})
 			case node.Expression: //array заменяем ссылку на переменную

+ 20 - 5
rt2/rules2/wrap/data/val.go

@@ -69,7 +69,7 @@ func (i *idx) base() (object.Type, object.ComplexType) {
 	case object.ArrayType:
 		return a.Base(), a.Complex()
 	case object.DynArrayType:
-		return a.Base(), nil
+		return a.Base(), a.Complex()
 	default:
 		panic(0)
 	}
@@ -305,7 +305,7 @@ func (i *idx) Set(v scope.Value) {
 		case object.DynArrayType:
 			_, ok := tt.Complex().(object.PointerType)
 			assert.For(ok, 20)
-			i.val()[i.idx] = &ptr{link: x.link, val: x}
+			i.val()[i.idx] = &ptr{link: i.link(), val: x}
 		default:
 			halt.As(100, reflect.TypeOf(tt))
 		}
@@ -474,6 +474,18 @@ func (p *ptr) Get() (ret scope.Value) {
 	return
 }
 
+func (p *ptr) Copy() (ret scope.Pointer) {
+	fake := object.New(object.VARIABLE, cp.Some())
+	fake.SetComplex(p.link.Complex())
+	fake.SetType(object.COMPLEX)
+	fake.SetName("<" + p.link.Name() + ">")
+	push(p.val.scope.d, p.val.scope.il, fake)
+	tmp := newPtr(fake)
+	ret = tmp.(scope.Pointer)
+	ret.Set(p)
+	return
+}
+
 func newPtr(o object.Object) scope.Variable {
 	_, ok := o.Complex().(object.PointerType)
 	assert.For(ok, 20)
@@ -483,7 +495,8 @@ func newPtr(o object.Object) scope.Variable {
 type ptrValue struct {
 	scope *area
 	id    cp.ID
-	link  object.Object
+	ct    object.ComplexType
+	//link  object.Object
 }
 
 func (p *ptrValue) String() string {
@@ -1849,9 +1862,9 @@ func (o *ops) TypeOf(x scope.Value) (object.Type, object.ComplexType) {
 	case *ptr:
 		//assert.For(v.val != nil, 20, v.Id())
 		if v.val != nil {
-			return v.val.link.Type(), v.val.link.Complex()
+			return object.COMPLEX, v.val.ct
 		} else {
-			//return v.link.Type(), v.link.Complex()
+			return v.link.Type(), v.link.Complex()
 		}
 	case *rec:
 		return v.link.Type(), v.link.Complex()
@@ -1861,6 +1874,8 @@ func (o *ops) TypeOf(x scope.Value) (object.Type, object.ComplexType) {
 		return v.link.Type(), v.link.Complex()
 	case *data:
 		return v.link.Type(), v.link.Complex()
+	case *idx:
+		return v.base()
 	default:
 		halt.As(100, reflect.TypeOf(v))
 	}

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

@@ -1,6 +1,7 @@
 package eval
 
 import (
+	"fw/cp"
 	"fw/cp/constant/enter"
 	"fw/cp/node"
 	"fw/rt2"
@@ -87,6 +88,14 @@ func GetExpression(in IN, key interface{}, expr node.Node, next Do) OUT {
 	rt2.RegOf(in.Frame)[context.KEY] = key
 	rt2.RegOf(in.Frame)[key] = nil
 	rt2.Assert(in.Frame, func(f frame.Frame, do frame.Condition) {
+		if _, call := expr.(node.CallNode); call {
+			tmp := rt2.RegOf(in.Frame)[context.RETURN]
+			if tmp != nil {
+				tmp_id := cp.ID(cp.Some())
+				rt2.RegOf(in.Frame)[key] = tmp_id
+				rt2.ValueOf(in.Frame)[tmp_id] = tmp.(scope.Value)
+			}
+		}
 		v := rt2.RegOf(f)[key]
 		do(v != nil, 1961, key)
 	})
@@ -98,7 +107,8 @@ func GetExpression(in IN, key interface{}, expr node.Node, next Do) OUT {
 func GetDesignator(in IN, key interface{}, design node.Node, next Do) OUT {
 	assert.For(design != nil, 20)
 	_, ok := design.(node.Designator)
-	assert.For(ok, 21, reflect.TypeOf(design))
+	_, call := design.(node.CallNode)
+	assert.For(ok || call, 21, reflect.TypeOf(design))
 	assert.For(key != nil, 22)
 	nf := rt2.New(design)
 	rt2.Push(nf, in.Frame)
@@ -106,12 +116,25 @@ func GetDesignator(in IN, key interface{}, design node.Node, next Do) OUT {
 	rt2.RegOf(in.Frame)[key] = nil
 	rt2.RegOf(in.Frame)[context.META] = nil
 	rt2.Assert(in.Frame, func(f frame.Frame, do frame.Condition) {
+		//do(m != nil, 1480, " no meta")
+		if m := rt2.RegOf(f)[context.META]; m != nil {
+			meta := m.(*Meta)
+			if call {
+				tmp := rt2.RegOf(in.Frame)[context.RETURN]
+				assert.For(tmp != nil, 40)
+				tmp_id := cp.ID(cp.Some())
+				rt2.RegOf(in.Frame)[key] = tmp_id
+				vr := tmp.(scope.Pointer).Copy()
+				assert.For(vr != nil, 50)
+				rt2.ValueOf(in.Frame)[tmp_id] = vr
+				meta.Scope = rt2.ScopeFor(in.Frame, vr.Id())
+				meta.Id = vr.Id()
+			}
+			do(meta.Scope != nil || meta.Rec != nil || meta.Arr != nil, 1380, " wrong meta")
+		}
 		v := rt2.RegOf(f)[key]
-		m := rt2.RegOf(f)[context.META]
 		do(v != nil, 1957, " no data for ", key)
-		do(m != nil, 1480, " no meta")
-		meta := m.(*Meta)
-		do(meta.Scope != nil || meta.Rec != nil || meta.Arr != nil, 1380, " wrong meta")
+
 	})
 	return Later(func(IN) OUT {
 		return Now(next)

+ 28 - 4
rt2/rules2/wrap/eval/expr.go

@@ -8,6 +8,7 @@ import (
 	"fw/cp/traps"
 	"fw/rt2"
 	"fw/rt2/context"
+	rtm "fw/rt2/module"
 	"fw/rt2/scope"
 	"math/big"
 	"reflect"
@@ -27,11 +28,12 @@ func getConst(in IN) OUT {
 
 func getVar(in IN) OUT {
 	v := in.IR.(node.VariableNode)
-	sc := rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
+	obj := rtm.MapImportObject(in.Frame.Domain(), v.Object())
+	sc := rt2.ScopeFor(in.Frame, obj.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()}
+	rt2.RegOf(in.Parent)[context.META] = &Meta{Scope: sc, Id: obj.Adr()}
 	return End()
 }
 
@@ -116,13 +118,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{}
+				rt2.RegOf(in.Parent)[context.META] = nil
 				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{}
+				rt2.RegOf(in.Parent)[context.META] = nil
 				return End()
 			default:
 				halt.As(100, t, reflect.TypeOf(cc))
@@ -162,6 +164,28 @@ func getDeref(in IN) OUT {
 				halt.As(100, d.Adr(), d.Ptr(), v, v.Get())
 			}
 			return out
+		case scope.Index:
+			switch {
+			case scope.GoTypeFrom(v.Get()) == nil:
+				out = makeTrap(in.Frame, traps.NILderef)
+			case !d.Ptr():
+				out = End()
+				switch r := v.Get().(type) {
+				case scope.Array:
+					arr := r.(scope.Array)
+					rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(arr))
+					rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+					rt2.RegOf(in.Parent)[context.META] = &Meta{Arr: arr, Id: arr.Id()}
+				default:
+					halt.As(100, reflect.TypeOf(r))
+				}
+			}
+			return out
+		case scope.Value:
+			rt2.ValueOf(in.Parent)[d.Adr()] = v
+			rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+			rt2.RegOf(in.Parent)[context.META] = nil
+			return End()
 		default:
 			halt.As(100, reflect.TypeOf(v))
 		}

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

@@ -145,15 +145,14 @@ func doAssign(in IN) (out OUT) {
 			halt.As(100, "wrong left", reflect.TypeOf(a.Left()))
 		}
 	case statement.NEW:
-		obj := a.Left().Object()
-		assert.For(obj != nil, 20)
 		heap := in.Frame.Domain().Discover(context.HEAP).(scope.Manager).Target().(scope.HeapAllocator)
 		if a.Right() != nil {
 			out = GetExpression(in, right, a.Right(), func(in IN) OUT {
 				size := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
 				return GetDesignator(in, left, a.Left(), func(in IN) OUT {
 					v := rt2.ValueOf(in.Frame)[KeyOf(in, left)].(scope.Variable)
-					fn := heap.Allocate(obj, obj.Complex().(object.PointerType), size)
+					_, c := scope.Ops.TypeOf(v)
+					fn := heap.Allocate("new", c.(object.PointerType), size)
 					v.Set(fn)
 					return End()
 				})
@@ -161,7 +160,8 @@ func doAssign(in IN) (out OUT) {
 		} else {
 			out = GetDesignator(in, left, a.Left(), func(IN) OUT {
 				v := rt2.ValueOf(in.Frame)[KeyOf(in, left)].(scope.Variable)
-				fn := heap.Allocate(obj, obj.Complex().(object.PointerType))
+				_, c := scope.Ops.TypeOf(v)
+				fn := heap.Allocate("new", c.(object.PointerType))
 				v.Set(fn)
 				return End()
 			})
@@ -371,11 +371,12 @@ func doCall(in IN) (out OUT) {
 	case node.EnterNode:
 		call(p, nil)
 	case node.ProcedureNode:
-		m := rtm.DomainModule(in.Frame.Domain())
+		//m := rtm.DomainModule(in.Frame.Domain())
 		ml := in.Frame.Domain().Global().Discover(context.MOD).(rtm.List)
 		switch p.Object().Mode() {
 		case object.LOCAL_PROC, object.EXTERNAL_PROC:
 			if imp := p.Object().Imp(); imp == "" {
+				m := rtm.ModuleOfObject(in.Frame.Domain(), p.Object())
 				proc := m.NodeByObject(p.Object())
 				assert.For(proc != nil, 40, m.Name, imp, p.Object().Imp(), p.Object().Adr(0, 0), p.Object().Name())
 				call(proc[0], nil)

+ 1 - 1
rt2/scope/area.go

@@ -39,7 +39,7 @@ type ScopeAllocator interface {
 
 type HeapAllocator interface {
 	Allocator
-	Allocate(object.Object, object.PointerType, ...interface{}) Value //указатель лежит в скоупе процедуры/модуля, а рекорд - в куче, поэтому нужно после создания экземпляра обновить указатель
+	Allocate(string, object.PointerType, ...interface{}) Value //указатель лежит в скоупе процедуры/модуля, а рекорд - в куче, поэтому нужно после создания экземпляра обновить указатель
 	Dispose(id cp.ID)
 }
 

+ 7 - 5
rt2/scope/data.go

@@ -53,10 +53,6 @@ type Variable interface {
 	Value
 }
 
-type Ref interface {
-	Value
-}
-
 type Record interface {
 	Variable
 	Get(cp.ID) Value
@@ -70,9 +66,15 @@ type Array interface {
 type Pointer interface {
 	Variable
 	Get() Value
+	Copy() Pointer
+}
+
+type Index interface {
+	Variable
+	Get() Value
 }
 
-//средство обновления значенияxb
+//средство обновления значения
 type ValueOf func(in Value)
 
 var ValueFrom func(v Value) Value