Переглянути джерело

реализовал основную схему интерпретации, все работает для первых демок

kpmy 10 роки тому
батько
коміт
aa8d98a8d3

+ 0 - 1
cp/node/node.go

@@ -28,7 +28,6 @@ type Statement interface {
 
 type Expression interface {
 	e() Expression
-	Designator
 }
 
 type Designator interface {

+ 1 - 0
domain.go

@@ -14,6 +14,7 @@ type stdDomain struct {
 
 func (d *stdDomain) New() context.Domain { return &stdDomain{global: d.global} }
 
+func (d *stdDomain) Global() context.Domain { return d.global }
 func (d *stdDomain) Attach(name string, x context.ContextAware) {
 	assert.For(x != nil, 20)
 	assert.For(name != context.UNIVERSE, 21)

+ 1 - 1
fw.go

@@ -37,7 +37,7 @@ func main() {
 	flag.Parse()
 	utils.Debug(debug)
 	if name == "" {
-		name = "XevDemo1"
+		name = "XevDemo4"
 		utils.Debug(true)
 	}
 	global := &stdDomain{god: true}

+ 1 - 0
rt2/context/ctx.go

@@ -23,6 +23,7 @@ type Domain interface {
 	Discover(name string, opts ...interface{}) ContextAware
 	Id(c ContextAware) string
 	ContextAware
+	Global() Domain
 }
 
 type ContextAware interface {

+ 38 - 5
rt2/rules2/wrap/eval/do.go

@@ -21,6 +21,8 @@ func BeginExpression(in IN) (out OUT) {
 		out = Now(getConst)
 	case node.DyadicNode:
 		out = Now(getDop)
+	case node.MonadicNode:
+		out = Now(getMop)
 	case node.Designator:
 		out = Now(BeginDesignator)
 	default:
@@ -33,6 +35,8 @@ func BeginDesignator(in IN) (out OUT) {
 	switch e := in.IR.(type) {
 	case node.VariableNode:
 		out = Now(getVar)
+	case node.ParameterNode:
+		out = Now(getVarPar)
 	default:
 		halt.As(100, reflect.TypeOf(e))
 	}
@@ -41,15 +45,16 @@ func BeginDesignator(in IN) (out OUT) {
 
 func GetExpression(in IN, key interface{}, expr node.Node, next Do) OUT {
 	assert.For(expr != nil, 20)
-	_, ok := expr.(node.Expression)
-	assert.For(ok, 21, reflect.TypeOf(expr))
+	_, e_ok := expr.(node.Expression)
+	_, d_ok := expr.(node.Designator)
+	assert.For(e_ok || d_ok, 21, reflect.TypeOf(expr))
 	assert.For(key != nil, 22)
 	nf := rt2.New(expr)
 	rt2.Push(nf, in.Frame)
 	rt2.RegOf(in.Frame)[context.KEY] = key
 	rt2.Assert(in.Frame, func(f frame.Frame) (bool, int) {
 		v := rt2.RegOf(f)[key]
-		return v != nil, 20
+		return v != nil, 1961
 	})
 	return Later(func(IN) OUT {
 		return Now(next)
@@ -66,7 +71,7 @@ func GetDesignator(in IN, key interface{}, design node.Node, next Do) OUT {
 	rt2.RegOf(in.Frame)[context.KEY] = key
 	rt2.Assert(in.Frame, func(f frame.Frame) (bool, int) {
 		v := rt2.RegOf(f)[key]
-		return v != nil, 20
+		return v != nil, 1957
 	})
 	return Later(func(IN) OUT {
 		return Now(next)
@@ -91,6 +96,8 @@ func BeginStatement(in IN) (out OUT) {
 		out = Now(doAssign)
 	case node.CallNode:
 		out = Now(doCall)
+	case node.ReturnNode:
+		out = Now(doReturn)
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
@@ -104,6 +111,16 @@ func EndStatement(in IN) (out OUT) {
 			if n.Enter() == enter.PROCEDURE {
 				rt2.ThisScope(in.Frame).Target().(scope.ScopeAllocator).Dispose(n)
 			}
+			if in.Parent != nil {
+				par := rt2.RegOf(in.Parent)
+				for k, v := range rt2.RegOf(in.Frame) {
+					par[k] = v
+				}
+				val := rt2.ValueOf(in.Parent)
+				for k, v := range rt2.ValueOf(in.Frame) {
+					val[k] = v
+				}
+			}
 			return End()
 		})
 	case node.AssignNode, node.CallNode:
@@ -115,10 +132,26 @@ func EndStatement(in IN) (out OUT) {
 					in.Frame.Root().PushFor(nf, in.Parent)
 				}
 			}
+			if _, ok := n.(node.CallNode); ok {
+				if in.Parent != nil {
+					par := rt2.RegOf(in.Parent)
+					for k, v := range rt2.RegOf(in.Frame) {
+						par[k] = v
+					}
+					val := rt2.ValueOf(in.Parent)
+					for k, v := range rt2.ValueOf(in.Frame) {
+						val[k] = v
+					}
+				}
+			}
 			return End()
 		})
+	case node.ReturnNode: //do nothing
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}
-	return out.Do(in)
+	if out.Next != WRONG {
+		return out.Do(in)
+	}
+	return End()
 }

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

@@ -3,6 +3,7 @@ package eval
 import (
 	"fw/cp/constant/operation"
 	"fw/cp/node"
+	"fw/cp/object"
 	"fw/rt2"
 	"fw/rt2/scope"
 	"ypk/assert"
@@ -28,6 +29,15 @@ func getVar(in IN) OUT {
 	return End()
 }
 
+func getVarPar(in IN) OUT {
+	v := in.IR.(node.ParameterNode)
+	rt2.ScopeFor(in.Frame, v.Object().Adr(), func(val scope.Value) {
+		rt2.ValueOf(in.Parent)[v.Adr()] = val
+		rt2.RegOf(in.Parent)[in.Key] = v.Adr()
+	})
+	return End()
+}
+
 func getDop(in IN) OUT {
 	const (
 		left  = "dop:left"
@@ -121,6 +131,32 @@ func getDop(in IN) OUT {
 			return Now(next)
 		}
 	}
-
 	return GetExpression(in, left, op.Left(), short)
 }
+
+func getMop(in IN) OUT {
+	const left = "mop:left"
+	op := in.IR.(node.MonadicNode)
+
+	do := func(in IN) OUT {
+		lv := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		var res scope.Value
+		switch op.Operation() {
+		case operation.ALIEN_CONV:
+			if op.Type() != object.NOTYPE {
+				res = scope.Ops.Conv(lv, op.Type())
+			} else {
+				res = scope.Ops.Conv(lv, op.Type(), op.Complex())
+			}
+
+		default:
+			halt.As(100, "unknown op", op.Operation())
+		}
+		assert.For(res != nil, 60)
+		rt2.ValueOf(in.Parent)[op.Adr()] = res
+		rt2.RegOf(in.Parent)[in.Key] = op.Adr()
+		return End()
+	}
+
+	return GetExpression(in, left, op.Left(), do)
+}

+ 139 - 5
rt2/rules2/wrap/eval/stmt.go

@@ -3,14 +3,19 @@ package eval
 import (
 	"fw/cp/constant/statement"
 	"fw/cp/node"
+	"fw/cp/object"
 	"fw/rt2"
+	"fw/rt2/context"
+	rtm "fw/rt2/module"
 	"fw/rt2/scope"
+	"fw/utils"
 	"reflect"
 	"ypk/assert"
 	"ypk/halt"
 )
 
 func doEnter(in IN) OUT {
+	e := in.IR.(node.EnterNode)
 	var next Do
 	tail := func(IN) (out OUT) {
 		body := in.IR.Right()
@@ -18,7 +23,8 @@ func doEnter(in IN) OUT {
 		case body == nil:
 			return End()
 		case body != nil && in.Parent != nil:
-			panic(0)
+			rt2.Push(rt2.New(body), in.Frame)
+			return Later(Tail(STOP))
 		case body != nil && in.Parent == nil: //секция BEGIN
 			rt2.Push(rt2.New(body), in.Frame)
 			end := in.IR.Link()
@@ -35,8 +41,24 @@ func doEnter(in IN) OUT {
 		return
 	}
 	sm := rt2.ThisScope(in.Frame)
-	if in.IR.Object() != nil { //параметры процедуры
-		panic(0)
+	if e.Object() != nil { //параметры процедуры
+		par, ok := rt2.RegOf(in.Frame)[e.Object()].(node.Node)
+		//fmt.Println(rt2.DataOf(f)[n.Object()])
+		//fmt.Println(ok)
+		if ok {
+			sm.Target().(scope.ScopeAllocator).Allocate(e, false)
+			next = func(in IN) OUT {
+				seq, _ := sm.Target().(scope.ScopeAllocator).Initialize(e,
+					scope.PARAM{Objects: e.Object().Link(),
+						Values: par,
+						Frame:  in.Frame,
+						Tail:   Propose(tail)})
+				return Later(Expose(seq))
+			}
+		} else {
+			sm.Target().(scope.ScopeAllocator).Allocate(e, true)
+			next = tail
+		}
 	} else {
 		sm.Target().(scope.ScopeAllocator).Allocate(in.IR, true)
 		next = tail
@@ -70,6 +92,118 @@ func doAssign(in IN) (out OUT) {
 	return
 }
 
-func doCall(in IN) OUT {
-	panic(0)
+func doReturn(in IN) OUT {
+	const left = "return:left"
+	r := in.IR.(node.ReturnNode)
+	return GetExpression(in, left, r.Left(), func(IN) OUT {
+		val := rt2.ValueOf(in.Frame)[KeyOf(in, left)]
+		if val == nil {
+			val, _ = rt2.RegOf(in.Frame)[context.RETURN].(scope.Value)
+		}
+		assert.For(val != nil, 40)
+		rt2.ValueOf(in.Parent)[r.Object().Adr()] = val
+		rt2.RegOf(in.Parent)[context.RETURN] = val
+		return End()
+	})
+}
+
+func doCall(in IN) (out OUT) {
+	const (
+		right = "call:right"
+	)
+	c := in.IR.(node.CallNode)
+
+	call := func(proc node.Node, d context.Domain) {
+		_, ok := proc.(node.EnterNode)
+		assert.For(ok, 20, "try call", reflect.TypeOf(proc), proc.Adr(), proc.Object().Adr())
+		nf := rt2.New(proc)
+		rt2.Push(nf, in.Frame)
+		if d != nil {
+			rt2.ReplaceDomain(nf, d)
+		}
+		//передаем ссылку на цепочку значений параметров в данные фрейма входа в процедуру
+		if (c.Right() != nil) && (proc.Object() != nil) {
+			rt2.RegOf(nf)[proc.Object()] = c.Right()
+		} else {
+			//fmt.Println("no data for call")
+		}
+		out = Later(func(in IN) OUT {
+			if in.Key != nil {
+				val := rt2.ValueOf(in.Frame)[c.Left().Object().Adr(0, 0)]
+				assert.For(val != nil, 40, rt2.ValueOf(in.Frame))
+				rt2.ValueOf(in.Parent)[c.Adr()] = val
+				rt2.RegOf(in.Parent)[in.Key] = c.Adr()
+				rt2.ValueOf(in.Parent)[c.Adr()] = val
+			}
+			return End()
+		})
+	}
+
+	switch p := c.Left().(type) {
+	case node.ProcedureNode:
+		m := rtm.DomainModule(in.Frame.Domain())
+		ml := in.Frame.Domain().Global().Discover(context.MOD).(rtm.List)
+		switch p.Object().Mode() {
+		case object.LOCAL_PROC, object.EXTERNAL_PROC:
+			if imp := m.ImportOf(p.Object()); imp == "" || imp == m.Name {
+				proc := m.NodeByObject(p.Object())
+				assert.For(proc != nil, 40)
+				call(proc[0], nil)
+			} else {
+				m := ml.Loaded(imp)
+				pl := m.ObjectByName(m.Enter, c.Left().Object().Name())
+				var proc object.ProcedureObject
+				var nl []node.Node
+				for _, n := range pl {
+					if n.Mode() == p.Object().Mode() {
+						proc = n.(object.ProcedureObject)
+					}
+
+				}
+				nl = m.NodeByObject(proc)
+				utils.PrintFrame("foreign call", len(nl), "proc refs", proc)
+				call(nl[0], in.Frame.Domain().Global().Discover(imp).(context.Domain))
+			}
+		case object.TYPE_PROC:
+			//sc := f.Domain().Discover(context.SCOPE).(scope.Manager)
+			assert.For(!p.Super(), 20)
+			out = GetExpression(in, right, c.Right(), func(IN) (out OUT) {
+				var (
+					proc []node.Node
+					dm   context.Domain
+				)
+				id := KeyOf(in, right)
+				v := rt2.ValueOf(in.Frame)[id]
+				t, ct := scope.Ops.TypeOf(v)
+				if ct == nil {
+					panic(0)
+					//return thisTrap(f, traps.Default)
+				}
+				assert.For(ct != nil, 40, id, v, t)
+				x := ml.NewTypeCalc()
+				x.ConnectTo(c)
+				for _, ml := range x.MethodList() {
+					for _, m := range ml {
+						if m.Obj.Name() == p.Object().Name() {
+							proc = append(proc, m.Enter)
+							dm = in.Frame.Domain().Global().Discover(m.Mod.Name).(context.Domain)
+							break
+						}
+					}
+					if len(proc) > 0 {
+						break
+					}
+				}
+				assert.For(len(proc) > 0, 40, p.Object().Name())
+				call(proc[0], dm)
+				out = Later(Tail(STOP))
+				return
+			})
+		default:
+			halt.As(100, "wrong proc mode ", p.Object().Mode(), p.Object().Adr(), p.Object().Name())
+		}
+	default:
+		halt.As(100, reflect.TypeOf(p))
+	}
+	return
 }

+ 3 - 0
rt2/rules2/wrap/eval/x.go

@@ -16,6 +16,9 @@ const (
 	END
 )
 
+var Propose func(Do) frame.Sequence
+var Expose func(frame.Sequence) Do
+
 func (n WAIT) Wait() frame.WAIT {
 	switch n {
 	case WRONG:

+ 28 - 1
rt2/rules2/wrap/nodes.go

@@ -15,6 +15,8 @@ func init() {
 	decision.PrologueFor = prologue
 	decision.EpilogueFor = epilogue
 	decision.AssertFor = test
+	eval.Propose = Propose
+	eval.Expose = Expose
 }
 
 func This(o eval.OUT) (seq frame.Sequence, ret frame.WAIT) {
@@ -35,6 +37,31 @@ func Propose(a eval.Do) frame.Sequence {
 		return This(a(in))
 	}
 }
+func waiting(n frame.WAIT) eval.WAIT {
+	switch n {
+	case frame.WRONG:
+		return eval.WRONG
+	case frame.STOP:
+		return eval.STOP
+	case frame.LATER:
+		return eval.LATER
+	case frame.NOW:
+		return eval.NOW
+	case frame.BEGIN:
+		return eval.BEGIN
+	case frame.END:
+		return eval.END
+	default:
+		panic(n)
+	}
+}
+
+func Expose(f frame.Sequence) eval.Do {
+	return func(in eval.IN) (out eval.OUT) {
+		s, w := f(in.Frame)
+		return eval.OUT{Do: Expose(s), Next: waiting(w)}
+	}
+}
 
 func test(n node.Node) (bool, int) {
 	switch n.(type) {
@@ -61,7 +88,7 @@ func epilogue(n node.Node) frame.Sequence {
 	switch n.(type) {
 	case node.Statement:
 		return Propose(eval.EndStatement)
-	case node.ConstantNode, node.VariableNode, node.DyadicNode: //do nothing
+	case node.ConstantNode, node.VariableNode, node.ParameterNode, node.DyadicNode, node.MonadicNode: //do nothing
 	default:
 		halt.As(100, reflect.TypeOf(n))
 	}