package hhc_ast import ( "git.swzry.com/zry/go-hhc-cli/hhc_common" ) type SDTWalker struct { root *SyntaxDefinitionTreeRoot current SyntaxDefTreeNode ctx *SDTWalkContext currentError hhc_common.SDTWalkError depthCount uint32 actualDepth uint32 } func NewSDTWalker(rootnode *SyntaxDefinitionTreeRoot) *SDTWalker { w := &SDTWalker{ root: rootnode, current: rootnode, ctx: &SDTWalkContext{ASTNodes: []ASTNode{}}, currentError: nil, depthCount: 0, actualDepth: 0, } return w } func (w *SDTWalker) Reset() { w.current = w.root w.ctx = &SDTWalkContext{ASTNodes: []ASTNode{}} w.currentError = nil w.depthCount = 0 w.actualDepth = 0 } func (w *SDTWalker) NextStep(token string) bool { //fmt.Println("On NextStep, dc=", w.depthCount, "ad=", w.actualDepth) w.depthCount++ if w.depthCount == w.actualDepth+1 { nc, serr := w.current.WalkNext(w.ctx, token) if serr != nil { w.currentError = serr return false } w.current = nc w.actualDepth++ w.currentError = nil return true } return false } func (w *SDTWalker) Back() bool { //fmt.Println("On Back, dc=", w.depthCount, "ad=", w.actualDepth) if w.depthCount > 0 { w.depthCount-- if w.depthCount < w.actualDepth { nc, serr := w.current.Fallback(w.ctx) if serr != nil { switch serr.(type) { case hhc_common.SDTWalkError_RootNodeCannotFallback: w.Reset() return false } w.currentError = serr return false } w.current = nc w.actualDepth-- w.currentError = nil return true } } return false } func (w *SDTWalker) GetHelps(prefix string) []hhc_common.SDTHelpInfo { return w.current.GetHelps(prefix) } func (w *SDTWalker) GetContext() *SDTWalkContext { return w.ctx } func (w *SDTWalker) GetError() hhc_common.SDTWalkError { return w.currentError } func (w *SDTWalker) HasError() bool { return w.currentError != nil } func (w *SDTWalker) IsSync() bool { return w.actualDepth == w.actualDepth } func (w *SDTWalker) IsEnd() bool { return w.current.IsEnd() } func (w *SDTWalker) GetEndExecute() (bool, ExecuteFunc) { if w.IsEnd() { e := w.current.(*SDTNode_End) if e != nil { ef := e.Exec return true, ef } else { return false, nil } } else { return false, nil } }