Jelajahi Sumber

реализация обработки узла if

kpmy 10 tahun lalu
induk
melakukan
300ec7fbb5
4 mengubah file dengan 85 tambahan dan 3 penghapusan
  1. 1 1
      fw.go
  2. 33 1
      rt2/rules2/wrap/eval/do.go
  3. 48 0
      rt2/rules2/wrap/eval/stmt.go
  4. 3 1
      rt2/rules2/wrap/nodes.go

+ 1 - 1
fw.go

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

+ 33 - 1
rt2/rules2/wrap/eval/do.go

@@ -43,6 +43,27 @@ func BeginDesignator(in IN) (out OUT) {
 	return
 }
 
+func GetStrange(in IN, key interface{}, ss node.Node, next Do) (out OUT) {
+	assert.For(ss != nil, 20)
+	assert.For(key != nil, 21)
+	switch ss.(type) {
+	case node.IfNode:
+		nf := rt2.New(ss)
+		rt2.Push(nf, in.Frame)
+		rt2.RegOf(in.Frame)[context.KEY] = key
+		rt2.Assert(in.Frame, func(f frame.Frame) (bool, int) {
+			v := rt2.RegOf(f)[key]
+			return v != nil, 1980
+		})
+		return Later(func(IN) OUT {
+			return Now(next)
+		})
+	default:
+		halt.As(100, reflect.TypeOf(ss))
+	}
+	return
+}
+
 func GetExpression(in IN, key interface{}, expr node.Node, next Do) OUT {
 	assert.For(expr != nil, 20)
 	_, e_ok := expr.(node.Expression)
@@ -77,6 +98,15 @@ func GetDesignator(in IN, key interface{}, design node.Node, next Do) OUT {
 		return Now(next)
 	})
 }
+func BeginStrange(in IN) OUT {
+	switch s := in.IR.(type) {
+	case node.IfNode:
+		return Now(doIf)
+	default:
+		halt.As(100, reflect.TypeOf(s))
+	}
+	panic(0)
+}
 
 func BeginStatement(in IN) (out OUT) {
 	switch n := in.IR.(type) {
@@ -98,6 +128,8 @@ func BeginStatement(in IN) (out OUT) {
 		out = Now(doCall)
 	case node.ReturnNode:
 		out = Now(doReturn)
+	case node.ConditionalNode:
+		out = Now(doCondition)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -123,7 +155,7 @@ func EndStatement(in IN) (out OUT) {
 			}
 			return End()
 		})
-	case node.AssignNode, node.CallNode:
+	case node.AssignNode, node.CallNode, node.ConditionalNode:
 		out = Now(func(in IN) OUT {
 			next := n.Link()
 			if next != nil {

+ 48 - 0
rt2/rules2/wrap/eval/stmt.go

@@ -92,6 +92,54 @@ func doAssign(in IN) (out OUT) {
 	return
 }
 
+func doIf(in IN) OUT {
+	const left = "if:left:if"
+	i := in.IR.(node.IfNode)
+	return GetExpression(in, left, i.Left(), func(in IN) OUT {
+		val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		assert.For(val != nil, 20)
+		rt2.ValueOf(in.Parent)[i.Adr()] = val
+		rt2.RegOf(in.Parent)[in.Key] = i.Adr()
+		return End()
+	})
+}
+
+func doCondition(in IN) OUT {
+	const left = "if:left"
+	i := in.IR.(node.ConditionalNode)
+	rt2.RegOf(in.Frame)[0] = i.Left() // if
+	var next Do
+	next = func(in IN) OUT {
+		last := rt2.RegOf(in.Frame)[0].(node.Node)
+		fi := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		done := scope.GoTypeFrom(fi).(bool)
+		rt2.RegOf(in.Frame)[0] = nil
+		rt2.ValueOf(in.Frame)[KeyOf(in, left)] = nil
+
+		if done && last.Right() != nil {
+			rt2.Push(rt2.New(last.Right()), in.Frame)
+			return Later(Tail(STOP))
+		} else if last.Right() == nil {
+			return End()
+		} else if last.Link() != nil { //elsif
+			rt2.RegOf(in.Frame)[0] = last.Link()
+			return GetStrange(in, left, i.Left(), next)
+		} else if i.Right() != nil { //else
+			rt2.Push(rt2.New(i.Right()), in.Frame)
+			return Later(Tail(STOP))
+		} else if i.Right() == nil {
+			return End()
+		} else if i.Right() == last {
+			return End()
+		} else {
+			halt.As(100, "wrong if then else")
+			panic(100)
+		}
+	}
+
+	return GetStrange(in, left, i.Left(), next)
+}
+
 func doReturn(in IN) OUT {
 	const left = "return:left"
 	r := in.IR.(node.ReturnNode)

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

@@ -78,6 +78,8 @@ func prologue(n node.Node) frame.Sequence {
 		return Propose(eval.BeginExpression)
 	case node.Designator:
 		return Propose(eval.BeginDesignator)
+	case node.IfNode:
+		return Propose(eval.BeginStrange)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -88,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: //do nothing
+	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode, node.IfNode: //do nothing
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}