Переглянути джерело

развитие нового механизма, добрался до демки19 с супервызовами.

kpmy 10 роки тому
батько
коміт
2231a42e4d

+ 1 - 0
cp/node/class.go

@@ -418,6 +418,7 @@ func (v *doNode) self() DoNode { return v }
 
 type rangeNode struct {
 	nodeFields
+	expr
 }
 
 func (v *rangeNode) self() RangeNode { return v }

+ 1 - 0
cp/node/node.go

@@ -213,4 +213,5 @@ type DoNode interface {
 type RangeNode interface {
 	self() RangeNode
 	Node
+	Expression
 }

+ 1 - 1
fw.go

@@ -37,7 +37,7 @@ func main() {
 	flag.Parse()
 	utils.Debug(debug)
 	if name == "" {
-		name = "XevDemo11"
+		name = "XevDemo19"
 		utils.Debug(false)
 	}
 	global := &stdDomain{god: true}

+ 5 - 3
rt2/module/ml.go

@@ -248,11 +248,13 @@ func (c *tc) MethodList() (ret map[int][]Method) {
 				}
 				if local && po.Link() != nil {
 					for pt := po.Link().Complex(); pt != nil; {
-						if t.Equals(pt) && tmp[po.Name()] == nil {
-							//fmt.Println("method", m.Name, po.Name(), local)
-							tmp[po.Name()] = po
+						if t.Equals(pt) && tmp[pt.Qualident()+"."+po.Name()] == nil {
+							fmt.Println("method", m.Name, pt.Qualident(), po.Name(), local)
+							tmp[pt.Qualident()+"."+po.Name()] = po
 							ret[depth] = append(ret[depth], Method{Enter: et, Obj: po, Mod: m})
 							break
+						} else if t.Equals(pt) {
+							//fmt.Println("double ", pt.Qualident(), po.Name())
 						}
 						if _, ok := pt.(inherited); ok {
 							pt = pt.(inherited).Complex()

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

@@ -23,6 +23,8 @@ func BeginExpression(in IN) (out OUT) {
 		out = Now(getDop)
 	case node.MonadicNode:
 		out = Now(getMop)
+	case node.RangeNode:
+		out = Now(getRange)
 	case node.Designator:
 		out = Now(BeginDesignator)
 	default:
@@ -45,6 +47,8 @@ func BeginDesignator(in IN) (out OUT) {
 		out = Now(getField)
 	case node.IndexNode:
 		out = Now(getIndex)
+	case node.GuardNode:
+		out = Now(getGuard)
 	default:
 		halt.As(100, reflect.TypeOf(e))
 	}
@@ -130,6 +134,25 @@ func BeginStatement(in IN) (out OUT) {
 			}
 		}
 		out = Now(tail)
+	case node.CompNode:
+		next := n
+		return Now(func(IN) OUT {
+			right := func(in IN) OUT {
+				if next.Right() != nil {
+					rt2.Push(rt2.New(next.Right()), in.Frame)
+					return Later(Tail(STOP))
+				}
+				return End()
+			}
+			left := func(in IN) OUT {
+				if next.Left() != nil {
+					rt2.Push(rt2.New(next.Left()), in.Frame)
+					return Later(right)
+				}
+				return Now(right)
+			}
+			return Now(left)
+		})
 	case node.AssignNode:
 		out = Now(doAssign)
 	case node.CallNode:
@@ -152,6 +175,8 @@ func BeginStatement(in IN) (out OUT) {
 		out = Now(doTrap)
 	case node.WithNode:
 		out = Now(doWith)
+	case node.CaseNode:
+		out = Now(doCase)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -200,7 +225,7 @@ func EndStatement(in IN) (out OUT) {
 			}
 			return End()
 		})
-	case node.AssignNode, node.ConditionalNode, node.WhileNode, node.RepeatNode, node.ExitNode, node.InitNode, node.WithNode:
+	case node.AssignNode, node.ConditionalNode, node.WhileNode, node.RepeatNode, node.ExitNode, node.InitNode, node.WithNode, node.CaseNode, node.CompNode:
 		out = Now(func(in IN) OUT {
 			next := n.Link()
 			if next != nil {
@@ -213,7 +238,7 @@ func EndStatement(in IN) (out OUT) {
 		})
 	case node.ReturnNode, node.LoopNode: //do nothing
 	default:
-		halt.As(100, reflect.TypeOf(n))
+		halt.As(100, "statement with no end", reflect.TypeOf(n))
 	}
 	if out.Next != WRONG {
 		return out.Do(in)

+ 61 - 5
rt2/rules2/wrap/eval/expr.go

@@ -5,8 +5,10 @@ import (
 	"fw/cp/constant/operation"
 	"fw/cp/node"
 	"fw/cp/object"
+	"fw/cp/traps"
 	"fw/rt2"
 	"fw/rt2/scope"
+	"math/big"
 	"reflect"
 	"ypk/assert"
 	"ypk/halt"
@@ -96,7 +98,7 @@ func getProc(in IN) OUT {
 func getDeref(in IN) OUT {
 	const left = "design:left"
 	d := in.IR.(node.DerefNode)
-	return GetDesignator(in, left, d.Left(), func(in IN) OUT {
+	return GetDesignator(in, left, d.Left(), func(in IN) (out OUT) {
 		_v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
 		switch v := _v.(type) {
 		case scope.Array:
@@ -116,6 +118,17 @@ func getDeref(in IN) OUT {
 			default:
 				halt.As(100, t, reflect.TypeOf(cc))
 			}
+		case scope.Pointer:
+			assert.For(d.Ptr(), 41)
+			rec := v.Get()
+			rt2.ValueOf(in.Parent)[d.Adr()] = rec
+			rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+			if scope.GoTypeFrom(rec) == nil {
+				out = makeTrap(in.Frame, traps.NILderef)
+			} else {
+				out = End()
+			}
+			return out
 		default:
 			halt.As(100, reflect.TypeOf(v))
 		}
@@ -237,10 +250,7 @@ func getMop(in IN) OUT {
 		case operation.NOT:
 			res = scope.Ops.Not(lv)
 		case operation.IS:
-			/*sc := rt2.ScopeFor(f, n.Left().Object().Adr())
-			rt2.ValueOf(f.Parent())[n.Adr()] = scope.Ops.Is(sc.Select(n.Left().Object().Adr()), n.Object().Complex())
-			return frame.End()*/
-			panic(0)
+			res = scope.Ops.Is(lv, op.Object().Complex())
 		case operation.ABS:
 			res = scope.Ops.Abs(lv)
 		case operation.ODD:
@@ -262,3 +272,49 @@ func getMop(in IN) OUT {
 
 	return GetExpression(in, left, op.Left(), do)
 }
+
+func getGuard(in IN) OUT {
+	const left = "guard:left"
+	g := in.IR.(node.GuardNode)
+	return GetDesignator(in, left, g.Left(), func(IN) OUT {
+		v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		assert.For(v != nil, 20)
+		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()
+			return End()
+		} else {
+			return makeTrap(in.Frame, 0)
+		}
+
+	})
+}
+
+func bit_range(_f scope.Value, _t scope.Value) scope.Value {
+	f := scope.GoTypeFrom(_f).(int32)
+	t := scope.GoTypeFrom(_t).(int32)
+	ret := big.NewInt(0)
+	for i := f; i <= t; i++ {
+		ret = ret.SetBit(ret, int(i), 1)
+	}
+	fmt.Println("bits", ret)
+	return scope.TypeFromGo(ret)
+}
+
+func getRange(in IN) OUT {
+	const (
+		left  = "range:left"
+		right = "range:right"
+	)
+	r := in.IR.(node.RangeNode)
+	return GetExpression(in, left, r.Left(), func(IN) OUT {
+		return GetExpression(in, right, r.Right(), func(in IN) OUT {
+			lv := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+			rv := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
+			res := bit_range(lv, rv)
+			rt2.ValueOf(in.Parent)[r.Adr()] = res
+			rt2.RegOf(in.Parent)[in.Key] = r.Adr()
+			return End()
+		})
+	})
+}

+ 149 - 28
rt2/rules2/wrap/eval/stmt.go

@@ -1,6 +1,7 @@
 package eval
 
 import (
+	"fmt"
 	"fw/cp"
 	"fw/cp/constant"
 	"fw/cp/constant/operation"
@@ -15,11 +16,21 @@ import (
 	"fw/rt2/scope"
 	"fw/utils"
 	"log"
+	"math/big"
 	"reflect"
 	"ypk/assert"
 	"ypk/halt"
 )
 
+func makeTrap(f frame.Frame, err traps.TRAP) (out OUT) {
+	trap := node.New(constant.TRAP, cp.Some()).(node.TrapNode)
+	code := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
+	code.SetData(int32(err))
+	trap.SetLeft(code)
+	rt2.Push(rt2.New(trap), f)
+	return Later(Tail(STOP))
+}
+
 func doEnter(in IN) OUT {
 	e := in.IR.(node.EnterNode)
 	var next Do
@@ -126,6 +137,28 @@ func doAssign(in IN) (out OUT) {
 		default:
 			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)
+					v.Set(fn(nil))
+					return End()
+				})
+			})
+		} 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))
+				v.Set(fn(nil))
+				return End()
+			})
+		}
 	default:
 		halt.As(100, "unsupported assign statement", a.Statement())
 	}
@@ -343,7 +376,6 @@ func doCall(in IN) (out OUT) {
 			}
 		case object.TYPE_PROC:
 			//sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
-			assert.For(!p.Super(), 20)
 			out = GetExpression(in, right, c.Right(), func(IN) (out OUT) {
 				var (
 					proc []node.Node
@@ -358,13 +390,19 @@ func doCall(in IN) (out OUT) {
 				}
 				assert.For(ct != nil, 40, id, v, t)
 				x := ml.NewTypeCalc()
-				x.ConnectTo(c)
-				for _, ml := range x.MethodList() {
+				x.ConnectTo(ct)
+				sup := p.Super()
+				for level, ml := range x.MethodList() {
 					for _, m := range ml {
+						fmt.Println(m.Obj.Name(), level)
 						if m.Obj.Name() == p.Object().Name() {
-							proc = append(proc, m.Enter)
+							if !sup {
+								proc = append(proc, m.Enter)
+								break
+							} else {
+								sup = false //супервызов должен быть вторым методом с тем же именем
+							}
 							dm = in.Frame.Domain().Global().Discover(m.Mod.Name).(context.Domain)
-							break
 						}
 					}
 					if len(proc) > 0 {
@@ -402,38 +440,121 @@ func doCall(in IN) (out OUT) {
 	return
 }
 
+const isFlag = 1700
+
 func doWith(in IN) OUT {
-	const left = "return:left"
+	const left = "with:left"
 	w := in.IR.(node.WithNode)
 	f := in.Frame
-	rt2.RegOf(f)[0] = w.Left() //if
-
-	seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
-		last := rt2.RegOf(f)[0].(node.Node)
-		done := scope.GoTypeFrom(rt2.ValueOf(f)[last.Adr()]).(bool)
-		rt2.ValueOf(f)[last.Adr()] = nil
+	rt2.RegOf(f)[isFlag] = w.Left() //if
+	var seq Do
+	seq = func(in IN) OUT {
+		last := rt2.RegOf(f)[isFlag].(node.Node)
+		id := KeyOf(in, left)
+		v := rt2.ValueOf(f)[id]
+		assert.For(v != nil, 40)
+		done := scope.GoTypeFrom(v).(bool)
+		rt2.ValueOf(f)[id] = nil
 		if done && last.Right() != nil {
 			rt2.Push(rt2.New(last.Right()), f)
-			return frame.Tail(frame.STOP), frame.LATER
+			return Later(Tail(STOP))
 		} else if last.Right() == nil {
-			return frame.End()
+			return End()
 		} else if last.Link() != nil { //elsif
-			rt2.RegOf(f)[0] = last.Link()
-			rt2.Push(rt2.New(last.Link()), f)
-			rt2.Assert(f, func(f frame.Frame) (bool, int) {
-				return rt2.ValueOf(f)[last.Link().Adr()] != nil, 61
-			})
-			return seq, frame.LATER
-		} else if n.Right() != nil { //else
-			rt2.Push(rt2.New(n.Right()), f)
-			return frame.Tail(frame.STOP), frame.LATER
-		} else if n.Right() == nil {
-			return frame.End()
-		} else if last == n.Right() {
-			return frame.End()
+			rt2.RegOf(f)[isFlag] = last.Link()
+			return Later(func(IN) OUT { return GetStrange(in, left, last.Link(), seq) })
+		} else if w.Right() != nil { //else
+			rt2.Push(rt2.New(w.Right()), f)
+			return Later(Tail(STOP))
+		} else if w.Right() == nil {
+			return End()
+		} else if last == w.Right() {
+			return End()
 		} else {
 			panic("conditional sequence wrong")
 		}
 	}
-	return seq, frame.LATER
+	return GetStrange(in, left, w.Left(), seq)
+}
+
+func int32Of(x interface{}) (a int32) {
+	//fmt.Println(reflect.TypeOf(x))
+	switch v := x.(type) {
+	case *int32:
+		z := *x.(*int32)
+		a = z
+	case int32:
+		a = x.(int32)
+	case *big.Int:
+		a = int32(v.Int64())
+	default:
+		//panic(fmt.Sprintln("unsupported type", reflect.TypeOf(x)))
+	}
+	return a
+}
+
+func doCase(in IN) OUT {
+	const left = "case:left"
+	c := in.IR.(node.CaseNode)
+
+	var e int
+
+	do := func(in IN) (out OUT) {
+		cond := c.Right().(node.ElseNode)
+		//fmt.Println("case?", e, cond.Min(), cond.Max())
+		if e < cond.Min() || e > cond.Max() { //case?
+			if cond.Right() != nil {
+				rt2.Push(rt2.New(cond.Right()), in.Frame)
+			}
+			out.Do = Tail(STOP)
+			out.Next = LATER
+		} else {
+			for next := cond.Left(); next != nil && out.Do == nil; next = next.Link() {
+				var ok bool
+				//				_c := next.Left()
+				for _c := next.Left(); _c != nil && !ok; _c = _c.Link() {
+					c := _c.(node.ConstantNode)
+					//fmt.Println("const", c.Data(), c.Min(), c.Max())
+					if (c.Min() != nil) && (c.Max() != nil) {
+						//fmt.Println(e, *c.Max(), "..", *c.Min())
+						ok = e >= *c.Min() && e <= *c.Max()
+					} else {
+						//fmt.Println(e, c.Data())
+						ok = int32Of(c.Data()) == int32(e)
+					}
+				}
+				//fmt.Println(ok)
+				if ok {
+					rt2.Push(rt2.New(next.Right()), in.Frame)
+					out.Do = Tail(STOP)
+					out.Next = LATER
+				}
+			}
+			if out.Do == nil && cond.Right() != nil {
+				rt2.Push(rt2.New(cond.Right()), in.Frame)
+				out.Do = Tail(STOP)
+				out.Next = LATER
+			}
+		}
+		assert.For(out.Do != nil, 60)
+		return out
+	}
+
+	return GetExpression(in, left, c.Left(), func(IN) (out OUT) {
+		v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		_x := scope.GoTypeFrom(v)
+		switch x := _x.(type) {
+		case nil:
+			panic("nil")
+		case int32:
+			e = int(x)
+			//fmt.Println("case", e)
+			out.Do = do
+			out.Next = NOW
+			return out
+		default:
+			halt.As(100, "unsupported case expr", reflect.TypeOf(_x))
+		}
+		panic(0)
+	})
 }

+ 1 - 1
rt2/rules2/wrap/nodes.go

@@ -90,7 +90,7 @@ func epilogue(n node.Node) frame.Sequence {
 	switch n.(type) {
 	case node.Statement:
 		return Propose(eval.EndStatement)
-	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode, node.IfNode, node.ProcedureNode, node.DerefNode, node.FieldNode, node.IndexNode: //do nothing
+	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode, node.IfNode, node.ProcedureNode, node.DerefNode, node.FieldNode, node.IndexNode, node.GuardNode, node.RangeNode: //do nothing
 	default:
 		halt.As(100, "no epilogue for", reflect.TypeOf(n))
 	}

+ 1 - 0
rt2/scope/modern/val.go

@@ -229,6 +229,7 @@ func (a *arr) Get(id scope.Value) scope.Value {
 	case *data:
 		return a.Get(i.val.(scope.Value))
 	case INTEGER:
+		assert.For(int64(i) < a.length, 20)
 		if len(a.val) == 0 {
 			a.val = make([]interface{}, int(a.length))
 		}