1
0
Эх сурвалжийг харах

развиваю новый механизм интерпретации

kpmy 10 жил өмнө
parent
commit
1fa1df95da

+ 2 - 2
fw.go

@@ -37,8 +37,8 @@ func main() {
 	flag.Parse()
 	utils.Debug(debug)
 	if name == "" {
-		name = "XevDemo5"
-		utils.Debug(true)
+		name = "XevDemo11"
+		utils.Debug(false)
 	}
 	global := &stdDomain{god: true}
 	global.global = global

+ 156 - 0
rt2/rules2/wrap/eval/call.go

@@ -0,0 +1,156 @@
+package eval
+
+import (
+	"encoding/json"
+	"fmt"
+	"fw/cp"
+	"fw/cp/constant"
+	cpm "fw/cp/module"
+	"fw/cp/node"
+	"fw/cp/object"
+	"fw/rt2"
+	"fw/rt2/context"
+	"fw/rt2/frame"
+	rtm "fw/rt2/module"
+	"fw/rt2/scope"
+	"math"
+	"reflect"
+	"ypk/assert"
+	"ypk/halt"
+	"ypk/mathe"
+)
+
+var sys map[string]func(f frame.Frame, par node.Node) OUT
+
+type Msg struct {
+	Type    string
+	Command string
+	Data    string
+}
+
+func callHandler(f frame.Frame, obj object.Object, data interface{}) {
+	//n := rt2.Utils.NodeOf(f)
+	//fmt.Println("call handler", obj)
+	if obj == nil {
+		return
+	}
+	m := rtm.DomainModule(f.Domain())
+	cn := node.New(constant.CALL, cp.Some())
+	ol := m.NodeByObject(obj)
+	assert.For(len(ol) <= 1, 40)
+	cn.SetLeft(ol[0])
+	cc := node.New(constant.CONSTANT, cp.Some()).(node.ConstantNode)
+	cc.SetData(data)
+	cc.SetType(object.SHORTSTRING)
+	cn.SetRight(cc)
+	rt2.Push(rt2.New(cn), f)
+}
+
+func go_process(f frame.Frame, par node.Node) OUT {
+	assert.For(par != nil, 20)
+	sm := rt2.ThisScope(f)
+	do := func(val string) {
+		if val != "" {
+			msg := &Msg{}
+			if err := json.Unmarshal([]byte(val), msg); err == nil {
+				switch msg.Type {
+				case "log":
+					fmt.Print(msg.Data)
+					callHandler(f, scope.FindObjByName(sm, "go_handler"), `{"type":"log"}`)
+				case "core":
+					switch msg.Command {
+					case "load":
+						panic(0)
+						//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)
+						ml := make([]*cpm.Module, 0)
+						_, err := modList.Load(msg.Data, func(m *cpm.Module) {
+							ml = append(ml, m)
+						})
+						for i := len(ml) - 1; i >= 0; i-- {
+							//							fl.grow(glob, ml[i])
+						}
+						assert.For(err == nil, 60)
+					default:
+						halt.As(100, msg.Command)
+					}
+				default:
+					panic(40)
+				}
+			} else {
+				fmt.Println(val, "not a json")
+			}
+		}
+	}
+	var val string
+	switch p := par.(type) {
+	case node.ConstantNode:
+		val = par.(node.ConstantNode).Data().(string)
+		do(val)
+		return Later(Tail(STOP))
+	case node.VariableNode, node.ParameterNode:
+		val = scope.GoTypeFrom(sm.Select(p.Object().Adr())).(string)
+		do(val)
+		return Later(Tail(STOP))
+	case node.DerefNode:
+		panic(0)
+		rt2.Push(rt2.New(p), f)
+		/*		return This(expectExpr(f, p, func(...IN) (out OUT) {
+				v := rt2.ValueOf(f)[p.Adr()]
+				assert.For(v != nil, 60)
+				val = scope.GoTypeFrom(v).(string)
+				do(val)
+				out.do = Tail(STOP)
+				out.next = LATER
+				return out
+			})) */
+	default:
+		halt.As(100, "unsupported param", reflect.TypeOf(p))
+	}
+	panic(0)
+}
+
+func go_math(f frame.Frame, par node.Node) OUT {
+	const (
+		LN   = 1.0
+		MANT = 2.0
+		EXP  = 3.0
+	)
+	assert.For(par != nil, 20)
+	sm := rt2.ThisScope(f)
+	res := math.NaN()
+	switch p := par.(type) {
+	case node.VariableNode:
+		val := sm.Select(p.Object().Adr())
+		rv, ok := scope.GoTypeFrom(val).([]float64)
+		assert.For(ok && (len(rv) > 1), 100, rv)
+		switch rv[0] {
+		case LN:
+			res = math.Log(rv[1])
+		case MANT:
+			res, _ = mathe.Me(rv[1])
+		case EXP:
+			_, res = mathe.Me(rv[1])
+		default:
+			halt.As(100, rv[0])
+		}
+	default:
+		halt.As(100, reflect.TypeOf(p))
+	}
+	rt2.RegOf(f.Parent())[context.RETURN] = scope.TypeFromGo(res)
+	return End()
+}
+
+func init() {
+	sys = make(map[string]func(f frame.Frame, par node.Node) OUT)
+	sys["go_process"] = go_process
+	sys["go_math"] = go_math
+}
+
+func syscall(f frame.Frame) OUT {
+	n := rt2.NodeOf(f)
+	name := n.Left().Object().Name()
+	return sys[name](f, n.Right())
+}

+ 35 - 2
rt2/rules2/wrap/eval/do.go

@@ -37,6 +37,14 @@ func BeginDesignator(in IN) (out OUT) {
 		out = Now(getVar)
 	case node.ParameterNode:
 		out = Now(getVarPar)
+	case node.ProcedureNode:
+		out = Now(getProc)
+	case node.DerefNode:
+		out = Now(getDeref)
+	case node.FieldNode:
+		out = Now(getField)
+	case node.IndexNode:
+		out = Now(getIndex)
 	default:
 		halt.As(100, reflect.TypeOf(e))
 	}
@@ -130,6 +138,20 @@ func BeginStatement(in IN) (out OUT) {
 		out = Now(doReturn)
 	case node.ConditionalNode:
 		out = Now(doCondition)
+	case node.WhileNode:
+		out = Now(doWhile)
+	case node.RepeatNode:
+		out = Now(doRepeat)
+	case node.LoopNode:
+		out = Now(doLoop)
+	case node.ExitNode:
+		out = Now(doExit)
+	case node.InitNode:
+		out = Later(Tail(STOP))
+	case node.TrapNode:
+		out = Now(doTrap)
+	case node.WithNode:
+		out = Now(doWith)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -155,7 +177,7 @@ func EndStatement(in IN) (out OUT) {
 			}
 			return End()
 		})
