Browse Source

поддержка ASSERT и HALT

p.kushnir 10 years ago
parent
commit
88c45b7721

File diff suppressed because it is too large
+ 1 - 0
PrivDemo11.oxf


File diff suppressed because it is too large
+ 1 - 0
XevDemo10.oxf


File diff suppressed because it is too large
+ 1 - 0
XevDemo9.oxf


+ 1 - 0
cp/constant/nodeclass.go

@@ -22,4 +22,5 @@ const (
 	DEREF
 	DEREF
 	FIELD
 	FIELD
 	INDEX
 	INDEX
+	TRAP
 )
 )

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

@@ -10,4 +10,6 @@ const (
 	LESSER
 	LESSER
 	LESS_EQUAL
 	LESS_EQUAL
 	LEN
 	LEN
+	NOT
+	NOT_EQUAL
 )
 )

+ 8 - 0
cp/node/class.go

@@ -57,6 +57,8 @@ func New(class constant.Class) Node {
 		return new(initNode)
 		return new(initNode)
 	case constant.INDEX:
 	case constant.INDEX:
 		return new(indexNode)
 		return new(indexNode)
+	case constant.TRAP:
+		return new(trapNode)
 	default:
 	default:
 		panic("no such class")
 		panic("no such class")
 	}
 	}
@@ -231,3 +233,9 @@ type indexNode struct {
 }
 }
 
 
 func (v *indexNode) self() IndexNode { return v }
 func (v *indexNode) self() IndexNode { return v }
+
+type trapNode struct {
+	nodeFields
+}
+
+func (v *trapNode) self() TrapNode { return v }

+ 5 - 0
cp/node/node.go

@@ -128,3 +128,8 @@ type IndexNode interface {
 	self() IndexNode
 	self() IndexNode
 	Node
 	Node
 }
 }
+
+type TrapNode interface {
+	self() TrapNode
+	Node
+}

BIN
doc/ast-rules.pdf


BIN
doc/ast.odt


+ 1 - 1
fw.go

