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

переделал рантайм более простыми абстракциями

kpmy 10 жил өмнө
parent
commit
ca0387c85b

+ 14 - 1
README.md

@@ -1,2 +1,15 @@
-fw
+The Framework (fw)
 ==
+
+Фреймворк это что-то скрытое, фреймворк для Компонентного Паскаля может быть любым.
+В том числе, можно написать фреймворк на другом языке программирования. 
+Например, на Go. А потом, когда пойму, как делать хорошо, возможно и на Dart/LLVM.
+
+Вводные:
+AST-выход компилятора ББ.
+
+Результат:
+Исполнение модулей на КП.
+
+Дополнения:
+Создание диалекта КП, который лучше (возможно) подойдет для высокоуровневой среды рантайма.

+ 14 - 15
fw/fw.go

@@ -1,27 +1,26 @@
 package main
 
 import (
+	"fmt"
 	"os"
-	"rt"
+	"rt2/frame"
+	"rt2/nodeframe"
+	_ "rt2/rules"
 	"xev"
+	"ypk/assert"
 )
 
 func main() {
 	path, _ := os.Getwd()
 	ret := xev.Load(path, "PrivDemo1.oxf")
-	if ret != nil {
-		p := rt.NewProcessor()
-		err := p.ConnectTo(ret)
-		if err != nil {
-			panic("not connected")
-		}
-		for {
-			res, _ := p.Do()
-			if res != rt.OK {
-				break
-			}
-		}
-	} else {
-		panic("no module")
+	assert.For(ret != nil, 20)
+	root := new(frame.RootFrame).Init()
+	var fu nodeframe.FrameUtils
+	root.Push(fu.New(ret.Enter))
+	i := 0
+	for x := frame.DO; x == frame.DO; x = root.Do() {
+		fmt.Println(x)
+		i++
 	}
+	fmt.Println("total steps", i)
 }

+ 1 - 0
old/README.md

@@ -0,0 +1 @@
+remove after 20150101 

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 0
old/fw~/PrivDemo1.oxf


+ 27 - 0
old/fw~/fw.go

@@ -0,0 +1,27 @@
+package main
+
+import (
+	"os"
+	"rt"
+	"xev"
+)
+
+func main() {
+	path, _ := os.Getwd()
+	ret := xev.Load(path, "PrivDemo1.oxf")
+	if ret != nil {
+		p := rt.NewProcessor()
+		err := p.ConnectTo(ret)
+		if err != nil {
+			panic("not connected")
+		}
+		for {
+			res, _ := p.Do()
+			if res != rt.OK {
+				break
+			}
+		}
+	} else {
+		panic("no module")
+	}
+}

+ 0 - 0
rt/heap.go → old/rt!/heap.go


+ 0 - 0
rt/op.go → old/rt!/op.go


+ 0 - 0
rt/proc.go → old/rt!/proc.go


+ 0 - 0
rt/seq.go → old/rt!/seq.go


+ 0 - 0
rt/stack.go → old/rt!/stack.go


+ 11 - 0
rt2/decision/table.go

@@ -0,0 +1,11 @@
+package decision
+
+import (
+	"cp/node"
+	"rt2/frame"
+)
+
+var (
+	PrologueFor func(n node.Node) frame.Sequence
+	EpilogueFor func(n node.Node) frame.Sequence
+)

+ 36 - 0
rt2/frame/frame.go

@@ -0,0 +1,36 @@
+package frame
+
+type WAIT int
+
+const (
+	WRONG WAIT = iota
+	STOP
+	SKIP
+	DO
+)
+
+// LIFO-стек, позволяет затолкнуть фрейм связанный с другим фреймом
+type Stack interface {
+	Push(f Frame)
+	PushFor(f, parent Frame)
+	Pop()
+	Top() Frame
+}
+
+//фрейм
+type Frame interface {
+	Do() WAIT
+	OnPush(root Stack, parent Frame)
+	OnPop()
+	Parent() Frame
+	Root() Stack
+}
+
+//пользовательская функция, которую выполнит фрейм, может поставить на очередь выполнения себя или другую функцию
+type Sequence func(f Frame) (Sequence, WAIT)
+
+func Tail(x WAIT) (seq Sequence) {
+	return func(f Frame) (Sequence, WAIT) { return nil, x }
+}
+
+func End() (Sequence, WAIT) { return nil, STOP }

+ 97 - 0
rt2/frame/stdFrame.go

@@ -0,0 +1,97 @@
+package frame
+
+import (
+	"container/list"
+	"fmt"
+)
+
+type RootFrame struct {
+	inner list.List
+}
+
+func (f *RootFrame) Init() *RootFrame {
+	f.inner = *list.New()
+	return f
+}
+
+func (f *RootFrame) Push(frame Frame) {
+	f.PushFor(frame, nil)
+}
+
+func (f *RootFrame) PushFor(frame, parent Frame) {
+	_, ok := frame.(*RootFrame)
+	if ok {
+		panic("impossibru")
+	}
+	f.inner.PushFront(frame)
+	frame.OnPush(f, parent)
+}
+
+func (f *RootFrame) Pop() {
+	if f.inner.Front() != nil {
+		elem := f.inner.Front()
+		frame := elem.Value.(Frame)
+		frame.OnPop()
+		f.inner.Remove(elem)
+	} else {
+		panic("it's empty stack")
+	}
+}
+
+func (f *RootFrame) Top() (frame Frame) {
+	elem := f.inner.Front()
+	if elem != nil {
+		frame = elem.Value.(Frame)
+	}
+	return frame
+}
+
+func (f *RootFrame) Do() (res WAIT) {
+	if f.Top() != nil {
+		x := f.Top()
+		//цикл дейкстры
+		for {
+			wait := x.Do()
+			fmt.Println(wait)
+			if wait == SKIP {
+				break
+			} else if wait == DO {
+			} else if wait == WRONG {
+				panic("something wrong")
+			} else {
+				if x == f.Top() {
+					f.Pop()
+				} else {
+					panic("do not stop if not top on stack")
+				}
+				break
+			}
+		}
+	}
+	if f.Top() != nil {
+		res = DO
+	} else {
+		res = STOP
+	}
+	return res
+}
+
+func (f *RootFrame) OnPush(a Stack, b Frame) {}
+func (f *RootFrame) OnPop()                  {}
+func (f *RootFrame) Parent() Frame           { return nil }
+func (f *RootFrame) Root() Stack             { return nil }
+
+func (w WAIT) String() string {
+	switch w {
+	case DO:
+		return "DO"
+	case SKIP:
+		return "SKIP"
+	case STOP:
+		return "STOP"
+	case WRONG:
+		return "WRONG"
+	default:
+		panic("wrong wait value")
+	}
+}

+ 73 - 0
rt2/nodeframe/frame.go

@@ -0,0 +1,73 @@
+package nodeframe
+
+import (
+	"cp/node"
+	"rt2/decision"
+	"rt2/frame"
+	"ypk/assert"
+)
+
+type FrameUtils struct{}
+
+func (fu FrameUtils) New(n node.Node) (f frame.Frame) {
+	assert.For(n != nil, 20)
+	f = new(nodeFrame)
+	f.(*nodeFrame).ir = n
+	return f
+}
+
+func (fu FrameUtils) Push(f, p frame.Frame) {
+	assert.For(f != nil, 20)
+	pp, _ := p.(*nodeFrame)
+	pp.push(f)
+
+}
+
+func (fu FrameUtils) NodeOf(f frame.Frame) node.Node {
+	ff, _ := f.(*nodeFrame)
+	assert.For(ff.ir != nil, 40)
+	return ff.ir
+}
+
+type nodeFrame struct {
+	root   frame.Stack
+	parent frame.Frame
+	ir     node.Node
+	seq    frame.Sequence
+}
+
+func (f *nodeFrame) Do() frame.WAIT {
+	assert.For(f.seq != nil, 20)
+	next, ret := f.seq(f)
+	if next != nil {
+		assert.For(ret != frame.STOP, 40)
+		f.seq = next
+	} else {
+		assert.For(ret == frame.STOP, 41)
+	}
+	return ret
+}
+
+func (f *nodeFrame) onPush() {
+	f.seq = decision.PrologueFor(f.ir)
+}
+
+func (f *nodeFrame) OnPop() {
+	f.seq = decision.EpilogueFor(f.ir)
+	if f.seq != nil {
+		_, _ = f.seq(f)
+	}
+}
+
+func (f *nodeFrame) push(n frame.Frame) {
+	f.root.PushFor(n, f)
+}
+
+func (f *nodeFrame) OnPush(root frame.Stack, parent frame.Frame) {
+	f.root = root
+	f.parent = parent
+	f.onPush()
+}
+
+func (f *nodeFrame) Parent() frame.Frame { return f.parent }
+func (f *nodeFrame) Root() frame.Stack   { return f.root }

+ 47 - 0
rt2/rules/assign.go

@@ -0,0 +1,47 @@
+package rules
+
+import (
+	"cp/node"
+	"cp/statement"
+	"rt2/frame"
+	"rt2/nodeframe"
+)
+
+func assignSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	var fu nodeframe.FrameUtils
+	a := fu.NodeOf(f)
+	switch a.(node.AssignNode).Statement() {
+	case statement.ASSIGN:
+		switch a.Left().(type) {
+		case node.VariableNode:
+			switch a.Right().(type) {
+			case node.ConstantNode:
+				seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+					//тут присвоение
+					return frame.End()
+				}
+				ret = frame.DO
+			case node.VariableNode:
+				seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+					//тут присвоение
+					return frame.End()
+				}
+				ret = frame.DO
+			case node.OperationNode:
+				fu.Push(fu.New(a.Right()), f)
+				seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+					//тут чтение результата операции
+					return frame.End()
+				}
+				ret = frame.SKIP
+			default:
+				panic("wrong right")
+			}
+		default:
+			panic("wrong left")
+		}
+	default:
+		panic("wrong statement")
+	}
+	return seq, ret
+}