-	case node.AssignNode, node.CallNode, node.ConditionalNode:
+	case node.CallNode:
 		out = Now(func(in IN) OUT {
 			next := n.Link()
 			if next != nil {
@@ -178,7 +200,18 @@ func EndStatement(in IN) (out OUT) {
 			}
 			return End()
 		})
-	case node.ReturnNode: //do nothing
+	case node.AssignNode, node.ConditionalNode, node.WhileNode, node.RepeatNode, node.ExitNode, node.InitNode, node.WithNode:
+		out = Now(func(in IN) OUT {
+			next := n.Link()
+			if next != nil {
+				nf := rt2.New(next)
+				if nf != nil {
+					in.Frame.Root().PushFor(nf, in.Parent)
+				}
+			}
+			return End()
+		})
+	case node.ReturnNode, node.LoopNode: //do nothing
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}

+ 103 - 1
rt2/rules2/wrap/eval/expr.go

@@ -1,11 +1,13 @@
 package eval
 
 import (
+	"fmt"
 	"fw/cp/constant/operation"
 	"fw/cp/node"
 	"fw/cp/object"
 	"fw/rt2"
 	"fw/rt2/scope"
+	"reflect"
 	"ypk/assert"
 	"ypk/halt"
 )
@@ -38,6 +40,89 @@ func getVarPar(in IN) OUT {
 	return End()
 }
 
