Explorar el Código

доделал цикл LOOP, процедуру INC

p.kushnir hace 10 años
padre
commit
9fffd87616

+ 2 - 0
cp/constant/nodeclass.go

@@ -17,4 +17,6 @@ const (
 	IF
 	WHILE
 	REPEAT
+	EXIT
+	LOOP
 )

+ 1 - 0
cp/constant/operation/operation.go

@@ -8,4 +8,5 @@ const (
 	CONVERT
 	EQUAL
 	LESSER
+	LESS_EQUAL
 )

+ 16 - 0
cp/node/class.go

@@ -38,6 +38,10 @@ func New(class constant.Class) Node {
 		return new(repeatNode)
 	case constant.WHILE:
 		return new(whileNode)
+	case constant.EXIT:
+		return new(exitNode)
+	case constant.LOOP:
+		return new(loopNode)
 	default:
 		panic("no such class")
 	}
@@ -176,3 +180,15 @@ type repeatNode struct {
 }
 
 func (v *repeatNode) self() RepeatNode { return v }
+
+type exitNode struct {
+	nodeFields
+}
+
+func (v *exitNode) self() ExitNode { return v }
+
+type loopNode struct {
+	nodeFields
+}
+
+func (v *loopNode) self() LoopNode { return v }

+ 10 - 0
cp/node/node.go

@@ -103,3 +103,13 @@ type RepeatNode interface {
 	self() RepeatNode
 	Node
 }
+
+type ExitNode interface {
+	self() ExitNode
+	Node
+}
+
+type LoopNode interface {
+	self() LoopNode
+	Node
+}

+ 1 - 0
cp/statement/statement.go

@@ -4,4 +4,5 @@ type Statement int
 
 const (
 	ASSIGN Statement = iota
+	INC
 )

+ 1 - 0
rt2/frame/frame.go

@@ -18,6 +18,7 @@ type Stack interface {
 	PushFor(f, parent Frame)
 	Pop()
 	Top() Frame
+	ForEach(run func(this Frame) bool)
 }
 
 //фрейм

+ 9 - 0
rt2/frame/stdFrame.go

@@ -81,6 +81,15 @@ func (f *RootFrame) Do() (res WAIT) {
 	return res
 }
 
+func (f *RootFrame) ForEach(run func(x Frame) bool) {
+	e := f.inner.Front()
+	ok := true
+	for (e != nil) && ok {
+		ok = run(e.Value.(Frame))
+		e = e.Next()
+	}
+}
+
 func (f *RootFrame) OnPush(a Stack, b Frame) {}
 func (f *RootFrame) OnPop()                  {}
 func (f *RootFrame) Parent() Frame           { return nil }

+ 29 - 1
rt2/rules/assign.go

@@ -2,8 +2,11 @@ package rules
 
 import (
 	"fmt"
+	"fw/cp/constant"
+	"fw/cp/constant/operation"
 	"fw/cp/node"
 	"fw/cp/statement"
+	"fw/rt2"
 	"fw/rt2/context"
 	"fw/rt2/frame"
 	"fw/rt2/nodeframe"
@@ -11,6 +14,24 @@ import (
 	"reflect"
 )
 
+func incSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	n := rt2.Utils.NodeOf(f)
+	op := node.New(constant.DYADIC).(node.OperationNode)
+	op.SetOperation(operation.PLUS)
+	op.SetLeft(n.Left())
+	op.SetRight(n.Right())
+	rt2.Utils.Push(rt2.Utils.New(op), f)
+	seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
+		sc.Update(n.Left().Object(), func(interface{}) interface{} {
+			return rt2.Utils.DataOf(f)[op]
+		})
+		return frame.End()
+	}
+	ret = frame.LATER
+	return seq, ret
+}
+
 func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	var fu nodeframe.FrameUtils
 	a := fu.NodeOf(f)
@@ -60,8 +81,15 @@ func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			fmt.Println(reflect.TypeOf(a.Left()))
 			panic("wrong left")
 		}
+	case statement.INC:
+		switch a.Left().(type) {
+		case node.VariableNode, node.ParameterNode:
+			seq, ret = incSeq(f)
+		default:
+			panic(fmt.Sprintln("wrong left", reflect.TypeOf(a.Left())))
+		}
 	default:
-		panic("wrong statement")
+		panic(fmt.Sprintln("wrong statement", a.(node.AssignNode).Statement()))
 	}
 	return seq, ret
 }

+ 39 - 0
rt2/rules/loop.go