@@ -25,7 +25,7 @@ func close() {
 func main() {
 func main() {
 	flag.Parse()
 	flag.Parse()
 	if name == "" {
 	if name == "" {
-		name = "XevDemo8"
+		name = "XevDemo10"
 	}
 	}
 	global := new(stdDomain)
 	global := new(stdDomain)
 	modList := module.New()
 	modList := module.New()

+ 5 - 2
rt2/frame/stdFrame.go

@@ -50,6 +50,7 @@ func (f *RootFrame) Top() (frame Frame) {
 }
 }
 
 
 func (f *RootFrame) Do() (res WAIT) {
 func (f *RootFrame) Do() (res WAIT) {
+	var trapped bool
 	if f.Top() != nil {
 	if f.Top() != nil {
 		x := f.Top()
 		x := f.Top()
 		//цикл дейкстры
 		//цикл дейкстры
@@ -60,7 +61,9 @@ func (f *RootFrame) Do() (res WAIT) {
 				break
 				break
 			} else if wait == NOW {
 			} else if wait == NOW {
 			} else if wait == WRONG {
 			} else if wait == WRONG {
-				panic("something wrong")
+				trapped = true
+				break
+				//panic("something wrong") do nothing, it's a trap
 			} else if wait == STOP {
 			} else if wait == STOP {
 				if x == f.Top() {
 				if x == f.Top() {
 					f.Pop()
 					f.Pop()
@@ -73,7 +76,7 @@ func (f *RootFrame) Do() (res WAIT) {
 			}
 			}
 		}
 		}
 	}
 	}
-	if f.Top() != nil {
+	if f.Top() != nil && !trapped {
 		res = NOW
 		res = NOW
 	} else {
 	} else {
 		res = STOP
 		res = STOP

+ 6 - 1
rt2/nodeframe/frame.go

@@ -1,6 +1,7 @@
 package nodeframe
 package nodeframe
 
 
 import (
 import (
+	"fmt"
 	"fw/cp/node"
 	"fw/cp/node"
 	"fw/rt2/context"
 	"fw/rt2/context"
 	"fw/rt2/decision"
 	"fw/rt2/decision"
@@ -58,7 +59,11 @@ func (f *nodeFrame) Do() frame.WAIT {
 		assert.For(ret != frame.STOP, 40)
 		assert.For(ret != frame.STOP, 40)
 		f.seq = next
 		f.seq = next
 	} else {
 	} else {
-		assert.For(ret == frame.STOP, 41)
+		assert.For(ret == frame.STOP || ret == frame.WRONG, 41)
+		if ret == frame.WRONG {
+			fmt.Println("stopped by signal")
+		}
+
 	}
 	}
 	return ret
 	return ret
 }
 }

+ 77 - 4
rt2/rules/op.go

@@ -14,6 +14,19 @@ import (
 	"ypk/assert"
 	"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) {
 func int32Of(x interface{}) (a int32) {
 	//fmt.Println(reflect.TypeOf(x))
 	//fmt.Println(reflect.TypeOf(x))
 	switch x.(type) {
 	switch x.(type) {
@@ -68,6 +81,20 @@ func leq(_a interface{}, _b interface{}) bool {
 	return a <= 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 length(a object.Object, _a, _b interface{}) (ret int64) {
 func length(a object.Object, _a, _b interface{}) (ret int64) {
 	//assert.For(a != nil, 20)
 	//assert.For(a != nil, 20)
 	assert.For(_b != nil, 21)
 	assert.For(_b != nil, 21)
@@ -75,9 +102,9 @@ func length(a object.Object, _a, _b interface{}) (ret int64) {
 	assert.For(b == 0, 22)
 	assert.For(b == 0, 22)
 	if a != nil {
 	if a != nil {
 		assert.For(a.Type() == object.COMPLEX, 23)
 		assert.For(a.Type() == object.COMPLEX, 23)
-		switch a.Complex().(type) {
+		switch typ := a.Complex().(type) {
 		case object.ArrayType:
 		case object.ArrayType:
-			ret = a.Complex().(object.ArrayType).Len()
+			ret = typ.Len()
 		case object.DynArrayType:
 		case object.DynArrayType:
 			switch _a.(type) {
 			switch _a.(type) {
 			case string:
 			case string:
@@ -102,6 +129,19 @@ func length(a object.Object, _a, _b interface{}) (ret int64) {
 
 
 func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	var fu nodeframe.FrameUtils
 	var fu nodeframe.FrameUtils
+
+	op := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		n := fu.NodeOf(f)
+		switch n.(node.OperationNode).Operation() {
+		case operation.NOT:
+			fu.DataOf(f.Parent())[n] = not(fu.DataOf(f)[n.Left()])
+			return frame.End()
+		default:
+			panic("no such op")
+		}
+
+	}
+
 	n := fu.NodeOf(f).(node.MonadicNode)
 	n := fu.NodeOf(f).(node.MonadicNode)
 	switch n.Operation() {
 	switch n.Operation() {
 	case operation.CONVERT:
 	case operation.CONVERT:
@@ -124,12 +164,42 @@ func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			return frame.End()
 			return frame.End()
 		default:
 		default:
 			panic(fmt.Sprintln("unsupported left", reflect.TypeOf(n.Left())))
 			panic(fmt.Sprintln("unsupported left", reflect.TypeOf(n.Left())))
-
+		}
+	case operation.NOT:
+		switch n.Left().(type) {
+		case node.ConstantNode:
+			fu.DataOf(f)[n.Left()] = n.Left().(node.ConstantNode).Data()
+			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.Left()] = sc.Select(scope.Id(n.Left().Object()))
+				return op, frame.NOW
+			}
+			ret = frame.NOW
+			return seq, ret
+		case node.OperationNode, node.DerefNode:
+			fu.Push(fu.New(n.Left()), f)
+			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+				return op, frame.NOW
+			}
+			ret = frame.LATER
+			return seq, ret
+		case node.FieldNode:
+			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(scope.Id(n.Left()))
+				return op, frame.NOW
+			}
+			ret = frame.NOW
+			return seq, ret
+		default:
+			fmt.Println(reflect.TypeOf(n.Left()))
+			panic("wrong left")
 		}
 		}
 	default:
 	default:
 		panic(fmt.Sprintln("no such operation", n.(node.MonadicNode).Operation()))
 		panic(fmt.Sprintln("no such operation", n.(node.MonadicNode).Operation()))
 	}
 	}
-
 }
 }
 
 
 func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
@@ -156,6 +226,9 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case operation.LEN:
 		case operation.LEN:
 			fu.DataOf(f.Parent())[n] = length(n.Left().Object(), fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
 			fu.DataOf(f.Parent())[n] = length(n.Left().Object(), fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
 			return frame.End()
 			return frame.End()
+		case operation.NOT_EQUAL:
+			fu.DataOf(f.Parent())[n] = neq(fu.DataOf(f)[n.Left()], fu.DataOf(f)[n.Right()])
+			return frame.End()
 		default:
 		default:
 			panic("unknown operation")
 			panic("unknown operation")
 		}
 		}

+ 13 - 2
rt2/rules/table.go

@@ -9,12 +9,13 @@ import (
 	"fw/rt2/frame"
 	"fw/rt2/frame"
 	"fw/rt2/nodeframe"
 	"fw/rt2/nodeframe"
 	"fw/rt2/scope"
 	"fw/rt2/scope"
+	"fw/utils"
 	"reflect"
 	"reflect"
 )
 )
 
 
 func prologue(n node.Node) frame.Sequence {
 func prologue(n node.Node) frame.Sequence {
 	//fmt.Println(reflect.TypeOf(n))
 	//fmt.Println(reflect.TypeOf(n))
-	switch n.(type) {
+	switch next := n.(type) {
 	case node.EnterNode:
 	case node.EnterNode:
 		return enterSeq
 		return enterSeq
 	case node.AssignNode:
 	case node.AssignNode:
@@ -50,6 +51,16 @@ func prologue(n node.Node) frame.Sequence {
 		return frame.Tail(frame.STOP)
 		return frame.Tail(frame.STOP)
 	case node.IndexNode:
 	case node.IndexNode:
 		return indexSeq
 		return indexSeq
+	case node.TrapNode:
+		return func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+			switch code := next.Left().(type) {
+			case node.ConstantNode:
+				utils.PrintTrap("TRAP:", code.Data())
+				return frame.Tail(frame.WRONG), frame.NOW
+			default:
+				panic(fmt.Sprintln("unsupported code", reflect.TypeOf(code)))
+			}
+		}
 	default:
 	default:
 		panic(fmt.Sprintln("unknown node", reflect.TypeOf(n)))
 		panic(fmt.Sprintln("unknown node", reflect.TypeOf(n)))
 	}
 	}
@@ -74,7 +85,7 @@ func epilogue(n node.Node) frame.Sequence {
 			sm.Dispose(n)
 			sm.Dispose(n)
 			return frame.End()
 			return frame.End()
 		}
 		}
-	case node.OperationNode, node.ReturnNode, node.IfNode, node.LoopNode, node.DerefNode, node.IndexNode:
+	case node.OperationNode, node.ReturnNode, node.IfNode, node.LoopNode, node.DerefNode, node.IndexNode, node.TrapNode:
 		return nil
 		return nil
 	default:
 	default:
 		fmt.Println(reflect.TypeOf(n))
 		fmt.Println(reflect.TypeOf(n))

+ 7 - 0
utils/debug.go

@@ -4,6 +4,7 @@ import "fmt"
 
 
 var debugFrame = false
 var debugFrame = false
 var debugScope = true
 var debugScope = true
+var debugTrap = true
 
 
 func PrintFrame(x ...interface{}) {
 func PrintFrame(x ...interface{}) {
 	if debugFrame {
 	if debugFrame {
@@ -16,3 +17,9 @@ func PrintScope(x ...interface{}) {
 		fmt.Println(x[0], x[1])
 		fmt.Println(x[0], x[1])
 	}
 	}
 }
 }
+
+func PrintTrap(x ...interface{}) {
+	if debugTrap {
+		fmt.Println(x[0], x[1])
+	}
+}

+ 6 - 0
xev/converter.go

@@ -322,6 +322,8 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 				ret.(node.OperationNode).SetOperation(operation.LESS_EQUAL)
 				ret.(node.OperationNode).SetOperation(operation.LESS_EQUAL)
 			case "len":
 			case "len":
 				ret.(node.OperationNode).SetOperation(operation.LEN)
 				ret.(node.OperationNode).SetOperation(operation.LEN)
+			case "not equal":
+				ret.(node.OperationNode).SetOperation(operation.NOT_EQUAL)
 			default:
 			default:
 				panic(fmt.Sprintln("no such operation", n.Data.Nod.Operation))
 				panic(fmt.Sprintln("no such operation", n.Data.Nod.Operation))
 			}
 			}
@@ -354,6 +356,8 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 			case "convert":
 			case "convert":
 				ret.(node.OperationNode).SetOperation(operation.CONVERT)
 				ret.(node.OperationNode).SetOperation(operation.CONVERT)
 				initType(n.Data.Nod.Typ, ret.(node.MonadicNode))
 				initType(n.Data.Nod.Typ, ret.(node.MonadicNode))
+			case "not":
+				ret.(node.OperationNode).SetOperation(operation.NOT)
 			default:
 			default:
 				panic("no such operation")
 				panic("no such operation")
 			}
 			}
@@ -377,6 +381,8 @@ func (r *Result) buildNode(n *Node) (ret node.Node) {
 			ret = node.New(node.INIT)
 			ret = node.New(node.INIT)
 		case "index":
 		case "index":
 			ret = node.New(constant.INDEX)
 			ret = node.New(constant.INDEX)
+		case "trap":
+			ret = node.New(constant.TRAP)
 		default:
 		default:
 			fmt.Println(n.Data.Nod.Class)
 			fmt.Println(n.Data.Nod.Class)
 			panic("no such node type")
 			panic("no such node type")

Some files were not shown because too many files changed in this diff