Explorar el Código

демо19, указатели и куча работают

kpmy hace 10 años
padre
commit
0aecb98167
Se han modificado 9 ficheros con 147 adiciones y 224 borrados
  1. 12 7
      rt2/rules/assign.go
  2. 11 2
      rt2/rules/deref.go
  3. 1 1
      rt2/rules/expect.go
  4. 1 1
      rt2/rules/field.go
  5. 0 195
      rt2/rules/op.go
  6. 1 0
      rt2/scope/data.go
  7. 39 3
      rt2/scope/modern/hp.go
  8. 4 2
      rt2/scope/modern/ms.go
  9. 78 13
      rt2/scope/modern/val.go

+ 12 - 7
rt2/rules/assign.go

@@ -126,7 +126,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.IndexNode:
 			rt2.Push(rt2.New(a.Left()), f)
 			rt2.Assert(f, func(f frame.Frame) (bool, int) {
-				return rt2.ValueOf(f)[l.Adr()] != nil, 62
+				return rt2.ValueOf(f)[l.Adr()] != nil, 63
 			})
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
@@ -139,8 +139,12 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case node.DerefNode:
 			//			rt2.DataOf(f)[a.Left()] = scope.ID{}
 			rt2.Push(rt2.New(a.Left()), f)
+			rt2.Assert(f, func(f frame.Frame) (bool, int) {
+				ok := rt2.ValueOf(f)[l.Adr()] != nil
+				return ok, 64
+			})
 			seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
-				//				leftId = rt2.DataOf(f)[a.Left()].(scope.ID)
+				left = rt2.ValueOf(f)[a.Left().Adr()]
 				return right(f)
 			}
 			ret = frame.LATER
@@ -163,18 +167,19 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			panic(fmt.Sprintln("wrong left", reflect.TypeOf(a.Left())))
 		}
 	case statement.NEW:
-		//sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-		heap := f.Domain().Discover(context.HEAP).(scope.Manager)
+		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
+		heap := f.Domain().Discover(context.HEAP).(scope.Manager).Target().(scope.HeapAllocator)
 		if a.Right() != nil {
 			seq, ret = This(expectExpr(f, a.Right(), func(...IN) OUT {
 				fmt.Println("NEW", rt2.ValueOf(f)[a.Right().Adr()], "here")
-				//				sc.Update(scope.Designator(a.Left()), heap.Target().(scope.HeapAllocator).Allocate(a.Left(), rt2.DataOf(f)[a.Right()]))
+				fn := heap.Allocate(a.Left(), rt2.ValueOf(f)[a.Right().Adr()])
+				sc.Update(a.Left().Object().Adr(), fn)
 				return End()
 			}))
 		} else {
 			fmt.Println("NEW here")
-			heap.Target().(scope.HeapAllocator).Allocate(a.Left())
-			//sc.Update(scope.Designator(a.Left()), heap.Target().(scope.HeapAllocator).Allocate(a.Left()))
+			fn := heap.Allocate(a.Left())
+			sc.Update(a.Left().Object().Adr(), fn)
 			return frame.End()
 		}
 	default:

+ 11 - 2
rt2/rules/deref.go

@@ -10,7 +10,7 @@ import (
 	"fw/rt2/frame"
 	"fw/rt2/scope"
 	"reflect"
-	//"ypk/assert"
+	"ypk/assert"
 	"ypk/halt"
 )
 