@@ -0,0 +1,39 @@
+package rules
+
+import (
+	"fw/cp/node"
+	"fw/rt2"
+	"fw/rt2/frame"
+)
+
+const flag = 0
+
+func exitSeq(x frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	x.Root().ForEach(func(f frame.Frame) (ok bool) {
+		n := rt2.Utils.NodeOf(f)
+		_, ok = n.(node.LoopNode)
+		if ok {
+			rt2.Utils.DataOf(f)[flag] = true
+		}
+		ok = !ok
+		return ok
+	})
+	return frame.End()
+}
+
+func loopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	n := rt2.Utils.NodeOf(f)
+	exit, ok := rt2.Utils.DataOf(f)[flag].(bool)
+	if ok && exit {
+		return frame.End()
+	}
+	if n.Left() != nil {
+		rt2.Utils.Push(rt2.Utils.New(n.Left()), f)
+		return loopSeq, frame.LATER
+	} else if n.Left() == nil {
+		return frame.End()
+	} else {
+		panic("unexpected loop seq")
+	}
+
+}

+ 11 - 0
rt2/rules/op.go

@@ -59,6 +59,14 @@ func lss(_a interface{}, _b interface{}) bool {
 	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 mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	var fu nodeframe.FrameUtils
 	n := fu.NodeOf(f).(node.MonadicNode)
@@ -109,6 +117,9 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case operation.LESSER:
 			fu.DataOf(f.Parent())[n] = lss(fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
 			return frame.End()
+		case operation.LESS_EQUAL:
+			fu.DataOf(f.Parent())[n] = leq(fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
+			return frame.End()
 		default:
 			panic("unknown operation")
 		}

+ 1 - 1
rt2/rules/repeat.go

@@ -17,7 +17,7 @@ func repeatSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	next := func(f frame.Frame) (frame.Sequence, frame.WAIT) {
 		done := fu.DataOf(f)[n.Right()].(bool)
 		fu.DataOf(f)[n.Right()] = nil
-		if !done && n.Right() != nil {
+		if !done && n.Left() != nil {
 			fu.Push(fu.New(n.Left()), f)
 			return cond, frame.LATER
 		} else if done {

+ 6 - 2
rt2/rules/table.go

@@ -40,6 +40,10 @@ func prologue(n node.Node) frame.Sequence {
 		return whileSeq
 	case node.RepeatNode:
 		return repeatSeq
+	case node.LoopNode:
+		return loopSeq
+	case node.ExitNode:
+		return exitSeq
 	default:
 		panic(fmt.Sprintln("unknown node", reflect.TypeOf(n)))
 	}
@@ -48,7 +52,7 @@ func prologue(n node.Node) frame.Sequence {
 func epilogue(n node.Node) frame.Sequence {
 	var fu nodeframe.FrameUtils
 	switch n.(type) {
-	case node.AssignNode, node.CallNode, node.ConditionalNode, node.WhileNode, node.RepeatNode:
+	case node.AssignNode, node.CallNode, node.ConditionalNode, node.WhileNode, node.RepeatNode, node.ExitNode:
 		return func(f frame.Frame) (frame.Sequence, frame.WAIT) {
 			next := n.Link()
 			if next != nil {
@@ -62,7 +66,7 @@ func epilogue(n node.Node) frame.Sequence {
 			sm.Dispose(n)
 			return frame.End()
 		}
-	case node.OperationNode, node.ReturnNode, node.IfNode:
+	case node.OperationNode, node.ReturnNode, node.IfNode, node.LoopNode:
 		return nil
 	default:
 		fmt.Println(reflect.TypeOf(n))

+ 5 - 0
rt2/utils.go

@@ -0,0 +1,5 @@
+package rt2
+
+import "fw/rt2/nodeframe"
+
+var Utils nodeframe.FrameUtils

+ 8 - 0
xev/converter.go

@@ -229,6 +229,8 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 				ret.(node.OperationNode).SetOperation(operation.EQUAL)
 			case "lesser":
 				ret.(node.OperationNode).SetOperation(operation.LESSER)
+			case "less or equal":
+				ret.(node.OperationNode).SetOperation(operation.LESS_EQUAL)
 			default:
 				panic("no such operation")
 			}
@@ -241,6 +243,8 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 			switch n.Data.Nod.Statement {
 			case "assign":
 				ret.(node.AssignNode).SetStatement(statement.ASSIGN)
+			case "inc":
+				ret.(node.AssignNode).SetStatement(statement.INC)
 			default:
 				panic("unknown assign statement")
 			}
@@ -269,6 +273,10 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 			ret = node.New(constant.WHILE)
 		case "repeat":
 			ret = node.New(constant.REPEAT)
+		case "loop":
+			ret = node.New(constant.LOOP)
+		case "exit":
+			ret = node.New(constant.EXIT)
 		default:
 			fmt.Println(n.Data.Nod.Class)
 			panic("no such node type")