Forráskód Böngészése

сделал NEW, теперь надо разыменование допиливать

kpmy 10 éve
szülő
commit
d81bd05a8a
7 módosított fájl, 118 hozzáadás és 52 törlés
  1. BIN
      code/XevDemo19.oz
  2. 2 1
      rt2/rules/assign.go
  3. 1 1
      rt2/rules/deref.go
  4. 7 5
      rt2/scope/area.go
  5. 46 3
      rt2/scope/std/heap.go
  6. 61 41
      rt2/scope/std/scope.go
  7. 1 1
      utils/debug.go

BIN
code/XevDemo19.oz


+ 2 - 1
rt2/rules/assign.go

@@ -170,8 +170,9 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			}))
 		} else {
 			fmt.Println("NEW here")
+			sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 			heap := scope.This(f.Domain().Discover(context.HEAP))
-			heap.Target().(scope.HeapAllocator).Allocate(a.Left())
+			sc.Update(scope.Designator(a.Left()), heap.Target().(scope.HeapAllocator).Allocate(a.Left()))
 			return frame.End()
 		}
 	default:

+ 1 - 1
rt2/rules/deref.go

@@ -13,9 +13,9 @@ import (
 func derefSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	n := rt2.NodeOf(f)
 	sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
+	fmt.Println("deref from ptr", n.(node.DerefNode).Ptr())
 	data := sc.Select(scope.Designator(n.Left()))
 	assert.For(data != nil, 40)
-	fmt.Println("deref from ptr", n.(node.DerefNode).Ptr())
 	rt2.DataOf(f.Parent())[n] = data
 	return frame.End()
 }

+ 7 - 5
rt2/scope/area.go

@@ -8,23 +8,25 @@ import (
 	"strconv"
 )
 
