Selaa lähdekoodia

добавил вывод трэпа при nil deref, а еще короткие булевы операции

kpmy 10 vuotta sitten
vanhempi
commit
c81fc2b617
13 muutettua tiedostoa jossa 121 lisäystä ja 29 poistoa
  1. BIN
      code/XevConsole.oz
  2. BIN
      code/XevTest0.oz
  3. 24 0
      cp/traps/t.go
  4. 1 1
      fw.go
  5. 7 1
      rt2/rules/deref.go
  6. 1 8
      rt2/rules/guard.go
  7. 6 1
      rt2/rules/if.go
  8. 38 7
      rt2/rules/op.go
  9. 2 2
      rt2/rules/table.go
  10. 19 0
      rt2/rules/trap.go
  11. 11 0
      rt2/scope/modern/val.go
  12. 8 7
      xev/cmds.go
  13. 4 2
      xev/loader.go

BIN
code/XevConsole.oz


BIN
code/XevTest0.oz


+ 24 - 0
cp/traps/t.go

@@ -0,0 +1,24 @@
+package traps
+
+import (
+	"strconv"
+)
+
+type TRAP int
+
+const (
+	Default TRAP = iota
+	NILderef
+)
+
+func This(i interface{}) TRAP { return TRAP(i.(int32)) }
+func (t TRAP) String() string {
+	switch t {
+	case Default:
+		return ""
+	case NILderef:
+		return "NIL dereference"
+	default:
+		return strconv.Itoa(int(t))
+	}
+}

+ 1 - 1
fw.go

@@ -32,7 +32,7 @@ func close() {
 func main() {
 	flag.Parse()
 	if name == "" {
-		name = "XevTest0"
+		name = "XevDemo19"
 	}
 	global := &stdDomain{god: true}
 	global.global = global

+ 7 - 1
rt2/rules/deref.go

@@ -3,6 +3,7 @@ package rules
 import (
 	"fw/cp/node"
 	"fw/cp/object"
+	"fw/cp/traps"
 	"fw/rt2"
 	"fw/rt2/context"
 	"fw/rt2/frame"
@@ -23,8 +24,13 @@ func derefSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				ptr, ok := v.(scope.Pointer)
 				assert.For(ok, 60, reflect.TypeOf(v))
 				rt2.ValueOf(f.Parent())[n.Adr()] = ptr.Get()
+				if scope.GoTypeFrom(ptr.Get()) == nil {
+					seq, ret = doTrap(f, traps.NILderef)
+				} else {
+					seq, ret = frame.End()
+				}
 			})
-			return frame.End()
+			return seq, ret
 		default:
 			halt.As(100, l.Adr(), reflect.TypeOf(l))
 		}

+ 1 - 8
rt2/rules/guard.go

@@ -2,8 +2,6 @@ package rules
 
 import (
 	"fmt"
-	"fw/cp"
-	"fw/cp/constant"
 	"fw/cp/node"
 	"fw/rt2"
 	"fw/rt2/context"
@@ -26,11 +24,6 @@ func guardSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		rt2.RegOf(f.Parent())[n] = n.Left()
 		return frame.End()
 	} else {
-		trap := node.New(constant.TRAP, int(cp.SomeAdr())).(node.TrapNode)
-		code := node.New(constant.CONSTANT, int(cp.SomeAdr())).(node.ConstantNode)
-		code.SetData(0)
-		trap.SetLeft(code)
-		rt2.Push(rt2.New(trap), f)
-		return frame.Tail(frame.STOP), frame.LATER
+		return doTrap(f, 0)
 	}
 }

+ 6 - 1
rt2/rules/if.go

