Browse Source

добавил примеры на математические правила и массив строк.
на очереди сравнение строк

kpmy 10 years ago
parent
commit
d95123dee4

BIN
code/XevConsole.oz


BIN
code/XevCore.oz


BIN
code/XevInit.oz


BIN
code/XevLog.oz


BIN
code/XevStrings.oz


BIN
code/XevTest0.oz


BIN
code/XevTest1.oz


BIN
code/XevTest2.oz


BIN
code/XevTestMath.oz


BIN
code/XevTestStrings.oz


BIN
code/XevXLog.oz


+ 10 - 0
cp/object/type.go

@@ -106,6 +106,7 @@ type ArrayType interface {
 	ComplexType
 	Base() Type
 	Len() int64
+	Complex(...ComplexType) ComplexType
 }
 
 type DynArrayType interface {
@@ -163,10 +164,19 @@ type arr struct {
 	comp
 	base   Type
 	length int64
+	cmp    ComplexType
 }
 
 func (a *arr) Base() Type { return a.base }
 func (a *arr) Len() int64 { return a.length }
+func (a *arr) Complex(t ...ComplexType) ComplexType {
+	if len(t) == 1 {
+		a.cmp = t[0]
+	} else if len(t) > 1 {
+		panic("too many args")
+	}
+	return a.cmp
+}
 
 type rec struct {
 	comp

+ 1 - 1
rt2/rules/call.go

@@ -68,7 +68,7 @@ func process(f frame.Frame, par node.Node) (frame.Sequence, frame.WAIT) {
 				case "core":
 					switch msg.Command {
 					case "load":
-						fmt.Println("try to load", msg.Data)
+						//fmt.Println("try to load", msg.Data)
 						glob := f.Domain().Discover(context.UNIVERSE).(context.Domain)
 						modList := glob.Discover(context.MOD).(rtm.List)
 						fl := glob.Discover(context.MT).(*flow)

+ 6 - 3
rt2/rules/case.go

@@ -17,18 +17,21 @@ func caseSeq(f frame.Frame) (frame.Sequence, frame.WAIT) {
 	in := func(in ...IN) (out OUT) {
 		cond := n.Right().(node.ElseNode)
 		if e < cond.Min() || e > cond.Max() { //case?
+			if cond.Right() != nil {
+				rt2.Push(rt2.New(cond.Right()), f)
+			}
 			out.do = Tail(STOP)
-			out.next = NOW
+			out.next = LATER
 		} else {
 			for next := cond.Left(); next != nil && out.do == nil; next = next.Link() {
 				var ok bool
 				for _c := next.Left(); _c != nil && !ok; _c = _c.Right() {
 					c := _c.(node.ConstantNode)
 					if (c.Min() != nil) && (c.Max() != nil) {
-						//	fmt.Println(e, *c.Max(), *c.Min())
+						//fmt.Println(e, *c.Max(), *c.Min())
 						ok = e >= *c.Min() && e <= *c.Max()
 					} else {
-						//	fmt.Println(e, c.Data())
+						//fmt.Println(e, c.Data())
 						ok = int32Of(c.Data()) == int32(e)
 					}
 				}

+ 10 - 1
rt2/rules/deref.go

@@ -38,7 +38,16 @@ func derefSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		if n.Left().Object() != nil {
 			switch l := n.Left().Object().(type) {
 			case object.ParameterObject, object.VariableObject:
-				rt2.ValueOf(f.Parent())[n.Adr()] = sc.Select(l.Adr())
+				val := sc.Select(l.Adr())
+				_, c := scope.Ops.TypeOf(val)
+				switch cc := c.(type) {
+				case object.ArrayType:
+					rt2.ValueOf(f.Parent())[n.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(val))
+				case object.DynArrayType:
+					rt2.ValueOf(f.Parent())[n.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(val))
+				default:
+					halt.As(100, reflect.TypeOf(cc))
+				}
 				return frame.End()
 			default:
 				halt.As(100, l.Adr(), reflect.TypeOf(l))

+ 3 - 3
rt2/rules/enter.go

@@ -1,13 +1,13 @@
 package rules
 
 import (
-	"fmt"
 	"fw/cp/node"
 	"fw/rt2"
 	"fw/rt2/context"
 	"fw/rt2/frame"
 	"fw/rt2/module"
 	"fw/rt2/scope"
+	"fw/utils"
 )
 
 func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
@@ -27,12 +27,12 @@ func enterSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		} else {
 			//Особый случай, вход в модуль, секция BEGIN
 			rt2.Push(rt2.New(body), f)
-			fmt.Println("begin", module.DomainModule(f.Domain()).Name)
+			utils.PrintFrame("begin", module.DomainModule(f.Domain()).Name)
 			//Выход из модуля, секция CLOSE
 			next := n.Link()
 			if next != nil {
 				seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
-					fmt.Println("end", module.DomainModule(f.Domain()).Name)
+					utils.PrintFrame("end", module.DomainModule(f.Domain()).Name)
 					f.Root().PushFor(rt2.New(next), f)
 					return frame.Tail(frame.STOP), frame.END
 				}

+ 10 - 13
rt2/rules/expect.go

@@ -5,7 +5,7 @@ import (
 	"fw/cp/node"
 	"fw/rt2"
 	"fw/rt2/frame"
-	//	"fw/rt2/scope"
+	"fw/rt2/scope"
 	"reflect"
 	"ypk/assert"
 )
@@ -31,21 +31,18 @@ func expectExpr(parent frame.Frame, expr node.Node, next Do) OUT {
 		}
 		return OUT{do: wait, next: LATER}
 	case node.IndexNode:
-		/*id := scope.Designator(expr)
-		rt2.Push(rt2.New(expr), parent)
+		rt2.Push(rt2.New(e), parent)
+		rt2.Assert(parent, func(f frame.Frame) (bool, int) {
+			return rt2.ValueOf(f)[e.Adr()] != nil, 64
+		})
 		wait := func(...IN) OUT {
-			if rt2.DataOf(parent)[expr] == nil {
-				panic("no result")
-			} else {
-				id.Index = new(int64)
-				*id.Index = int64(rt2.DataOf(parent)[expr].(int32))
-				rt2.DataOf(parent)[expr] = sm.Select(id)
-			}
+			idx := rt2.ValueOf(parent)[e.Adr()]
+			arr := sm.Select(e.Left().Object().Adr()).(scope.Array)
+			idx = arr.Get(idx)
+			rt2.ValueOf(parent)[e.Adr()] = idx
 			return OUT{do: next, next: NOW}
 		}
-		return OUT{do: wait, next: LATER}*/
-		panic(0)
-		return End()
+		return OUT{do: wait, next: LATER}
 	case node.ProcedureNode:
 		rt2.RegOf(parent)[expr] = e.Object()
 		return OUT{do: next, next: NOW}

+ 6 - 1
rt2/rules/op.go

@@ -55,6 +55,9 @@ func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 		case operation.BITS:
 			rt2.ValueOf(f.Parent())[n.Adr()] = scope.Ops.Bits(rt2.ValueOf(f)[n.Left().Adr()])
 			return frame.End()
+		case operation.MINUS:
+			rt2.ValueOf(f.Parent())[n.Adr()] = scope.Ops.Minus(rt2.ValueOf(f)[n.Left().Adr()])
+			return frame.End()
 		default:
 			panic("no such op")
 		}
@@ -128,7 +131,7 @@ func mopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			fmt.Println(reflect.TypeOf(n.Left()))
 			panic("wrong left")
 		}
-	case operation.ABS, operation.ODD, operation.CAP, operation.BITS:
+	case operation.ABS, operation.ODD, operation.CAP, operation.BITS, operation.MINUS:
 		return This(expectExpr(f, n.Left(), Expose(op)))
 	default:
 		panic(fmt.Sprintln("no such operation", n.(node.MonadicNode).Operation()))
@@ -299,6 +302,8 @@ func dopSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
 			}
 			ret = frame.NOW
 			return seq, ret
+		case node.IndexNode:
+			return This(expectExpr(f, n.Left(), Expose(short)))
 		default:
 			fmt.Println(reflect.TypeOf(n.Left()))
 			panic("wrong left")

+ 2 - 2
rt2/rules/table.go

@@ -196,12 +196,12 @@ func (f *flow) Do() (ret frame.WAIT) {
 func (f *flow) OnPush(root frame.Stack, parent frame.Frame) {
 	f.root = root
 	f.parent = parent
-	fmt.Println("flow control pushed")
+	//fmt.Println("flow control pushed")
 	f.this = len(f.fl) - 1
 }
 
 func (f *flow) OnPop() {
-	fmt.Println("flow control poped")
+	//fmt.Println("flow control poped")
 }
 
 func (f *flow) Parent() frame.Frame    { return f.parent }

+ 1 - 0
rt2/scope/data.go

@@ -30,6 +30,7 @@ type Operations interface {
 	Odd(Value) Value
 	Cap(Value) Value
 	Bits(Value) Value //это не BITS из КП, BITS(x) = {x}
+	Minus(Value) Value
 
 	Is(Value, object.ComplexType) Value
 	Conv(Value, object.Type, ...object.ComplexType) Value

+ 6 - 2
rt2/scope/modern/ms.go

@@ -98,7 +98,11 @@ func (l *level) alloc(mod *cpm.Module, root node.Node, ol []object.Object, skip
 			switch x := o.(type) {
 			case object.VariableObject, object.FieldObject:
 				switch t := o.Complex().(type) {
-				case nil, object.BasicType, object.ArrayType, object.DynArrayType:
+				case nil, object.BasicType:
+					l.v[l.next] = newData(x)
+					l.k[x.Adr()] = l.next
+					l.next++
+				case object.ArrayType, object.DynArrayType:
 					l.v[l.next] = newData(x)
 					l.k[x.Adr()] = l.next
 					l.next++
@@ -247,7 +251,7 @@ func (a *salloc) Initialize(n node.Node, par scope.PARAM) (seq frame.Sequence, r
 					return end, frame.NOW
 				}
 				ret = frame.LATER
-			case node.FieldNode:
+			case node.FieldNode, node.DerefNode:
 				nf := rt2.New(nv)
 				rt2.Push(nf, f)
 				rt2.Assert(f, func(f frame.Frame) (bool, int) {

+ 133 - 30
rt2/scope/modern/val.go

@@ -117,15 +117,17 @@ func (a *dynarr) Set(v scope.Value) {
 	case *dynarr:
 		a.val = x.val
 	case STRING:
-		v := make([]interface{}, len(x))
-		for i := 0; i < len(x); i++ {
-			v[i] = CHAR(x[i])
+		z := []rune(string(x))
+		v := make([]interface{}, len(z))
+		for i := 0; i < len(z); i++ {
+			v[i] = CHAR(z[i])
 		}
 		a.val = v
 	case SHORTSTRING:
-		v := make([]interface{}, len(x))
-		for i := 0; i < len(x); i++ {
-			v[i] = SHORTCHAR(x[i])
+		z := []rune(string(x))
+		v := make([]interface{}, len(z))
+		for i := 0; i < len(z); i++ {
+			v[i] = SHORTCHAR(z[i])
 		}
 		a.val = v
 	case INTEGER:
@@ -136,18 +138,19 @@ func (a *dynarr) Set(v scope.Value) {
 }
 
 func (a *arr) tryString() (ret string) {
-	for i := 0; i < len(a.val) && a.val[i] != nil; i++ {
+	stop := false
+	for i := 0; !stop && i < len(a.val) && a.val[i] != nil; i++ {
 		switch x := a.val[i].(type) {
 		case CHAR:
-			if int(x) == 0 {
-				break
+			stop = int(x) == 0
+			if !stop {
+				ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 			}
-			ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 		case SHORTCHAR:
-			if int(x) == 0 {
-				break
+			stop = int(x) == 0
+			if !stop {
+				ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 			}
-			ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 		default:
 			halt.As(100, reflect.TypeOf(x))
 		}
@@ -170,6 +173,7 @@ func (a *arr) String() (ret string) {
 	return ret
 }
 
+//возвращает *idx
 func (a *arr) Get(id scope.Value) scope.Value {
 	switch i := id.(type) {
 	case *data:
@@ -195,7 +199,7 @@ func (i *idx) String() string {
 }
 
 func (i *idx) Set(v scope.Value) {
-	//fmt.Println(i, len(i.arr.val))
+	t := i.arr.link.Complex()
 	switch x := v.(type) {
 	case *idx:
 		i.arr.val[i.idx] = x.arr.val[x.idx]
@@ -203,24 +207,47 @@ func (i *idx) Set(v scope.Value) {
 		i.Set(x.val.(scope.Value))
 	case CHAR:
 		i.arr.val[i.idx] = x
+	case STRING:
+		_ = t.(object.ArrayType)
+		i.arr.val[i.idx].(*arr).Set(x)
 	default:
-		halt.As(100, reflect.TypeOf(x))
+		halt.As(100, reflect.TypeOf(x), x, t)
 	}
 }
 
+func (i *idx) Get() scope.Value {
+	x := i.arr.val[i.idx]
+	switch z := x.(type) {
+	case CHAR:
+		return z
+	case nil:
+		b := i.arr.link.Complex().(object.ArrayType).Base()
+		switch b {
+		case object.CHAR:
+			return CHAR(rune(0))
+		default:
+			halt.As(101, reflect.TypeOf(b))
+		}
+	default:
+		halt.As(100, i.idx, reflect.TypeOf(z))
+	}
+	panic(0)
+}
+
 func (a *dynarr) tryString() (ret string) {
-	for i := 0; i < len(a.val) && a.val[i] != nil; i++ {
+	stop := false
+	for i := 0; !stop && i < len(a.val) && a.val[i] != nil; i++ {
 		switch x := a.val[i].(type) {
 		case CHAR:
-			if int(x) == 0 {
-				break
+			stop = int(x) == 0
+			if !stop {
+				ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 			}
-			ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 		case SHORTCHAR:
-			if int(x) == 0 {
-				break
+			stop = int(x) == 0
+			if !stop {
+				ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 			}
-			ret = fmt.Sprint(ret, string([]rune{rune(x)}))
 		default:
 			halt.As(100, reflect.TypeOf(x))
 		}
@@ -420,6 +447,16 @@ func newData(o object.Object) (ret scope.Variable) {
 			}
 		case object.ArrayType:
 			ret = &arr{link: o, length: t.Len()}
+			if a := ret.(*arr); t.Base() == object.COMPLEX {
+				a.val = make([]interface{}, int(t.Len()))
+				for i := 0; i < int(t.Len()); i++ {
+					fake := object.New(object.VARIABLE, int(cp.SomeAdr()))
+					fake.SetName("[?]")
+					fake.SetType(object.COMPLEX)
+					fake.SetComplex(t.Complex())
+					a.val[i] = newData(fake)
+				}
+			}
 		case object.DynArrayType:
 			ret = &dynarr{link: o}
 		default:
@@ -440,6 +477,8 @@ func fromg(x interface{}) scope.Value {
 		return BOOLEAN(x)
 	case *big.Int:
 		return SET{bits: x}
+	case string:
+		return STRING(x)
 	default:
 		halt.As(100, reflect.TypeOf(x))
 	}
@@ -517,7 +556,7 @@ func vfrom(v scope.Value) scope.Value {
 		default:
 			halt.As(100, n.link.Type())
 		}
-	case INTEGER:
+	case INTEGER, CHAR:
 		return n
 	default:
 		halt.As(100, reflect.TypeOf(n))
@@ -563,10 +602,24 @@ 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.ArrayType).Base())
 		}
 		panic(0)
+	case *idx:
+		switch n.arr.link.Complex().(object.ArrayType).Base() {
+		case object.CHAR:
+			return rune(n.Get().(CHAR))
+		default:
+			halt.As(100, n.arr.link.Complex().(object.ArrayType).Base())
+		}
+		panic(0)
 	case PTR:
 		assert.For(n == NIL, 40)
 		return nil
@@ -574,6 +627,8 @@ func gfrom(v scope.Value) interface{} {
 		return int32(n)
 	case BOOLEAN:
 		return bool(n)
+	case STRING:
+		return string(n)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -883,7 +938,7 @@ func (o *ops) Div(a, b scope.Value) scope.Value {
 			case INTEGER:
 				switch y := b.(type) {
 				case INTEGER:
-					return INTEGER(x / y)
+					return INTEGER(math.Floor(float64(x) / float64(y)))
 				default:
 					panic(fmt.Sprintln(reflect.TypeOf(y)))
 				}
@@ -915,7 +970,12 @@ func (o *ops) Mod(a, b scope.Value) scope.Value {
 			case INTEGER:
 				switch y := b.(type) {
 				case INTEGER:
-					return INTEGER(x % y)
+					z := x % y
+					switch {
+					case (x < 0) != (y < 0):
+						z = z + y
+					}
+					return INTEGER(z)
 				default:
 					panic(fmt.Sprintln(reflect.TypeOf(y)))
 				}
@@ -1041,14 +1101,17 @@ func (o *ops) Len(a object.Object, _a, _b scope.Value) (ret scope.Value) {
 		}
 	} else {
 		switch a := _a.(type) {
-		//		case string:
-		//			ret = int64(utf8.RuneCountInString(_a.(string)))
-		//		case []interface{}:
-		//			ret = int64(len(_a.([]interface{})))
 		case *arr:
 			ret = INTEGER(int32(a.length))
 		case *dynarr:
 			ret = INTEGER(int32(len(a.val)))
+		case STRING:
+			rs := []rune(string(a))
+			ln := len(rs)
+			ret = INTEGER(0)
+			for l := 0; l < ln && rs[l] != 0; l++ {
+				ret = INTEGER(l + 1)
+			}
 		default:
 			panic(fmt.Sprintln("unsupported", reflect.TypeOf(a)))
 		}
@@ -1129,6 +1192,17 @@ func (o *ops) Conv(a scope.Value, typ object.Type, comp ...object.ComplexType) s
 		default:
 			halt.As(100, reflect.TypeOf(x))
 		}
+	case object.LONGINT:
+		switch x := a.(type) {
+		case *data:
+			return o.Conv(vfrom(x), typ)
+		case INTEGER:
+			return LONGINT(x)
+		case REAL:
+			return LONGINT(math.Floor(float64(x)))
+		default:
+			halt.As(100, reflect.TypeOf(x))
+		}
 	case object.SET:
 		switch x := a.(type) {
 		case *data:
@@ -1167,6 +1241,8 @@ func (o *ops) Conv(a scope.Value, typ object.Type, comp ...object.ComplexType) s
 					return SHORTSTRING(x.tryString())
 				case *arr:
 					return SHORTSTRING(x.tryString())
+				case STRING:
+					return SHORTSTRING(x)
 				default:
 					halt.As(100, reflect.TypeOf(x))
 				}
@@ -1206,6 +1282,20 @@ func (o *ops) Abs(a scope.Value) scope.Value {
 	panic(100)
 }
 
+func (o *ops) Minus(a scope.Value) scope.Value {
+	switch x := a.(type) {
+	case *data:
+		return o.Minus(vfrom(x))
+	case INTEGER:
+		return INTEGER(-x)
+	case LONGINT:
+		return LONGINT(-x)
+	default:
+		halt.As(100, reflect.TypeOf(x))
+	}
+	panic(100)
+}
+
 func (o *ops) Odd(a scope.Value) scope.Value {
 	switch x := a.(type) {
 	case *data:
@@ -1274,9 +1364,11 @@ func (o *ops) Eq(a, b scope.Value) scope.Value {
 }
 
 func (o *ops) Neq(a, b scope.Value) scope.Value {
-	switch a.(type) {
+	switch i := a.(type) {
 	case *data:
 		return o.Neq(vfrom(a), b)
+	case *idx:
+		return o.Neq(vfrom(i.Get()), b)
 	default:
 		switch b.(type) {
 		case *data:
@@ -1319,6 +1411,13 @@ func (o *ops) Neq(a, b scope.Value) scope.Value {
 				default:
 					panic(fmt.Sprintln(reflect.TypeOf(y)))
 				}
+			case CHAR:
+				switch y := b.(type) {
+				case CHAR:
+					return BOOLEAN(x != y)
+				default:
+					panic(fmt.Sprintln(reflect.TypeOf(y)))
+				}
 			default:
 				panic(fmt.Sprintln(reflect.TypeOf(x)))
 			}
@@ -1442,6 +1541,10 @@ func (o *ops) TypeOf(x scope.Value) (object.Type, object.ComplexType) {
 		}
 	case *rec:
 		return v.link.Type(), v.link.Complex()
+	case *dynarr:
+		return v.link.Type(), v.link.Complex()
+	case *arr:
+		return v.link.Type(), v.link.Complex()
 	default:
 		halt.As(100, reflect.TypeOf(v))
 	}

+ 8 - 1
xev/converter.go

@@ -243,8 +243,15 @@ func (r *Result) doType(n *Node) (ret object.ComplexType) {
 				ret = object.NewArrayType(object.CHAR, int64(n.Data.Typ.Par), n.Id)
 			case "SHORTCHAR":
 				ret = object.NewArrayType(object.SHORTCHAR, int64(n.Data.Typ.Par), n.Id)
+			case "COMPLEX":
+				ret = object.NewArrayType(object.COMPLEX, int64(n.Data.Typ.Par), n.Id)
+				base := r.findLink(n, "base")
+				if base != nil {
+					ret.(object.ArrayType).Complex(r.doType(base))
+					assert.For(ret.(object.ArrayType).Complex() != nil, 41)
+				}
 			default:
-				panic(fmt.Sprintln("unknown array type", n.Data.Typ.Base))
+				panic(fmt.Sprintln("unknown array type", n.Id, n.Data.Typ.Base))
 			}
 		case "RECORD":
 			switch n.Data.Typ.Base {