@@ -19,7 +19,16 @@ func derefSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 	fmt.Println("deref from ptr", n.Ptr())
 	if n.Ptr() {
-		panic(0)
+		switch l := n.Left().Object().(type) {
+		case object.ParameterObject, object.VariableObject:
+			sc.Select(l.Adr(), func(v scope.Value) {
+				ptr, ok := v.(scope.Pointer)
+				assert.For(ok, 60, reflect.TypeOf(v))
+				rt2.ValueOf(f.Parent())[n.Adr()] = ptr.Get()
+			})
+		default:
+			halt.As(100, l.Adr(), reflect.TypeOf(l))
+		}
 	} else {
 		switch l := n.Left().Object().(type) {
 		case object.ParameterObject, object.VariableObject:

+ 1 - 1
rt2/rules/expect.go

@@ -16,7 +16,7 @@ func expectExpr(parent frame.Frame, expr node.Node, next Do) OUT {
 	sm := rt2.ScopeOf(parent)
 	switch e := expr.(type) {
 	case node.ConstantNode:
-		rt2.ValueOf(parent)[expr.Adr()] = sm.Provide(e.Data())(nil)
+		rt2.ValueOf(parent)[expr.Adr()] = sm.Provide(e)(nil)
 		return OUT{do: next, next: NOW}
 	case node.VariableNode, node.ParameterNode:
 		rt2.ValueOf(parent)[expr.Adr()] = sm.Select(expr.Object().Adr())

+ 1 - 1
rt2/rules/field.go

@@ -28,7 +28,7 @@ func fieldSeq(in ...IN) (out OUT) {
 			rt2.ValueOf(f.Parent())[n.Adr()] = v.(scope.Record).Get(n.Object().Adr())
 		})
 		out = End()
-	case node.FieldNode:
+	case node.FieldNode, node.DerefNode:
 		rt2.Push(rt2.New(l), f)
 		rt2.Assert(f, func(f frame.Frame) (bool, int) {
 			_, ok := rt2.ValueOf(f)[l.Adr()].(scope.Record)

+ 0 - 195
rt2/rules/op.go

@@ -4,31 +4,15 @@ import (
 	"fmt"
 	"fw/cp/constant/operation"
 	"fw/cp/node"
-	"fw/cp/object"
 	"fw/rt2"
 	"fw/rt2/context"
 	"fw/rt2/frame"
 	"fw/rt2/scope"
-	"math"
 	"math/big"
 	"reflect"
-	"strings"
 	"ypk/assert"
 )
 
-func boolOf(x interface{}) (a bool) {
-	switch x.(type) {
-	case *bool:
-		z := *x.(*bool)
-		a = z
-	case bool:
-		a = x.(bool)
-	default:
-		panic(fmt.Sprintln("unsupported type", reflect.TypeOf(x)))
-	}
-	return a
-}
-
 func int32Of(x interface{}) (a int32) {
 	//fmt.Println(reflect.TypeOf(x))
 	switch v := x.(type) {
@@ -45,185 +29,6 @@ func int32Of(x interface{}) (a int32) {
 	return a
 }
 
-func float64Of(x interface{}) (a float64) {
-	//fmt.Println(reflect.TypeOf(x))
-	switch v := x.(type) {
-	case *int32:
-		z := *x.(*int32)
-		a = float64(z)
-	case int32:
-		a = float64(x.(int32))
-	case float64:
-		a = v
-	default:
-		panic(fmt.Sprintln("unsupported type", reflect.TypeOf(x)))
-	}
-	return a
-}
-
-func div(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a / b
-}
-
-func mod(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a % b
-}
-
-func times(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a * b
-}
-
-func slash(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a float64 = float64Of(_a)
-	var b float64 = float64Of(_b)
-	return a / b
-}
-
-func ash(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a << uint(b)
-}
-
-func in(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	fmt.Println("операция IN все врет")
-	return a == b
-}
-
-func sub(_a interface{}, _b interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a - b
-}
-
-func and(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a bool = boolOf(_a)
-	var b bool = boolOf(_b)
-	return a && b
-}
-
-func or(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a bool = boolOf(_a)
-	var b bool = boolOf(_b)
-	return a || b
-}
-
-func lss(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a < b
-}
-
-func gtr(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a > b
-}
-
-func geq(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a >= b
-}
-
-func leq(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a <= b
-}
-
-func neq(_a interface{}, _b interface{}) bool {
-	assert.For(_a != nil, 20)
-	assert.For(_b != nil, 21)
-	var a int32 = int32Of(_a)
-	var b int32 = int32Of(_b)
-	return a != b
-}
-
-func not(_a interface{}) bool {
-	assert.For(_a != nil, 20)
-	var a bool = boolOf(_a)
-	return !a
-}
-
-func is(p object.Object, typ object.ComplexType) bool {
-	var compare func(x, a object.RecordType) bool
-	compare = func(x, a object.RecordType) bool {
-		switch {
-		case x.Name() == a.Name():
-			//	fmt.Println("eq")
-			return true //опасно сравнивать имена конеш
-		case x.BaseType() != nil:
-			//	fmt.Println("go base")
-			return compare(x.BaseType(), a)
-		default:
-			return false
-		}
-	}
-	x, a := p.Complex().(object.RecordType)
-	y, b := typ.(object.RecordType)
-	//fmt.Println("compare", p.Complex(), typ, a, b, a && b && compare(x, y))
-	return a && b && compare(x, y)
-}
-
-func abs(_a interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	var a int32 = int32Of(_a)
-	return int32(math.Abs(float64(a)))
-}
-
-func odd(_a interface{}) bool {
-	assert.For(_a != nil, 20)
-	var a int32 = int32Of(_a)
-	return int32(math.Abs(float64(a)))%2 == 1
-}
-
-func cap_char(_a interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	var a int32 = int32Of(_a)
-	x := []rune{rune(a), rune(0)}
-	return int32([]rune(strings.ToUpper(string(x)))[0])
-}
-
-func bits(_a interface{}) interface{} {
-	assert.For(_a != nil, 20)
-	return big.NewInt(int64(int32Of(_a)))
-}
-
 func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 	n := rt2.NodeOf(f).(node.MonadicNode)

+ 1 - 0
rt2/scope/data.go

@@ -66,6 +66,7 @@ type Array interface {
 
 type Pointer interface {
 	Variable
+	Get() Value
 }
 
 //средство обновления значенияx

+ 39 - 3
rt2/scope/modern/hp.go

@@ -3,11 +3,13 @@ package modern
 import (
 	"fmt"
 	//cpm "fw/cp/module"
+	"fw/cp"
 	"fw/cp/node"
 	"fw/cp/object"
 	rtm "fw/rt2/module"
 	"fw/rt2/scope"
 	"reflect"
+	"ypk/assert"
 	"ypk/halt"
 )
 
@@ -17,15 +19,49 @@ type halloc struct {
 
 func (h *halloc) Allocate(n node.Node, par ...interface{}) scope.ValueFor {
 	fmt.Println("HEAP ALLOCATE")
-	_ = rtm.ModuleOfNode(h.area.d, n)
+	mod := rtm.ModuleOfNode(h.area.d, n)
 	if h.area.data == nil {
 		h.area.data = append(h.area.data, newlvl())
 	}
+	var ol []object.Object
+	skip := make(map[cp.ID]interface{})
+	l := h.area.data[0]
+	var res scope.Value
+	f_res := func(x scope.Value) scope.Value {
+		return res
+	}
+	var talloc func(t object.PointerType)
+	talloc = func(t object.PointerType) {
+		switch bt := t.Base().(type) {
+		case object.RecordType:
+			fake := object.New(object.VARIABLE, int(cp.SomeAdr()))
+			fake.SetComplex(bt)
+			fake.SetType(object.COMPLEX)
+			fake.SetName("{}")
+			l.alloc(mod, nil, append(ol, fake), skip)
+			res = &ptrValue{scope: h.area, id: fake.Adr()}
+		case object.DynArrayType:
+			assert.For(len(par) > 0, 20)
+			fake := object.New(object.VARIABLE, int(cp.SomeAdr()))
+			fake.SetComplex(bt)
+			fake.SetType(object.COMPLEX)
+			fake.SetName("[]")
+			l.alloc(mod, nil, append(ol, fake), skip)
+			h.area.Select(fake.Adr(), func(v scope.Value) {
+				arr, ok := v.(*dynarr)
+				assert.For(ok, 60)
+				arr.Set(par[0].(scope.Value))
+			})
+			res = &ptrValue{scope: h.area, id: fake.Adr()}
+		default:
+			halt.As(100, fmt.Sprintln("cannot allocate", reflect.TypeOf(bt)))
+		}
+	}
 	switch v := n.(type) {
 	case node.VariableNode:
 		switch t := v.Object().Complex().(type) {
 		case object.PointerType:
-			panic(0)
+			talloc(t)
 			//h.area.data[0].alloc(mod, nil, )
 		default:
 			halt.As(100, reflect.TypeOf(t))
@@ -33,7 +69,7 @@ func (h *halloc) Allocate(n node.Node, par ...interface{}) scope.ValueFor {
 	default:
 		halt.As(101, reflect.TypeOf(v))
 	}
-	return nil
+	return f_res
 }
 
 func (h *halloc) Dispose(n node.Node) {}

+ 4 - 2
rt2/scope/modern/ms.go

@@ -230,11 +230,13 @@ func (a *salloc) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence, r
 					case object.VariableObject, object.ParameterObject:
 						l.r[l.k[dn.Adr()]] = nil
 						data := rt2.ValueOf(f)[nv.Adr()]
-						switch data.(type) {
+						switch deref := data.(type) {
 						case STRING, SHORTSTRING:
 							val := &dynarr{link: old.link}
-							val.Set(data)
+							val.Set(deref)
 							l.v[l.k[dn.Adr()]] = val
+						case *rec:
+							l.v[l.k[dn.Adr()]] = deref
 						default:
 							halt.As(100, reflect.TypeOf(data))
 						}

+ 78 - 13
rt2/scope/modern/val.go

@@ -43,6 +43,7 @@ type rec struct {
 type ptr struct {
 	link object.Object
 	scope.Pointer
+	val *ptrValue
 }
 
 type idx struct {
@@ -118,6 +119,8 @@ func (a *dynarr) Set(v scope.Value) {
 			v[i] = SHORTCHAR(x[i])
 		}
 		a.val = v
+	case INTEGER:
+		a.val = make([]interface{}, int(x))
 	default:
 		halt.As(100, reflect.TypeOf(x))
 	}
@@ -247,13 +250,28 @@ func (d *data) String() string {
 }
 
 func (p *ptr) String() string {
-	return "pointer"
+	return fmt.Sprint("pointer ", p.link.Complex().(object.PointerType).Name(), "&", p.val)
 }
 
 func (p *ptr) Id() cp.ID { return p.link.Adr() }
 
-func (p *ptr) Set(scope.Value) {
-	panic(0)
+func (p *ptr) Set(v scope.Value) {
+	switch x := v.(type) {
+	case *ptr:
+		p.Set(x.val)
+	case *ptrValue:
+		p.val = x
+	default:
+		halt.As(100, reflect.TypeOf(x))
+	}
+}
+
+func (p *ptr) Get() scope.Value {
+	if p.val == nil {
+		return NIL
+	} else {
+		return p.val.scope.Select(p.val.id)
+	}
 }
 
 func newPtr(o object.Object) scope.Variable {
@@ -262,6 +280,21 @@ func newPtr(o object.Object) scope.Variable {
 	return &ptr{link: o}
 }
 
+type ptrValue struct {
+	scope *area
+	id    cp.ID
+}
+
+func (p *ptrValue) String() string {
+	return fmt.Sprint(p.id)
+}
+
+type PTR int
+
+func (p PTR) String() string { return "NIL" }
+
+const NIL PTR = 0
+
 type INTEGER int32
 type BOOLEAN bool
 type BYTE int8
@@ -828,18 +861,45 @@ func (o *ops) Len(a object.Object, _a, _b scope.Value) (ret scope.Value) {
 }
 
 func (o *ops) Is(a scope.Value, typ object.ComplexType) scope.Value {
-	var compare func(x, a object.RecordType) bool
-	compare = func(x, a object.RecordType) bool {
-		switch {
-		case x.Name() == a.Name():
-			//	fmt.Println("eq")
-			return true //опасно сравнивать имена конеш
-		case x.BaseType() != nil:
-			//	fmt.Println("go base")
-			return compare(x.BaseType(), a)
+	var compare func(x, a object.ComplexType) bool
+	compare = func(_x, _a object.ComplexType) bool {
+		switch x := _x.(type) {
+		case object.RecordType:
+			switch a := _a.(type) {
+			case object.RecordType:
+				switch {
+				case x.Name() == a.Name():
+					//	fmt.Println("eq")
+					return true //опасно сравнивать имена конеш
+				case x.BaseType() != nil:
+					//	fmt.Println("go base")
+					return compare(x.BaseType(), a)
+				default:
+					return false
+				}
+			default:
+				halt.As(100, reflect.TypeOf(a))
+			}
+		case object.PointerType:
+			switch a := _a.(type) {
+			case object.PointerType:
+				switch {
+				case x.Name() == a.Name():
+					//	fmt.Println("eq")
+					return true //опасно сравнивать имена конеш
+				case x.Base() != nil:
+					//	fmt.Println("go base")
+					return compare(x.Base(), a)
+				default:
+					return false
+				}
+			default:
+				halt.As(100, reflect.TypeOf(a))
+			}
 		default:
-			return false
+			halt.As(100, reflect.TypeOf(a))
 		}
+		panic(0)
 	}
 	switch x := a.(type) {
 	case *rec:
@@ -847,6 +907,11 @@ func (o *ops) Is(a scope.Value, typ object.ComplexType) scope.Value {
 		y, b := typ.(object.RecordType)
 		fmt.Println("compare", x.link.Complex(), typ, a, b, a && b && compare(z, y))
 		return BOOLEAN(a && b && compare(z, y))
+	case *ptr:
+		z, a := x.link.Complex().(object.PointerType)
+		y, b := typ.(object.PointerType)
+		fmt.Println("compare", x.link.Complex(), typ, a, b, a && b && compare(z, y))
+		return BOOLEAN(a && b && compare(z, y))
 	default:
 		halt.As(100, reflect.TypeOf(x))
 	}