interop.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package core
  2. import (
  3. "strings"
  4. "kumachan/standalone/util/richtext"
  5. "kumachan/lang/source"
  6. )
  7. type RuntimeHandle interface {
  8. GetFrameInfo() *FrameInfo
  9. WithFrameInfo(info *FrameInfo) RuntimeHandle
  10. LibraryNativeFunction(id string) NativeFunction
  11. ProgramPath() string
  12. ProgramArgs() ([] string)
  13. SerializationContext() SerializationContext
  14. EventLoop() *EventLoop
  15. Debugger() (DebuggerInstance, bool)
  16. }
  17. type FrameInfo struct {
  18. Base *FrameInfo
  19. Callee string
  20. CallSite source.Location
  21. }
  22. var topLevelFrameInfo = &FrameInfo {
  23. Callee: "[top-level]",
  24. }
  25. func TopLevelFrameInfo() *FrameInfo {
  26. return topLevelFrameInfo
  27. }
  28. func AddFrameInfo(h RuntimeHandle, callee string, loc source.Location) RuntimeHandle {
  29. var base = h.GetFrameInfo()
  30. return h.WithFrameInfo(&FrameInfo {
  31. Base: base,
  32. Callee: callee,
  33. CallSite: loc,
  34. })
  35. }
  36. func (info *FrameInfo) DescribeCaller() string {
  37. if info.Base != nil {
  38. return describeFunctionName(info.Base.Callee)
  39. } else {
  40. return "[nil]"
  41. }
  42. }
  43. func (info *FrameInfo) DescribeStackTrace() richtext.Block {
  44. var b richtext.Block
  45. var loc = source.Location {}
  46. for i := info; i != topLevelFrameInfo; i = i.Base {
  47. var callee_desc = describeFunctionName(i.Callee)
  48. b.WriteSpan(callee_desc, richtext.TAG_B)
  49. if loc.File != nil {
  50. var file_desc = loc.FileDesc()
  51. var pos_desc = loc.PosDesc()
  52. b.WriteSpan(file_desc)
  53. b.WriteSpan(pos_desc)
  54. }
  55. b.WriteLineFeed()
  56. loc = i.CallSite
  57. }
  58. return b
  59. }
  60. func describeFunctionName(name string) string {
  61. if name == "" {
  62. return "[entry]"
  63. } else if strings.HasSuffix(name, "::") {
  64. var ns = strings.TrimSuffix(name, "::")
  65. return (ns + "::[entry]")
  66. } else {
  67. return name
  68. }
  69. }