Ver código fonte

IF THEN ELSE, переименовал константы WAIT

p.kushnir 10 anos atrás
pai
commit
bfc107fbd4

+ 1 - 1
fw/fw.go

@@ -27,7 +27,7 @@ func main() {
 		var fu nodeframe.FrameUtils
 		root.PushFor(fu.New(ret.Enter), nil)
 		i := 0
-		for x := frame.DO; x == frame.DO; x = root.Do() {
+		for x := frame.NOW; x == frame.NOW; x = root.Do() {
 			//fmt.Println(x)
 			i++
 		}

+ 2 - 2
rt2/frame/frame.go

@@ -9,8 +9,8 @@ type WAIT int
 const (
 	WRONG WAIT = iota
 	STOP
-	SKIP
-	DO
+	LATER
+	NOW
 )
 
 // LIFO-стек, позволяет затолкнуть фрейм связанный с другим фреймом

+ 11 - 8
rt2/frame/stdFrame.go

@@ -56,23 +56,25 @@ func (f *RootFrame) Do() (res WAIT) {
 		for {
 			wait := x.Do()
 			//fmt.Println(wait)
-			if wait == SKIP {
+			if wait == LATER {
 				break
-			} else if wait == DO {
+			} else if wait == NOW {
 			} else if wait == WRONG {
 				panic("something wrong")
-			} else {
+			} else if wait == STOP {
 				if x == f.Top() {
 					f.Pop()
 				} else {
 					panic("do not stop if not top on stack")
 				}
 				break
+			} else {
+				panic("wrong wait code")
 			}
 		}
 	}
 	if f.Top() != nil {
-		res = DO
+		res = NOW
 	} else {
 		res = STOP
 	}
@@ -89,14 +91,15 @@ func (f *RootFrame) Init(d context.Domain) {
 	assert.For(d != nil, 21)
 	f.domain = d
 }
+
 func (f *RootFrame) Handle(msg interface{}) {}
 
 func (w WAIT) String() string {
 	switch w {
-	case DO:
-		return "DO"
-	case SKIP:
-		return "SKIP"
+	case NOW:
+		return "NOW"
+	case LATER:
+		return "LATER"
 	case STOP:
 		return "STOP"
 	case WRONG:

+ 7 - 2
rt2/nodeframe/frame.go

@@ -18,9 +18,8 @@ func (fu FrameUtils) New(n node.Node) (f frame.Frame) {
 	assert.For(n != nil, 20)
 	f = new(nodeFrame)
 	f.(*nodeFrame).ir = n
-	f.(*nodeFrame).num = count
 	f.(*nodeFrame).data = make(map[interface{}]interface{})
-	count++
+	fmt.Println("_", "NEW", reflect.TypeOf(n))
 	return f
 }
 
@@ -65,10 +64,15 @@ func (f *nodeFrame) Do() frame.WAIT {
 }
 
 func (f *nodeFrame) onPush() {
+	f.num = count
+	count++
+	fmt.Println("_", "PUSH", reflect.TypeOf(f.ir))
 	f.seq = decision.PrologueFor(f.ir)
 }
 
 func (f *nodeFrame) OnPop() {
+	count--
+	fmt.Println("_", "POP", reflect.TypeOf(f.ir))
 	f.seq = decision.EpilogueFor(f.ir)
 	if f.seq != nil {
 		_, _ = f.seq(f)
@@ -93,6 +97,7 @@ func (f *nodeFrame) Init(d context.Domain) {
 	assert.For(d != nil, 21)
 	f.domain = d
 }
+
 func (f *nodeFrame) Handle(msg interface{}) {
 	assert.For(msg != nil, 20)
 

+ 3 - 3
rt2/rules/assign.go

@@ -25,7 +25,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				})
 				return frame.End()
 			}
-			ret = frame.DO
+			ret = frame.NOW
 		case node.VariableNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
@@ -34,7 +34,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				})
 				return frame.End()
 			}
-			ret = frame.DO
+			ret = frame.NOW
 		case node.OperationNode, node.CallNode:
 			fu.Push(fu.New(a.Right()), f)
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
@@ -44,7 +44,7 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				})
 				return frame.End()
 			}