+func getField(in IN) OUT {
+	const left = "field:left"
+	f := in.IR.(node.FieldNode)
+	return GetDesignator(in, left, f.Left(), func(in IN) OUT {
+		_v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		switch v := _v.(type) {
+		case scope.Record:
+			fld := v.Get(f.Object().Adr())
+			rt2.ValueOf(in.Parent)[f.Adr()] = fld
+			rt2.RegOf(in.Parent)[in.Key] = f.Adr()
+			return End()
+		default:
+			halt.As(100, reflect.TypeOf(v))
+		}
+		panic(0)
+	})
+}
+
+func getIndex(in IN) OUT {
+	const (
+		left  = "index:left"
+		right = "index:right"
+	)
+	i := in.IR.(node.IndexNode)
+	return GetExpression(in, right, i.Right(), func(IN) OUT {
+		idx := rt2.ValueOf(in.Frame)[KeyOf(in, right)]
+		assert.For(idx != nil, 40)
+		return GetDesignator(in, left, i.Left(), func(IN) OUT {
+			arr := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+			assert.For(arr != nil, 41)
+			switch a := arr.(type) {
+			case scope.Array:
+				rt2.ValueOf(in.Parent)[i.Adr()] = a.Get(idx)
+				rt2.RegOf(in.Parent)[in.Key] = i.Adr()
+				return End()
+			default:
+				halt.As(100, reflect.TypeOf(a))
+			}
+			panic(890)
+		})
+	})
+}
+
+func getProc(in IN) OUT {
+	p := in.IR.(node.ProcedureNode)
+	sc := rt2.ThisScope(in.Frame)
+	fn := sc.Provide(p.Object())
+	assert.For(fn != nil, 40)
+	rt2.ValueOf(in.Parent)[p.Adr()] = fn(nil)
+	rt2.RegOf(in.Parent)[in.Key] = p.Adr()
+	return End()
+}
+
+func getDeref(in IN) OUT {
+	const left = "design:left"
+	d := in.IR.(node.DerefNode)
+	return GetDesignator(in, left, d.Left(), func(in IN) OUT {
+		_v := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		switch v := _v.(type) {
+		case scope.Array:
+			assert.For(!d.Ptr(), 40)
+			t, c := scope.Ops.TypeOf(v)
+			switch cc := c.(type) {
+			case object.ArrayType:
+				assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
+				rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
+				rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+				return End()
+			case object.DynArrayType:
+				assert.For(cc.Base() == object.CHAR || cc.Base() == object.SHORTCHAR, 41)
+				rt2.ValueOf(in.Parent)[d.Adr()] = scope.TypeFromGo(scope.GoTypeFrom(v))
+				rt2.RegOf(in.Parent)[in.Key] = d.Adr()
+				return End()
+			default:
+				halt.As(100, t, reflect.TypeOf(cc))
+			}
+		default:
+			halt.As(100, reflect.TypeOf(v))
+		}
+		panic(0)
+	})
+}
+
 func getDop(in IN) OUT {
 	const (
 		left  = "dop:left"
@@ -60,6 +145,7 @@ func getDop(in IN) OUT {
 			res = scope.Ops.Eq(l, r)
 		case operation.LESSER:
 			res = scope.Ops.Lss(l, r)
+			fmt.Println(res, l, r)
 		case operation.LESS_EQUAL:
 			res = scope.Ops.Leq(l, r)
 		case operation.LEN:
@@ -148,7 +234,23 @@ func getMop(in IN) OUT {
 			} else {
 				res = scope.Ops.Conv(lv, op.Type(), op.Complex())
 			}
-
+		case operation.NOT:
+			res = scope.Ops.Not(lv)
+		case operation.IS:
+			/*sc := rt2.ScopeFor(f, n.Left().Object().Adr())
+			rt2.ValueOf(f.Parent())[n.Adr()] = scope.Ops.Is(sc.Select(n.Left().Object().Adr()), n.Object().Complex())
+			return frame.End()*/
+			panic(0)
+		case operation.ABS:
+			res = scope.Ops.Abs(lv)
+		case operation.ODD:
+			res = scope.Ops.Odd(lv)
+		case operation.CAP:
+			res = scope.Ops.Cap(lv)
+		case operation.BITS:
+			res = scope.Ops.Bits(lv)
+		case operation.MINUS:
+			res = scope.Ops.Minus(lv)
 		default:
 			halt.As(100, "unknown op", op.Operation())
 		}

+ 182 - 0
rt2/rules2/wrap/eval/stmt.go

@@ -1,14 +1,20 @@
 package eval
 
 import (
+	"fw/cp"
+	"fw/cp/constant"
+	"fw/cp/constant/operation"
 	"fw/cp/constant/statement"
 	"fw/cp/node"
 	"fw/cp/object"
+	"fw/cp/traps"
 	"fw/rt2"
 	"fw/rt2/context"
+	"fw/rt2/frame"
 	rtm "fw/rt2/module"
 	"fw/rt2/scope"
 	"fw/utils"
+	"log"
 	"reflect"
 	"ypk/assert"
 	"ypk/halt"
@@ -66,6 +72,26 @@ func doEnter(in IN) OUT {
 	return Now(next)
 }
 
+func inc_dec_seq(in IN, code operation.Operation) OUT {
+	n := in.IR
+	a := node.New(constant.ASSIGN, cp.Some()).(node.AssignNode)
+	a.SetStatement(statement.ASSIGN)
+	a.SetLeft(n.Left())
+	op := node.New(constant.DYADIC, cp.Some()).(node.OperationNode)
+	op.SetOperation(code)
+	op.SetLeft(n.Left())
+	op.SetRight(n.Right())
+	a.SetRight(op)
+	rt2.Push(rt2.New(a), in.Frame)
+	/*seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
+		sc.Update(n.Left().Object().Adr(), scope.Simple(rt2.ValueOf(f)[op.Adr()]))
+		return frame.End()
+	}
+	ret = frame.LATER */
+	return Later(Tail(STOP))
+}
+
 func doAssign(in IN) (out OUT) {
 	const (
 		right = "assign:right"
@@ -86,6 +112,20 @@ func doAssign(in IN) (out OUT) {
 				return End()
 			})
 		})
+	case statement.INC, statement.INCL:
+		switch a.Left().(type) {
+		case node.VariableNode, node.ParameterNode, node.FieldNode:
+			out = inc_dec_seq(in, operation.PLUS)
+		default:
+			halt.As(100, "wrong left", reflect.TypeOf(a.Left()))
+		}
+	case statement.DEC, statement.EXCL:
+		switch a.Left().(type) {
+		case node.VariableNode, node.ParameterNode, node.FieldNode:
+			out = inc_dec_seq(in, operation.MINUS)
+		default:
+			halt.As(100, "wrong left", reflect.TypeOf(a.Left()))
+		}
 	default:
 		halt.As(100, "unsupported assign statement", a.Statement())
 	}
@@ -140,6 +180,95 @@ func doCondition(in IN) OUT {
 	return GetStrange(in, left, i.Left(), next)
 }
 
+func doWhile(in IN) OUT {
+	const left = "while:left"
+	w := in.IR.(node.WhileNode)
+	var next Do
+
+	next = func(IN) OUT {
+		key := KeyOf(in, left)
+		fi := rt2.ValueOf(in.Frame)[key]
+		rt2.ValueOf(in.Frame)[key] = nil
+		done := scope.GoTypeFrom(fi).(bool)
+		if done && w.Right() != nil {
+			rt2.Push(rt2.New(w.Right()), in.Frame)
+			return Later(func(IN) OUT { return GetExpression(in, left, w.Left(), next) })
+		} else if !done {
+			return End()
+		} else if w.Right() == nil {
+			return End()
+		} else {
+			panic("unexpected while seq")
+		}
+	}
+
+	return GetExpression(in, left, w.Left(), next)
+}
+
+const exitFlag = 1812
+
+func doExit(in IN) OUT {
+	in.Frame.Root().ForEach(func(f frame.Frame) (ok bool) {
+		n := rt2.NodeOf(f)
+		_, ok = n.(node.LoopNode)
+		if ok {
+			rt2.RegOf(f)[exitFlag] = true
+		}
+		ok = !ok
+		return ok
+	})
+	return End()
+}
+
+func doLoop(in IN) OUT {
+	l := in.IR.(node.LoopNode)
+	exit, ok := rt2.RegOf(in.Frame)[exitFlag].(bool)
+	if ok && exit {
+		return End()
+	}
+	if l.Left() != nil {
+		rt2.Push(rt2.New(l.Left()), in.Frame)
+		return Later(doLoop)
+	} else if l.Left() == nil {
+		return End()
+	} else {
+		panic("unexpected loop seq")
+	}
+}
+
+func doRepeat(in IN) OUT {
+	const right = "return:right"
+	r := in.IR.(node.RepeatNode)
+	rt2.ValueOf(in.Frame)[r.Right().Adr()] = scope.TypeFromGo(false)
+	var next Do
+	next = func(in IN) OUT {
+		fi := rt2.ValueOf(in.Frame)[r.Right().Adr()]
+		done := scope.GoTypeFrom(fi).(bool)
+		if !done && r.Left() != nil {
+			rt2.Push(rt2.New(r.Left()), in.Frame)
+			return Later(func(IN) OUT { return GetExpression(in, right, r.Right(), next) })
+		} else if done {
+			return End()
+		} else if r.Left() == nil {
+			return End()
+		} else {
+			panic("unexpected repeat seq")
+		}
+	}
+	return Now(next)
+}
+
+func doTrap(in IN) OUT {
+	const left = "trap:left"
+
+	return GetExpression(in, left, in.IR.Left(), func(IN) OUT {
+		val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		log.Println("TRAP:", traps.This(scope.GoTypeFrom(val)))
+		return Now(Tail(WRONG))
+	})
+
+}
+
 func doReturn(in IN) OUT {
 	const left = "return:left"
 	r := in.IR.(node.ReturnNode)
@@ -250,8 +379,61 @@ func doCall(in IN) (out OUT) {
 		default:
 			halt.As(100, "wrong proc mode ", p.Object().Mode(), p.Object().Adr(), p.Object().Name())
 		}
+	case node.VariableNode:
+		m := rtm.DomainModule(in.Frame.Domain())
+		sc := rt2.ScopeFor(in.Frame, p.Object().Adr())
+		obj := scope.GoTypeFrom(sc.Select(p.Object().Adr()))
+
+		if obj, ok := obj.(object.Object); ok {
+			proc := m.NodeByObject(obj)
+			call(proc[0], nil)
+		} else {
+			name := p.Object().Name()
+			switch {
+			case sys[name] != nil:
+				return syscall(in.Frame)
+			default:
+				halt.As(100, "unknown sysproc variable", name)
+			}
+		}
 	default:
 		halt.As(100, reflect.TypeOf(p))
 	}
 	return
 }