@@ -11,7 +11,7 @@ import (
 
 func ifExpr(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 	n := rt2.NodeOf(f)
-	switch n.Left().(type) {
+	switch l := n.Left().(type) {
 	case node.OperationNode:
 		rt2.Push(rt2.New(n.Left()), f)
 		seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
@@ -20,6 +20,11 @@ func ifExpr(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			return frame.End()
 		}
 		ret = frame.LATER
+	case node.ConstantNode, node.VariableNode, node.ParameterNode:
+		return This(expectExpr(f, l, func(...IN) OUT {
+			rt2.ValueOf(f.Parent())[n.Adr()] = rt2.ValueOf(f)[l.Adr()]
+			return End()
+		}))
 	default:
 		panic(fmt.Sprintf("unknown condition expression", reflect.TypeOf(n.Left())))
 	}

+ 38 - 7
rt2/rules/op.go

@@ -208,7 +208,7 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 
 	right := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		n := rt2.NodeOf(f)
-		switch n.Right().(type) {
+		switch r := n.Right().(type) {
 		case node.ConstantNode:
 			rt2.ValueOf(f)[n.Right().Adr()] = sc.Provide(n.Right())(nil)
 			return op, frame.NOW
@@ -219,8 +219,12 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			}
 			ret = frame.NOW
 			return seq, ret
-		case node.OperationNode, node.DerefNode:
+		case node.OperationNode, node.DerefNode, node.CallNode:
 			rt2.Push(rt2.New(n.Right()), f)
+			rt2.Assert(f, func(f frame.Frame) (bool, int) {
+				return rt2.ValueOf(f)[r.Adr()] != nil, 60
+			})
+
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				return op, frame.NOW
 			}
@@ -241,23 +245,50 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		}
 	}
 
+	short := func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+		n := rt2.NodeOf(f).(node.OperationNode)
+		switch n.Operation() {
+		case operation.AND:
+			val := scope.GoTypeFrom(rt2.ValueOf(f)[n.Left().Adr()]).(bool)
+			if val {
+				return right, frame.NOW
+			} else {
+				rt2.ValueOf(f.Parent())[n.Adr()] = scope.TypeFromGo(false)
+				return frame.End()
+			}
+		case operation.OR:
+			val := scope.GoTypeFrom(rt2.ValueOf(f)[n.Left().Adr()]).(bool)
+			if !val {
+				return right, frame.NOW
+			} else {
+				rt2.ValueOf(f.Parent())[n.Adr()] = scope.TypeFromGo(true)
+				return frame.End()
+			}
+		default:
+			return right, frame.NOW
+		}
+	}
+
 	left := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		n := rt2.NodeOf(f)
 		switch l := n.Left().(type) {
 		case node.ConstantNode:
 			rt2.ValueOf(f)[n.Left().Adr()] = sc.Provide(n.Left())(nil)
-			return right, frame.NOW
+			return short, frame.NOW
 		case node.VariableNode, node.ParameterNode:
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				rt2.ValueOf(f)[n.Left().Adr()] = sc.Select(n.Left().Object().Adr())
-				return right, frame.NOW
+				return short, frame.NOW
 			}
 			ret = frame.NOW
 			return seq, ret
-		case node.OperationNode, node.DerefNode, node.RangeNode:
+		case node.OperationNode, node.DerefNode, node.RangeNode, node.CallNode:
 			rt2.Push(rt2.New(n.Left()), f)
+			rt2.Assert(f, func(f frame.Frame) (bool, int) {
+				return rt2.ValueOf(f)[l.Adr()] != nil, 60
+			})
 			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
-				return right, frame.NOW
+				return short, frame.NOW
 			}
 			ret = frame.LATER
 			return seq, ret
@@ -267,7 +298,7 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 				sc.Select(l.Left().Object().Adr(), func(v scope.Value) {
 					rt2.ValueOf(f)[n.Left().Adr()] = v.(scope.Record).Get(l.Object().Adr())
 				})
-				return right, frame.NOW
+				return short, frame.NOW
 			}
 			ret = frame.NOW
 			return seq, ret

+ 2 - 2
rt2/rules/table.go