-			ret = frame.SKIP
+			ret = frame.LATER
 		default:
 			fmt.Println(reflect.TypeOf(a.Right()))
 			panic("wrong right")

+ 1 - 1
rt2/rules/call.go

@@ -33,7 +33,7 @@ func callSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			fu.DataOf(f.Parent())[n] = fu.DataOf(f)[n.Left().Object()]
 			return frame.End()
 		}
-		ret = frame.SKIP
+		ret = frame.LATER
 	default:
 		panic("unknown call left")
 	}

+ 3 - 3
rt2/rules/enter.go

@@ -25,7 +25,7 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	if f.Parent() != nil {
 		//Вход в процедуру не несет значимых действий и просто заменяет себя в цепочке родителей на своего родителя
 		fu.Push(fu.New(body), f.Parent())
-		return frame.Tail(frame.STOP), frame.SKIP
+		return frame.Tail(frame.STOP), frame.LATER
 	} else {
 		//Особый случай, вход в модуль, секция BEGIN
 		fu.Push(fu.New(body), f)
@@ -34,12 +34,12 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		if next != nil {
 			seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
 				f.Root().PushFor(fu.New(next), f)
-				return frame.Tail(frame.STOP), frame.SKIP
+				return frame.Tail(frame.STOP), frame.LATER
 			}
 		} else {
 			seq = frame.Tail(frame.STOP)
 		}
-		return seq, frame.SKIP
+		return seq, frame.LATER
 
 	}
 }

+ 49 - 2
rt2/rules/if.go

@@ -1,9 +1,56 @@
 package rules
 
 import (
+	"cp/node"
+	"fmt"
+	"reflect"
 	"rt2/frame"
+	"rt2/nodeframe"
 )
 
-func ifSeq(f frame.Frame) (frame.Sequence, frame.WAIT) {
-	return frame.End()
+func ifExpr(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	var fu nodeframe.FrameUtils
+	n := fu.NodeOf(f)
+	switch n.Left().(type) {
+	case node.OperationNode:
+		fu.Push(fu.New(n.Left()), f)
+		seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+			fu.DataOf(f.Parent())[n] = fu.DataOf(f)[n.Left()]
+			return frame.End()
+		}
+		ret = frame.LATER
+	default:
+		panic(fmt.Sprintf("unknown condition expression", reflect.TypeOf(n.Left())))
+	}
+	return seq, ret
+}
+
+func ifSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	var fu nodeframe.FrameUtils
+	n := fu.NodeOf(f)
+	fu.DataOf(f)[0] = n.Left() //if
+	fu.Push(fu.New(n.Left()), f)
+	seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+		last := fu.DataOf(f)[0].(node.Node)
+		done := fu.DataOf(f)[last].(bool)
+		fu.DataOf(f)[last] = nil
+		if done {
+			fu.Push(fu.New(last.Right()), f)
+			return frame.Tail(frame.STOP), frame.LATER
+		} else if last.Link() != nil { //elsif
+			fu.DataOf(f)[0] = last.Link()
+			fu.Push(fu.New(last.Link()), f)
+			return seq, frame.LATER
+		} else if n.Right() != nil { //else
+			fu.Push(fu.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()
+		} else {
+			panic("conditional sequence wrong")
+		}
+	}
+	return seq, frame.LATER
 }

+ 21 - 11
rt2/rules/op.go

@@ -35,6 +35,13 @@ func sum(_a interface{}, _b interface{}) interface{} {
 	return a + b
 }
 