+
+func doWith(in IN) OUT {
+	const left = "return:left"
+	w := in.IR.(node.WithNode)
+	f := in.Frame
+	rt2.RegOf(f)[0] = w.Left() //if
+
+	seq = func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+		last := rt2.RegOf(f)[0].(node.Node)
+		done := scope.GoTypeFrom(rt2.ValueOf(f)[last.Adr()]).(bool)
+		rt2.ValueOf(f)[last.Adr()] = nil
+		if done && last.Right() != nil {
+			rt2.Push(rt2.New(last.Right()), f)
+			return frame.Tail(frame.STOP), frame.LATER
+		} else if last.Right() == nil {
+			return frame.End()
+		} else if last.Link() != nil { //elsif
+			rt2.RegOf(f)[0] = last.Link()
+			rt2.Push(rt2.New(last.Link()), f)
+			rt2.Assert(f, func(f frame.Frame) (bool, int) {
+				return rt2.ValueOf(f)[last.Link().Adr()] != nil, 61
+			})
+			return seq, frame.LATER
+		} else if n.Right() != nil { //else
+			rt2.Push(rt2.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
+}

+ 3 - 3
rt2/rules2/wrap/nodes.go

@@ -81,7 +81,7 @@ func prologue(n node.Node) frame.Sequence {
 	case node.IfNode:
 		return Propose(eval.BeginStrange)
 	default:
-		halt.As(100, reflect.TypeOf(n))
+		halt.As(100, "no prologue for", reflect.TypeOf(n))
 	}
 	panic(0)
 }
@@ -90,9 +90,9 @@ func epilogue(n node.Node) frame.Sequence {
 	switch n.(type) {
 	case node.Statement:
 		return Propose(eval.EndStatement)
-	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode, node.IfNode: //do nothing
+	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode, node.IfNode, node.ProcedureNode, node.DerefNode, node.FieldNode, node.IndexNode: //do nothing
 	default:
-		halt.As(100, reflect.TypeOf(n))
+		halt.As(100, "no epilogue for", reflect.TypeOf(n))
 	}
 	return nil
 }

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

@@ -229,7 +229,6 @@ func (a *arr) Get(id scope.Value) scope.Value {
 	case *data:
 		return a.Get(i.val.(scope.Value))
 	case INTEGER:
-		assert.For(int64(i) < a.length, 20)
 		if len(a.val) == 0 {
 			a.val = make([]interface{}, int(a.length))
 		}