+ 25 - 0
rt2/rules/call.go

@@ -0,0 +1,25 @@
+package rules
+
+import (
+	"cp/node"
+	"rt2/frame"
+	"rt2/nodeframe"
+)
+
+func callSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	var fu nodeframe.FrameUtils
+	n := fu.NodeOf(f)
+	switch n.Left().(type) {
+	case node.ProcedureNode:
+		//proc := f.p.thisMod.NodeByObject(f.ir.Left().Object())
+		//f.Root().Push(fu.New(?))
+		seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+			return frame.End()
+		}
+		ret = frame.STOP
+		seq = nil //frame.SKIP //uncomment when truly work
+	default:
+		panic("unknown call left")
+	}
+	return seq, ret
+}

+ 61 - 0
rt2/rules/op.go

@@ -0,0 +1,61 @@
+package rules
+
+import (
+	"cp/constant/operation"
+	"cp/node"
+	"rt2/frame"
+	"rt2/nodeframe"
+)
+
+func opSeq(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+	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.PLUS:
+			//складываем
+			return frame.End()
+		default:
+			panic("unknown operation")
+		}
+	}
+
+	right := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		n := fu.NodeOf(f)
+		switch n.Right().(type) {
+		case node.ConstantNode:
+			//f.ret[f.ir.Right()] = f.ir.Right().(node.ConstantNode).Data()
+			return op, frame.DO
+		case node.VariableNode:
+			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+				//f.ret[f.ir.Right()] = f.p.heap.This(f.ir.Right().Object())
+				return op, frame.DO
+			}
+			ret = frame.DO
+			return seq, ret
+		default:
+			panic("wrong right")
+		}
+	}
+
+	left := func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+		n := fu.NodeOf(f)
+		switch n.Left().(type) {
+		case node.ConstantNode:
+			//f.ret[f.ir.Left()] = f.ir.Left().(node.ConstantNode).Data()
+			return right, frame.DO
+		case node.VariableNode:
+			seq = func(f frame.Frame) (seq frame.Sequence, ret frame.WAIT) {
+				//f.ret[f.ir.Left()] = f.p.heap.This(f.ir.Left().Object())
+				return right, frame.DO
+			}
+			ret = frame.DO
+			return seq, ret
+		default:
+			panic("wrong left")
+		}
+	}
+
+	return left, frame.DO
+}