+func eq(_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 mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	var fu nodeframe.FrameUtils
 	n := fu.NodeOf(f).(node.MonadicNode)
@@ -76,6 +83,9 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case operation.PLUS:
 			fu.DataOf(f.Parent())[n] = sum(fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
 			return frame.End()
+		case operation.EQUAL:
+			fu.DataOf(f.Parent())[n] = eq(fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
+			return frame.End()
 		default:
 			panic("unknown operation")
 		}
@@ -86,23 +96,23 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		switch n.Right().(type) {
 		case node.ConstantNode:
 			fu.DataOf(f)[n.Right()] = n.Right().(node.ConstantNode).Data()
-			return op, frame.DO
+			return op, frame.NOW
 		case node.VariableNode, node.ParameterNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 				fu.DataOf(f)[n.Right()] = sc.Select(n.Right().Object())
 				//fmt.Println(n.Right().Object(), reflect.TypeOf(n.Right().Object()))
 				assert.For(fu.DataOf(f)[n.Right()] != nil, 60)
-				return op, frame.DO
+				return op, frame.NOW
 			}
-			ret = frame.DO
+			ret = frame.NOW
 			return seq, ret
 		case node.OperationNode:
 			fu.Push(fu.New(n.Right()), f)
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
-				return op, frame.DO
+				return op, frame.NOW
 			}
-			ret = frame.SKIP
+			ret = frame.LATER
 			return seq, ret
 		default:
 			fmt.Println(reflect.TypeOf(n.Right()))
@@ -115,26 +125,26 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		switch n.Left().(type) {
 		case node.ConstantNode:
 			fu.DataOf(f)[n.Left()] = n.Left().(node.ConstantNode).Data()
-			return right, frame.DO
+			return right, frame.NOW
 		case node.VariableNode, node.ParameterNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 				fu.DataOf(f)[n.Left()] = sc.Select(n.Left().Object())
-				return right, frame.DO
+				return right, frame.NOW
 			}
-			ret = frame.DO
+			ret = frame.NOW
 			return seq, ret
 		case node.OperationNode:
 			fu.Push(fu.New(n.Left()), f)
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
-				return right, frame.DO
+				return right, frame.NOW
 			}
-			ret = frame.SKIP
+			ret = frame.LATER
 			return seq, ret
 		default:
 			fmt.Println(reflect.TypeOf(n.Left()))
 			panic("wrong left")
 		}
 	}
-	return left, frame.DO
+	return left, frame.NOW
 }

+ 4 - 4
rt2/rules/return.go

@@ -21,26 +21,26 @@ func returnSeq(f frame.Frame) (frame.Sequence, frame.WAIT) {
 				fu.DataOf(f.Parent())[a.Object()] = a.Left().(node.ConstantNode).Data()
 				return frame.End()
 			}
-			ret = frame.DO
+			ret = frame.NOW
 		case node.VariableNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
 				fu.DataOf(f.Parent())[a.Object()] = sc.Select(a.Left().Object())
 				return frame.End()
 			}
-			ret = frame.DO
+			ret = frame.NOW
 		case node.OperationNode, node.CallNode:
 			fu.Push(fu.New(a.Left()), f)
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				fu.DataOf(f.Parent())[a.Object()] = fu.DataOf(f)[a.Left()]
 				return frame.End()
 			}
-			ret = frame.SKIP
+			ret = frame.LATER
 		default:
 			fmt.Println(reflect.TypeOf(a.Left()))
 			panic("wrong right")
 		}
 		return seq, ret
 	}
-	return left, frame.DO
+	return left, frame.NOW
 }

+ 3 - 1
rt2/rules/table.go

@@ -34,6 +34,8 @@ func prologue(n node.Node) frame.Sequence {
 		return returnSeq
 	case node.ConditionalNode:
 		return ifSeq
+	case node.IfNode:
+		return ifExpr
 	default:
 		panic(fmt.Sprintln("unknown node", reflect.TypeOf(n)))
 	}
@@ -56,7 +58,7 @@ func epilogue(n node.Node) frame.Sequence {
 			sm.Dispose(n)
 			return frame.End()
 		}
-	case node.OperationNode, node.ReturnNode:
+	case node.OperationNode, node.ReturnNode, node.IfNode:
 		return nil
 	default:
 		fmt.Println(reflect.TypeOf(n))