浏览代码

выделил логику выполнения операций и выражений в отдельный модуль

kpmy 10 年之前
父节点
当前提交
5ff167cc44
共有 3 个文件被更改,包括 313 次插入105 次删除
  1. 76 105
      rt/proc.go
  2. 208 0
      rt/seq.go
  3. 29 0
      rt/stack.go

+ 76 - 105
rt/proc.go

@@ -4,7 +4,6 @@ import (
 	"cp/node"
 	"cp/node"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
-	"reflect"
 )
 )
 
 
 type Result int
 type Result int
@@ -20,19 +19,69 @@ type Processor interface {
 	Do() (Result, error)
 	Do() (Result, error)
 }
 }
 
 
+type Sequence interface {
+	Do(f *frame) Wait
+}
+
 func NewProcessor() Processor {
 func NewProcessor() Processor {
 	return new(procImpl).Init()
 	return new(procImpl).Init()
 }
 }
 
 
 type frame struct {
 type frame struct {
-	Frame
-	prologue, epilogue interface{}
-	ir, ret            node.Node
+	p      *procImpl
+	parent *frame
+	ir     node.Node
+	seq    Sequence
+	ret    map[node.Node]interface{}
+}
+
+func (f *frame) Do() (wait Wait) {
+	if f.seq == nil {
+		panic("no sequence")
+	}
+	return f.seq.Do(f)
+}
+
+func (f *frame) OnPush() {
+	switch f.ir.(type) {
+	case node.AssignNode:
+		f.ret = make(map[node.Node]interface{}, 2)
+		f.seq = new(assignSeq)
+	case node.OperationNode:
+		f.ret = make(map[node.Node]interface{}, 3)
+		f.seq = new(opSeq)
+	default:
+		panic("unknown ir")
+	}
+}
+
+func (f *frame) OnPop() {
+	switch f.ir.(type) {
+	case node.AssignNode:
+		if f.ir.Link() != nil {
+			f.p.stack.Push(NewFrame(f.p, f.ir.Link()))
+		}
+	case node.OperationNode:
+		f.parent.ret[f.ir] = f.ret[f.ir]
+	}
+}
+
+func (f *frame) push(t *frame) {
+	t.parent = f
+	f.p.stack.Push(t)
+}
+
+func NewFrame(p *procImpl, ir node.Node) Frame {
+	f := new(frame)
+	f.ir = ir
+	f.p = p
+	return f
 }
 }
 
 
 type procImpl struct {
 type procImpl struct {
 	stack Stack
 	stack Stack
 	heap  Heap
 	heap  Heap
+	cycle int64
 }
 }
 
 
 func (p *procImpl) Init() *procImpl {
 func (p *procImpl) Init() *procImpl {
@@ -44,12 +93,9 @@ func (p *procImpl) Init() *procImpl {
 func (p *procImpl) ConnectTo(head node.Node) (err error) {
 func (p *procImpl) ConnectTo(head node.Node) (err error) {
 	if head != nil {
 	if head != nil {
 		switch head.(type) {
 		switch head.(type) {
+		// особый случай, после enter вправо, а не вниз
 		case node.EnterNode:
 		case node.EnterNode:
-			f := new(frame)
-			f.ir = head.Right()
-			f.prologue = prologue
-			f.epilogue = prologue
-			p.stack.Push(f)
+			p.stack.Push(NewFrame(p, head.Right()))
 		default:
 		default:
 			panic("oops")
 			panic("oops")
 		}
 		}
@@ -59,104 +105,29 @@ func (p *procImpl) ConnectTo(head node.Node) (err error) {
 	return err
 	return err
 }
 }
 
 
-func prologue() {
-
-}
-
-func (p *procImpl) doExpression() {
-	f := p.stack.Top().(*frame)
-	fmt.Println(reflect.TypeOf(f.ir))
-	switch f.ir.(type) {
-	//assign works like .left := .right
-	case node.AssignNode:
-		if f.prologue != nil {
-			f.ret = f.ir.Link()
-			switch f.ir.Left().(type) {
-			case node.VariableNode: //nothing to do
-			default:
-				panic("left is not variable")
-			}
-			switch f.ir.Right().(type) {
-			case node.ConstantNode:
-				x := p.heap.ThisVariable(f.ir.Left().Object())
-				_ = x
-				*x.(*int) = f.ir.Right().(node.ConstantNode).Data().(int)
-				fmt.Println(x)
-				x = p.heap.ThisVariable(f.ir.Left().Object())
-				fmt.Println(*x.(*int))
-			case node.OperationNode:
-				nf := new(frame)
-				nf.ir = f.ir.Right()
-				nf.ret = f.ir
-				nf.prologue = prologue
-				nf.epilogue = node.New(node.CONSTANT)
-				f.epilogue = nf.epilogue
-				p.stack.Push(nf)
-			default:
-				panic("unknown right assign")
-			}
-			f.prologue = nil
-		} else if f.epilogue != nil {
-			switch f.epilogue.(type) {
-			case node.ConstantNode:
-				x := p.heap.ThisVariable(f.ir.Left().Object())
-				_ = x
-				*x.(*int) = f.epilogue.(node.ConstantNode).Data().(int)
-				fmt.Println(*x.(*int))
-			default:
-				fmt.Println("no custom epilogue")
-			}
-			p.stack.Pop()
-			if f.ret != nil {
-				nf := new(frame)
-				nf.ir = f.ret
-				nf.prologue = prologue
-				nf.epilogue = prologue
-				p.stack.Push(nf)
-			}
-
-		}
-	case node.OperationNode:
-		switch f.ir.(node.OperationNode).Operation() {
-		case node.PLUS:
-			var a, b int
-			switch f.ir.Left().(type) {
-			case node.ConstantNode:
-				a = f.ir.Left().(node.ConstantNode).Data().(int)
-			case node.VariableNode:
-				x := p.heap.ThisVariable(f.ir.Left().Object())
-				a = *x.(*int)
-			default:
-				panic("unknown left operand")
-			}
-			switch f.ir.Right().(type) {
-			case node.ConstantNode:
-				b = f.ir.Right().(node.ConstantNode).Data().(int)
-			case node.VariableNode:
-				x := p.heap.ThisVariable(f.ir.Right().Object())
-				b = *x.(*int)
-			default:
-				panic("unknown right operand")
-			}
-			switch f.epilogue.(type) {
-			case node.ConstantNode:
-				fmt.Println(a, b)
-				f.epilogue.(node.ConstantNode).SetData(a + b)
-				p.stack.Pop()
-			default:
-				panic("unknown epilogue")
-			}
-		default:
-			panic("unknown operation")
-		}
-	default:
-		panic("ooops")
-	}
-}
-
 func (p *procImpl) Do() (res Result, err error) {
 func (p *procImpl) Do() (res Result, err error) {
 	if p.stack.Top() != nil {
 	if p.stack.Top() != nil {
-		p.doExpression()
+		fmt.Println(p.cycle)
+		p.cycle++
+		f := p.stack.Top()
+		//цикл дейкстры
+		for {
+			wait := f.Do()
+			fmt.Println(wait)
+			if wait == SKIP {
+				break
+			} else if wait == DO {
+			} else if wait == WRONG {
+				panic("something wrong")
+			} else {
+				if f == p.stack.Top() {
+					p.stack.Pop()
+				} else {
+					panic("do not stop if not top on stack")
+				}
+				break
+			}
+		}
 	} else {
 	} else {
 		err = errors.New("no program")
 		err = errors.New("no program")
 	}
 	}

+ 208 - 0
rt/seq.go

@@ -0,0 +1,208 @@
+package rt
+
+import (
+	"cp/node"
+	"fmt"
+	"reflect"
+)
+
+type assignSeq struct {
+	step func() Wait
+}
+
+func (s *assignSeq) Do(f *frame) (ret Wait) {
+	_ = f.ir.(node.AssignNode)
+	if s.step == nil {
+		ret = DO
+		s.step = func() Wait {
+			switch f.ir.Left().(type) {
+			case node.VariableNode:
+				f.ret[f.ir.Left()] = f.ir.Left().Object()
+				s.step = func() Wait {
+					switch f.ir.Right().(type) {
+					case node.ConstantNode:
+						f.ret[f.ir.Right()] = f.ir.Right().(node.ConstantNode).Data()
+						s.step = func() Wait {
+							fmt.Println(reflect.TypeOf(f.ret[f.ir.Right()]))
+							fmt.Println("присвоение константы")
+							return STOP
+						}
+						return DO
+					case node.OperationNode:
+						nf := NewFrame(f.p, f.ir.Right()).(*frame)
+						f.push(nf)
+						s.step = func() Wait {
+							fmt.Println(reflect.TypeOf(f.ret[f.ir.Right()]))
+							fmt.Println("присвоение результата операции")
+							return STOP
+						}
+						return SKIP
+					default:
+						panic("wrong right")
+					}
+				}
+				return DO
+			default:
+				panic("wrong left")
+			}
+		}
+	} else {
+		ret = s.step()
+	}
+	return ret
+}
+
+type opSeq struct {
+	step func() Wait
+}
+
+func (s *opSeq) Do(f *frame) (ret Wait) {
+	_ = f.ir.(node.OperationNode)
+	op := func() Wait {
+		switch f.ir.(node.OperationNode).Operation() {
+		case node.PLUS:
+			a := f.ret[f.ir.Left()]
+			b := f.ret[f.ir.Right()]
+			f.ret[f.ir] = 0 //a + b
+			fmt.Println("сложение")
+			fmt.Println(reflect.TypeOf(a), reflect.TypeOf(b))
+			return STOP
+		default:
+			panic("unknown operation")
+		}
+	}
+	right := func() Wait {
+		switch f.ir.Right().(type) {
+		case node.ConstantNode:
+			f.ret[f.ir.Right()] = f.ir.Right().(node.ConstantNode).Data()
+			s.step = op
+			return DO
+		case node.VariableNode:
+			s.step = func() Wait {
+				f.ret[f.ir.Right()] = f.p.heap.ThisVariable(f.ir.Right().Object())
+				s.step = op
+				return DO
+			}
+			return SKIP
+		default:
+			panic("wrong right")
+		}
+	}
+	left := func() Wait {
+		switch f.ir.Left().(type) {
+		case node.ConstantNode:
+			f.ret[f.ir.Left()] = f.ir.Left().(node.ConstantNode).Data()
+			s.step = right
+			return DO
+		case node.VariableNode:
+			s.step = func() Wait {
+				f.ret[f.ir.Left()] = f.p.heap.ThisVariable(f.ir.Left().Object())
+				s.step = right
+				return DO
+			}
+			return SKIP
+		default:
+			panic("wrong left")
+		}
+	}
+	if s.step == nil {
+		s.step = left
+		ret = DO
+	} else {
+		ret = s.step()
+	}
+	return ret
+}
+
+/*
+func (p *procImpl) doStat() {
+	f := p.stack.Top().(*frame)
+	fmt.Println(reflect.TypeOf(f.ir))
+	switch f.ir.(type) {
+	//assign works like .left := .right
+	case node.AssignNode:
+		if f.prologue != nil {
+			f.ret = f.ir.Link()
+			switch f.ir.Left().(type) {
+			case node.VariableNode: //nothing to do
+			default:
+				panic("left is not variable")
+			}
+			switch f.ir.Right().(type) {
+			case node.ConstantNode:
+				x := p.heap.ThisVariable(f.ir.Left().Object())
+				_ = x
+				*x.(*int) = f.ir.Right().(node.ConstantNode).Data().(int)
+				fmt.Println(x)
+				x = p.heap.ThisVariable(f.ir.Left().Object())
+				fmt.Println(*x.(*int))
+			case node.OperationNode:
+				nf := new(frame)
+				nf.ir = f.ir.Right()
+				nf.ret = f.ir
+				nf.prologue = prologue
+				nf.epilogue = node.New(node.CONSTANT)
+				f.epilogue = nf.epilogue
+				p.stack.Push(nf)
+			default:
+				panic("unknown right assign")
+			}
+			f.prologue = nil
+		} else if f.epilogue != nil {
+			switch f.epilogue.(type) {
+			case node.ConstantNode:
+				x := p.heap.ThisVariable(f.ir.Left().Object())
+				_ = x
+				*x.(*int) = f.epilogue.(node.ConstantNode).Data().(int)
+				fmt.Println(*x.(*int))
+			default:
+				fmt.Println("no custom epilogue")
+			}
+			p.stack.Pop()
+			if f.ret != nil {
+				nf := new(frame)
+				nf.ir = f.ret
+				nf.prologue = prologue
+				nf.epilogue = prologue
+				p.stack.Push(nf)
+			}
+
+		}
+	case node.OperationNode:
+		switch f.ir.(node.OperationNode).Operation() {
+		case node.PLUS:
+			var a, b int
+			switch f.ir.Left().(type) {
+			case node.ConstantNode:
+				a = f.ir.Left().(node.ConstantNode).Data().(int)
+			case node.VariableNode:
+				x := p.heap.ThisVariable(f.ir.Left().Object())
+				a = *x.(*int)
+			default:
+				panic("unknown left operand")
+			}
+			switch f.ir.Right().(type) {
+			case node.ConstantNode:
+				b = f.ir.Right().(node.ConstantNode).Data().(int)
+			case node.VariableNode:
+				x := p.heap.ThisVariable(f.ir.Right().Object())
+				b = *x.(*int)
+			default:
+				panic("unknown right operand")
+			}
+			switch f.epilogue.(type) {
+			case node.ConstantNode:
+				fmt.Println(a, b)
+				f.epilogue.(node.ConstantNode).SetData(a + b)
+				p.stack.Pop()
+			default:
+				panic("unknown epilogue")
+			}
+		default:
+			panic("unknown operation")
+		}
+	default:
+		panic("ooops")
+	}
+}
+*/

+ 29 - 0
rt/stack.go

@@ -2,6 +2,15 @@ package rt
 
 
 import "container/list"
 import "container/list"
 
 
+type Wait int
+
+const (
+	WRONG Wait = iota
+	SKIP
+	STOP
+	DO
+)
+
 type Stack interface {
 type Stack interface {
 	Push(frame Frame)
 	Push(frame Frame)
 	Pop() Frame
 	Pop() Frame
@@ -9,6 +18,9 @@ type Stack interface {
 }
 }
 
 
 type Frame interface {
 type Frame interface {
+	Do() (wait Wait)
+	OnPush()
+	OnPop()
 }
 }
 
 
 func NewStack() Stack {
 func NewStack() Stack {
@@ -26,6 +38,7 @@ func (s *stdStack) Init() *stdStack {
 
 
 func (s *stdStack) Push(frame Frame) {
 func (s *stdStack) Push(frame Frame) {
 	s.inner.PushFront(frame)
 	s.inner.PushFront(frame)
+	frame.OnPush()
 }
 }
 
 
 func (s *stdStack) Pop() (frame Frame) {
 func (s *stdStack) Pop() (frame Frame) {
@@ -33,6 +46,7 @@ func (s *stdStack) Pop() (frame Frame) {
 		elem := s.inner.Front()
 		elem := s.inner.Front()
 		frame = elem.Value.(Frame)
 		frame = elem.Value.(Frame)
 		s.inner.Remove(elem)
 		s.inner.Remove(elem)
+		frame.OnPop()
 	} else {
 	} else {
 		panic("it's empty stack")
 		panic("it's empty stack")
 	}
 	}
@@ -46,3 +60,18 @@ func (s *stdStack) Top() (frame Frame) {
 	}
 	}
 	return frame
 	return frame
 }
 }
+
+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")
+	}
+}