@@ -5,12 +5,12 @@ import (
 	"fmt"
 	"fw/cp/module"
 	"fw/cp/node"
+	"fw/cp/traps"
 	"fw/rt2"
 	"fw/rt2/context"
 	"fw/rt2/decision"
 	"fw/rt2/frame"
 	"fw/rt2/frame/std"
-	//	rt_module "fw/rt2/module"
 	"fw/rt2/scope"
 	"fw/utils"
 	"reflect"
@@ -62,7 +62,7 @@ func prologue(n node.Node) frame.Sequence {
 		return func(f frame.Frame) (frame.Sequence, frame.WAIT) {
 			switch code := next.Left().(type) {
 			case node.ConstantNode:
-				utils.PrintTrap("TRAP:", code.Data())
+				utils.PrintTrap("TRAP:", traps.This(code.Data()))
 				return frame.Tail(frame.WRONG), frame.NOW
 			default:
 				panic(fmt.Sprintln("unsupported code", reflect.TypeOf(code)))

+ 19 - 0
rt2/rules/trap.go

@@ -0,0 +1,19 @@
+package rules
+
+import (
+	"fw/cp"
+	"fw/cp/constant"
+	"fw/cp/node"
+	"fw/cp/traps"
+	"fw/rt2"
+	"fw/rt2/frame"
+)
+
+func doTrap(f frame.Frame, err traps.TRAP) (frame.Sequence, frame.WAIT) {
+	trap := node.New(constant.TRAP, int(cp.SomeAdr())).(node.TrapNode)
+	code := node.New(constant.CONSTANT, int(cp.SomeAdr())).(node.ConstantNode)
+	code.SetData(int32(err))
+	trap.SetLeft(code)
+	rt2.Push(rt2.New(trap), f)
+	return frame.Tail(frame.STOP), frame.LATER
+}

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

@@ -520,6 +520,8 @@ func gfrom(v scope.Value) interface{} {
 		} else {
 			return gfrom(n.val.(scope.Value))
 		}
+	case *rec:
+		return n
 	case *proc:
 		return n.link
 	case *dynarr:
@@ -530,6 +532,12 @@ func gfrom(v scope.Value) interface{} {
 			} else {
 				return ""
 			}
+		case object.CHAR:
+			if n.val != nil {
+				return n.tryString()
+			} else {
+				return ""
+			}
 		default:
 			halt.As(100, n.link.Complex().(object.DynArrayType).Base())
 		}
@@ -546,6 +554,9 @@ func gfrom(v scope.Value) interface{} {
 			halt.As(100, n.link.Complex().(object.ArrayType).Base())
 		}
 		panic(0)
+	case PTR:
+		assert.For(n == NIL, 40)
+		return nil
 	case INTEGER:
 		return int32(n)
 	case BOOLEAN:

+ 8 - 7
xev/cmds.go

@@ -4,7 +4,7 @@ import (
 	"archive/zip"
 	"fmt"
 	"fw/cp/module"
-	"io/ioutil"
+	"io"
 	"path/filepath"
 	"ypk/assert"
 )
@@ -13,20 +13,21 @@ const CODE = "code"
 
 func Load(path, name string) (ret *module.Module) {
 	fmt.Println(path + ` ` + name)
-	var data []byte
+	//var data []byte
+	var rd io.Reader
 	r, err := zip.OpenReader(filepath.Join(path, CODE, name))
 	assert.For(err == nil, 40)
 	for _, f := range r.File {
 		if f.Name == CODE {
-			r, _ := f.Open()
-			data, _ = ioutil.ReadAll(r)
+			rd, _ = f.Open()
+			//data, _ = ioutil.ReadAll(r)
 		}
 	}
 	//data, _ = ioutil.ReadFile(filepath.Join(path, CODE, name))
-	fmt.Println(len(data))
-	if data != nil {
-		result := LoadOXF(data)
+	if r != nil {
+		result := LoadOXF(rd)
 		ret = DoAST(result)
+		fmt.Println("load", len(ret.Nodes), "nodes")
 	}
 	return ret
 }

+ 4 - 2
xev/loader.go

@@ -3,6 +3,7 @@ package xev
 import (
 	"encoding/xml"
 	"fmt"
+	"io"
 )
 
 type CptType struct {
@@ -104,9 +105,10 @@ func traverse(r *Result) {
 	}
 }
 
-func LoadOXF(data []byte) *Result {
+func LoadOXF(rd io.Reader) *Result {
 	r := new(Result)
-	err := xml.Unmarshal(data, r)
+	dec := xml.NewDecoder(rd)
+	err := dec.Decode(r)
 	if err == nil {
 		//fmt.Println(len(r.GraphList))
 		//traverse(r)