// package inspect package main import ( . "fmt" . "reflect" // "log" ) import "bytes" import "go/parser" import "go/ast" import "go/token" import "net/http" import "net/url" import "html" import "strconv" var _ = html.EscapeString var _ = html.UnescapeString type any interface{} func pr(x ...any) { for _, e := range x { Printf("## %#v ", e) } Println() } // The Registry of numbered objects. func Load() *ast.File { fset := token.NewFileSet() // positions are relative to fset // Parse the file containing this very example // but stop after processing the imports. root, err := parser.ParseFile(fset, "a.go", nil, 0 /*parser.Trace | parser.ParseComments */) if err != nil { panic(err) } pr("root", root) // Print the imports from the file's AST. for _, s := range root.Imports { Println(s.Path.Value) pr(s) pr(s.Path) pr(s.Path.Value) } return root } type Registry struct { next int m map[int]any } type Reply struct { w http.ResponseWriter r *http.Request buf *bytes.Buffer registry *Registry query url.Values } func NewReply(w http.ResponseWriter, r *http.Request, registry *Registry) *Reply { z := &Reply{w: w, r: r, buf: bytes.NewBuffer(nil), registry: registry, query: r.URL.Query()} return z } func NewInspector(root any) *Registry { z := new(Registry) z.m = make(map[int]any) return z } func (p *Registry) Register(x any) int { z := p.next p.next++ p.m[z] = x return z } func (p *Registry) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) // z := bytes.NewBuffer(nil) // z.WriteString("EHLO\r\n") reply := NewReply(w, r, p) reply.Emit() w.Write(reply.buf.Bytes()) } func (p *Reply) Emit() { pr(p.query) s := p.query.Get("n") n, err := strconv.Atoi(s) if err != nil { panic("'n' should be a number: " + s) } obj := p.registry.m[n] p.EmitObject(obj) } func (p *Reply) Html(s string) { p.buf.WriteString(s) } func (p *Reply) Ascii(s string) { p.buf.WriteString(html.EscapeString(s)) } func (p *Reply) EmitObject(x any) { p.Ascii(Sprintf("%#v", x)) } func Serve(root *ast.File) { http.Handle("/", NewInspector(root)) http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { Fprintf(w, "Hello, %q ;;; %q", html.EscapeString(r.URL.Path), html.EscapeString(Sprintf("%#v", r.URL.Query()))) }) panic(http.ListenAndServe(":8080", nil)) } func main() { var x float64 = 3.4 Println("type:", TypeOf(x)) var v = ValueOf(x) Println("value:", v) Println("value:", v.Kind()) Println("value:", v.Float()) root := Load() Serve(root) }