package interp

import (
	
	
	
	
	
	
)

// astDot displays an AST in graphviz dot(1) format using dotty(1) co-process.
func ( *node) ( io.Writer,  string) {
	fmt.Fprintf(, "digraph ast {\n")
	fmt.Fprintf(, "labelloc=\"t\"\n")
	fmt.Fprintf(, "label=\"%s\"\n", )
	.Walk(func( *node) bool {
		var  string
		switch .kind {
		case basicLit, identExpr:
			 = strings.ReplaceAll(.ident, "\"", "\\\"")
		default:
			if .action != aNop {
				 = .action.String()
			} else {
				 = .kind.String()
			}
		}
		fmt.Fprintf(, "%d [label=\"%d: %s\"]\n", .index, .index, )
		if .anc != nil {
			fmt.Fprintf(, "%d -> %d\n", .anc.index, .index)
		}
		return true
	}, nil)
	fmt.Fprintf(, "}\n")
}

// cfgDot displays a CFG in graphviz dot(1) format using dotty(1) co-process.
func ( *node) ( io.Writer) {
	fmt.Fprintf(, "digraph cfg {\n")
	.Walk(nil, func( *node) {
		if .kind == basicLit || .tnext == nil {
			return
		}
		var  string
		if .action == aNop {
			 = "nop: end_" + .kind.String()
		} else {
			 = .action.String()
		}
		fmt.Fprintf(, "%d [label=\"%d: %v %d\"]\n", .index, .index, , .findex)
		if .fnext != nil {
			fmt.Fprintf(, "%d -> %d [color=green]\n", .index, .tnext.index)
			fmt.Fprintf(, "%d -> %d [color=red]\n", .index, .fnext.index)
		} else if .tnext != nil {
			fmt.Fprintf(, "%d -> %d\n", .index, .tnext.index)
		}
	})
	fmt.Fprintf(, "}\n")
}

type nopCloser struct {
	io.Writer
}

func (nopCloser) () error { return nil }

// dotWriter returns an output stream to a dot(1) co-process where to write data in .dot format.
func dotWriter( string) io.WriteCloser {
	if  == "" {
		return nopCloser{io.Discard}
	}
	 := strings.Fields()
	 := exec.Command([0], [1:]...)
	,  := .StdinPipe()
	if  != nil {
		log.Fatal()
	}
	if  = .Start();  != nil {
		log.Fatal()
	}
	return 
}

func defaultDotCmd(,  string) string {
	,  := filepath.Split()
	 := filepath.Ext()
	if  == "" {
		 += ".dot"
	} else {
		 = strings.Replace(, , ".dot", 1)
	}
	return "dot -Tdot -o" +  +  + 
}