+ 58 - 0
rt2/rules/table.go

@@ -0,0 +1,58 @@
+//dynamicaly loading from outer space
+package rules
+
+import (
+	"cp/node"
+	"fmt"
+	"reflect"
+	"rt2/decision"
+	"rt2/frame"
+	"rt2/nodeframe"
+	"ypk/assert"
+)
+
+func prologue(n node.Node) frame.Sequence {
+	var fu nodeframe.FrameUtils
+	fmt.Println(reflect.TypeOf(n))
+	switch n.(type) {
+	case node.EnterNode:
+		return func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+			node := fu.NodeOf(f).Right()
+			assert.For(node != nil, 40)
+			f.Root().Push(fu.New(node))
+			return frame.Tail(frame.STOP), frame.SKIP
+		}
+	case node.AssignNode:
+		return assignSeq
+	case node.OperationNode:
+		return opSeq
+	case node.CallNode:
+		return callSeq
+	default:
+		panic("unknown node")
+	}
+}
+
+func epilogue(n node.Node) frame.Sequence {
+	var fu nodeframe.FrameUtils
+	switch n.(type) {
+	case node.AssignNode, node.CallNode:
+		return func(f frame.Frame) (frame.Sequence, frame.WAIT) {
+			next := n.Link()
+			if next != nil {
+				f.Root().Push(fu.New(next))
+			}
+			return frame.End()
+		}
+	case node.OperationNode, node.EnterNode:
+		return nil //do nothing
+	default:
+		fmt.Println(reflect.TypeOf(n))
+		panic("unhandled epilogue")
+	}
+}
+
+func init() {
+	decision.PrologueFor = prologue
+	decision.EpilogueFor = epilogue
+}

+ 7 - 0
ypk/assert/debug.go

@@ -0,0 +1,7 @@
+package assert
+
+func For(cond bool, code int) {
+	if !cond {
+		panic(code)
+	}
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно