Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -134,6 +134,7 @@ ${CMAKE_BINARY_DIR}/lib/go/llgo-${LLGO_VERSION}/cgo ${CMAKE_BINARY_DIR}/bin/llgo-go${CMAKE_EXECUTABLE_SUFFIX} cmd/llgoi/llgoi.go + cmd/llgoi/pretty.go GOFLAGS "cc=${CMAKE_BINARY_DIR}/bin/clang" "cxx=${CMAKE_BINARY_DIR}/bin/clang++" "go=${CMAKE_BINARY_DIR}/bin/llgo-go" Index: cmd/llgoi/llgoi.go =================================================================== --- cmd/llgoi/llgoi.go +++ cmd/llgoi/llgoi.go @@ -125,7 +125,8 @@ return err } - return nil + _, err = in.loadSourcePackageFromCode(prettySrc, "__llgo__/pretty", in.copts) + return err } func (in *interp) dispose() { @@ -283,8 +284,7 @@ var code bytes.Buffer fmt.Fprintf(&code, "package %s", pkgname) - code.WriteString("\n\nimport __fmt__ \"fmt\"\n") - code.WriteString("import __os__ \"os\"\n") + code.WriteString("\n\nimport __pretty__ \"__llgo__/pretty\"\n") for _, pkg := range in.imports { fmt.Fprintf(&code, "import %q\n", pkg.Path()) @@ -327,23 +327,17 @@ fmt.Fprintf(&code, " = %s\n\n", l.line) code.WriteString("func init() {\n\t") - for i, t := range typs { - var varname, prefix string + for i := range typs { + var varname string if len(l.assigns) != 0 && l.assigns[i] != "" { if _, ok := in.scope[l.assigns[i]]; ok { fmt.Fprintf(&code, "\t%s = __llgoiV%d\n", l.assigns[i], i) } varname = l.assigns[i] - prefix = l.assigns[i] } else { varname = fmt.Sprintf("__llgoiV%d", i) - prefix = fmt.Sprintf("#%d", i) - } - if _, ok := t.Underlying().(*types.Interface); ok { - fmt.Fprintf(&code, "\t__fmt__.Printf(\"%s %s (%%T) = %%+v\\n\", %s, %s)\n", prefix, t.String(), varname, varname) - } else { - fmt.Fprintf(&code, "\t__fmt__.Printf(\"%s %s = %%+v\\n\", %s)\n", prefix, t.String(), varname) } + fmt.Fprintf(&code, "\t__pretty__.Print(%s)\n", varname) } code.WriteString("}") } else { Index: cmd/llgoi/pretty.go =================================================================== --- /dev/null +++ cmd/llgoi/pretty.go @@ -0,0 +1,96 @@ +package main + +const prettySrc = ` +package pretty + +import ( + "fmt" + "io" + "reflect" + "strconv" + "os" +) + +func Print(val interface{}) { + Fprint(os.Stdout, val) +} + +func Fprint(w io.Writer, val interface{}) { + printIndented(w, val, 0, 2, false) + fmt.Fprint(w, "\n") +} + +func maybePrintConversion(w io.Writer, ty reflect.Type) func() { + if ty.PkgPath() != "" { + fmt.Fprint(w, ty.String() + "(") + return func() { + fmt.Fprint(w, ")") + } + } else { + return func() {} + } +} + +func isSimpleType(ty reflect.Type) bool { + switch ty.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + return true + default: + return false + } +} + +func printIndented(w io.Writer, val interface{}, indent, ptrdepth int, aggElem bool) { + if val == nil { + fmt.Print("nil") + } + + nl := func() { + fmt.Fprint(w, "\n") + for i := 0; i != indent; i++ { + fmt.Fprintf(w, "\t") + } + } + + ty := reflect.TypeOf(val) + switch ty.Kind() { + case reflect.Bool, + reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + defer maybePrintConversion(w, ty)() + fmt.Fprint(w, val) + + case reflect.Array: + if !aggElem { + fmt.Fprint(w, ty.String()) + } + fmt.Fprint(w, "{") + if isSimpleType(ty.Elem()) { + for i := 0; i != ty.Len(); i++ { + if i != 0 { + fmt.Fprint(w, ", ") + } + fmt.Fprint(w, reflect.ValueOf(val).Index(i).Interface()) + } + } else { + indent++ + for i := 0; i != ty.Len(); i++ { + nl() + printIndented(w, reflect.ValueOf(val).Index(i).Interface(), indent, ptrdepth, true) + fmt.Fprint(w, ",") + } + indent-- + nl() + } + fmt.Fprint(w, "}") + + case reflect.String: + defer maybePrintConversion(w, ty)() + fmt.Fprint(w, strconv.Quote(val.(string))) + } +} +`