-const DEPTH = 16
-
 type ID struct {
 	Name  string
-	Path  [DEPTH]string
+	Path  string
 	Index *int64
+	Ref   *int
 }
 
 func (i ID) String() string {
 	if i.Name != "" {
 		ret := i.Name
-		if i.Path[0] != "" {
-			ret = ret + "." + i.Path[0]
+		if i.Path != "" {
+			ret = ret + "." + i.Path
 		}
 		if i.Index != nil {
 			ret = ret + "[" + strconv.FormatInt(*i.Index, 10) + "]"
 		}
+		if i.Ref != nil {
+			ret = ret + strconv.Itoa(*i.Ref)
+		}
 		return ret
 	} else {
 		return "<empty id>"

+ 46 - 3
rt2/scope/std/heap.go

@@ -7,12 +7,13 @@ import (
 	"fw/rt2/context"
 	"fw/rt2/scope"
 	"reflect"
+	"ypk/assert"
 )
 
 type heap struct {
 	d    context.Domain
 	data *area
-	next int64
+	next int
 }
 
 func nh() scope.Manager {
@@ -24,7 +25,23 @@ func (h *heap) Allocate(n node.Node) scope.ValueFor {
 	case node.VariableNode:
 		switch t := v.Object().Complex().(type) {
 		case object.PointerType:
-
+			h.next++
+			switch bt := t.Base().(type) {
+			case object.RecordType:
+				fake := object.New(object.VARIABLE)
+				fake.SetComplex(bt)
+				fake.SetType(object.COMPLEX)
+				r := &rec{link: fake}
+				id := scope.ID{Name: "@"}
+				id.Ref = new(int)
+				*id.Ref = h.next
+				alloc(nil, h.data, id, r)
+				return func(interface{}) interface{} {
+					return id
+				}
+			default:
+				panic(fmt.Sprintln("cannot allocate", reflect.TypeOf(t)))
+			}
 		default:
 			panic(fmt.Sprintln("unsupported type", reflect.TypeOf(t)))
 		}
@@ -42,7 +59,33 @@ func (h *heap) Target(...scope.Allocator) scope.Allocator {
 
 func (h *heap) Update(i scope.ID, val scope.ValueFor) {}
 
-func (h *heap) Select(i scope.ID) interface{} { return nil }
+func (h *heap) Select(i scope.ID) interface{} {
+	fmt.Println("heap select", i)
+	type result struct {
+		x interface{}
+	}
+	var res *result
+	var sel func(interface{}) *result
+	sel = func(x interface{}) (ret *result) {
+		fmt.Println(x)
+		switch x := x.(type) {
+		case record:
+			if i.Path == "" {
+				ret = &result{x: x.(*rec).link}
+			} else {
+				z := x.getField(i.Path)
+				ret = sel(z)
+			}
+		default:
+			panic(0)
+		}
+		return ret
+	}
+	res = sel(h.data.get(i))
+	assert.For(res != nil, 40)
+	//fmt.Println(res.x)
+	return res.x
+}
 
 func (h *heap) Init(d context.Domain) { h.d = d }
 

+ 61 - 41
rt2/scope/std/scope.go

@@ -51,7 +51,7 @@ type value interface {
 }
 
 type reference interface {
-	id() scope.ID
+	id(...scope.ID) scope.ID
 }
 
 type array interface {
@@ -81,7 +81,14 @@ type ref struct {
 	ref  scope.ID
 }
 
-func (r *ref) id() scope.ID { return r.ref }
+func (r *ref) id(x ...scope.ID) scope.ID {
+	if len(x) == 1 {
+		r.ref = x[0]
+	} else if len(x) > 1 {
+		panic("there can be only one")
+	}
+	return r.ref
+}
 
 type arr struct {
 	link object.Object
@@ -144,10 +151,11 @@ func design(n ...node.Node) (id scope.ID) {
 	case node.VariableNode, node.ParameterNode:
 		id = scope.ID{Name: x.Object().Name()}
 	case node.FieldNode:
+		fmt.Println(x.Object().Name())
 		if len(n) == 1 {
-			id = scope.ID{Name: x.Left().Object().Name(), Path: [scope.DEPTH]string{x.Object().Name()}}
+			id = scope.ID{Name: x.Left().Object().Name(), Path: x.Object().Name()}
 		} else if n[1] != nil {
-			id = scope.ID{Name: n[1].Object().Name(), Path: [scope.DEPTH]string{x.Object().Name()}}
+			id = scope.ID{Name: n[1].Object().Name(), Path: x.Object().Name()}
 		} else {
 			panic("wrong params")
 		}
@@ -187,7 +195,7 @@ func obj(o object.Object) (key scope.ID, val interface{}) {
 		case object.RecordType:
 			val = &rec{link: o}
 		case object.PointerType:
-			val = &ref{link: o}
+			val = &ref{link: o, ref: scope.ID{Ref: new(int)}}
 		default:
 			fmt.Println("unexpected", reflect.TypeOf(t))
 		}
@@ -201,25 +209,23 @@ func obj(o object.Object) (key scope.ID, val interface{}) {
 	return key, val
 }
 
-func alloc(root node.Node, h KVarea, o object.Object) {
-	if k, v := obj(o); v != nil {
-		h.set(k, v)
-		switch rv := v.(type) {
-		case record:
-			rv.init(root)
-			switch t := o.Complex().(type) {
-			case object.RecordType:
-				for rec := t; rec != nil; {
-					for x := rec.Link(); x != nil; x = x.Link() {
-						//fmt.Println(o.Name(), ".", x.Name())
-						alloc(root, v.(KVarea), x)
-					}
-					rec = rec.BaseType()
+func alloc(root node.Node, h KVarea, k scope.ID, v interface{}) {
+	h.set(k, v)
+	switch rv := v.(type) {
+	case record:
+		rv.init(root)
+		o := rv.(*rec).link
+		switch t := o.Complex().(type) {
+		case object.RecordType:
+			for rec := t; rec != nil; {
+				for x := rec.Link(); x != nil; x = x.Link() {
+					//fmt.Println(o.Name(), ".", x.Name())
+					k, f := obj(x)
+					alloc(root, v.(KVarea), k, f)
 				}
+				rec = rec.BaseType()
 			}
 		}
-	} else {
-		//fmt.Println("nil allocated", reflect.TypeOf(o))
 	}
 }
 
@@ -232,10 +238,12 @@ func (m *manager) Allocate(n node.Node, final bool) {
 	runtime.SetFinalizer(h, area_fin)
 	mod := rt_mod.DomainModule(m.Domain())
 	for _, o := range mod.Objects[n] {
-		alloc(n, h, o)
+		k, v := obj(o)
+		//fmt.Println(k, v)
+		alloc(n, h, k, v)
 	}
 	m.areas.PushFront(h)
-	//fmt.Println("allocate")
+	fmt.Println("allocate")
 }
 
 func (m *manager) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence, ret frame.WAIT) {
@@ -245,7 +253,7 @@ func (m *manager) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence,
 	assert.For(h.root == n, 21)
 	assert.For(!h.ready, 22)
 	val := par.Values
-	//fmt.Println("initialize")
+	fmt.Println("initialize")
 	f := par.Frame
 	end := func(frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		h.ready = true
@@ -289,8 +297,8 @@ func (m *manager) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence,
 		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()
+				//fmt.Println(rt2.DataOf(f)[ov])
+				return end, frame.NOW
 			}
 			ret = frame.LATER
 		default:
@@ -312,20 +320,19 @@ func (m *manager) Dispose(n node.Node) {
 }
 
 func (m *manager) Select(i scope.ID) interface{} {
-	//fmt.Println("select", i)
-	depth := 0
 	type result struct {
 		x interface{}
 	}
 	var res *result
 	var sel func(interface{}) *result
-
+	fmt.Println(i)
 	sel = func(x interface{}) (ret *result) {
 		switch x := x.(type) {
 		case value:
 			ret = &result{x: x.get()}
 		case reference:
 			i = x.id()
+			fmt.Println("ref!", i)
 			ret = nil
 		case array:
 			if i.Index != nil {
@@ -334,15 +341,21 @@ func (m *manager) Select(i scope.ID) interface{} {
 				ret = &result{x: x.sel()}
 			}
 		case record:
-			if i.Path[depth] == "" {
+			if i.Path == "" {
 				ret = &result{x: x.(*rec).link}
 			} else {
-				z := x.getField(i.Path[depth])
-				depth++
+				z := x.getField(i.Path)
 				ret = sel(z)
 			}
 		case nil:
-			//do nothing
+			if i.Name == "@" {
+				fmt.Println("ptr")
+				if hm := m.Domain().Discover(context.HEAP).(scope.Manager); hm != nil {
+					ret = &result{x: hm.Select(i)}
+				} else {
+					panic(0)
+				}
+			}
 		default:
 			panic(0)
 		}
@@ -351,7 +364,6 @@ func (m *manager) Select(i scope.ID) interface{} {
 	for e := m.areas.Front(); (e != nil) && (res == nil); e = e.Next() {
 		h := e.Value.(*area)
 		if h.ready {
-			depth = 0
 			res = sel(h.get(i))
 		}
 	}
@@ -382,7 +394,6 @@ func arrConv(x interface{}) []interface{} {
 func (m *manager) Update(i scope.ID, val scope.ValueFor) {
 	assert.For(val != nil, 21)
 	var x interface{}
-	depth := 0
 	var upd func(x interface{}) (ret interface{})
 	upd = func(x interface{}) (ret interface{}) {
 		switch x := x.(type) {
@@ -394,8 +405,19 @@ func (m *manager) Update(i scope.ID, val scope.ValueFor) {
 			x.set(tmp)
 			ret = x
 		case reference:
-			i.Name = x.id().Name
-			ret = nil
+			if x.id().Ref != nil && *x.id().Ref == 0 { //это нулевой указатель
+				tmp := val(nil)
+				ret = x
+				switch id := tmp.(type) {
+				case scope.ID:
+					x.id(id)
+				default:
+					panic("only id for nil pointer")
+				}
+			} else { //это параметр процедуры
+				i.Name = x.id().Name
+				ret = nil
+			}
 		case array:
 			if i.Index != nil {
 				old := x.get(*i.Index)
@@ -412,12 +434,11 @@ func (m *manager) Update(i scope.ID, val scope.ValueFor) {
 			}
 			ret = x
 		case record:
-			if i.Path[depth] == "" {
+			if i.Path == "" {
 				//fmt.Println(i, depth)
 				panic(0) //случай выбора всей записи целиком
 			} else {
-				z := x.getField(i.Path[depth])
-				depth++
+				z := x.getField(i.Path)
 				ret = upd(z)
 			}
 		case nil:
@@ -430,7 +451,6 @@ func (m *manager) Update(i scope.ID, val scope.ValueFor) {
 	}
 	for e := m.areas.Front(); (e != nil) && (x == nil); e = e.Next() {
 		h := e.Value.(*area)
-		depth = 0
 		x = upd(h.get(i))
 	}
 	assert.For(x != nil, 40)

+ 1 - 1
utils/debug.go

@@ -2,7 +2,7 @@ package utils
 
 import "fmt"
 
-var debugFrame = false
+var debugFrame = true
 var debugScope = true
 var debugTrap = true