symbol.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package loader
  2. import (
  3. "fmt"
  4. "kumachan/transformer/node"
  5. )
  6. const CoreModule = "Core"
  7. type MaybeSymbol interface { MaybeSymbol() }
  8. func (Symbol) MaybeSymbol() {}
  9. type Symbol struct {
  10. ModuleName string
  11. SymbolName string
  12. }
  13. func (sym Symbol) String() string {
  14. if sym.ModuleName == "" {
  15. return sym.SymbolName
  16. } else {
  17. return fmt.Sprintf("%s::%s", sym.ModuleName, sym.SymbolName)
  18. }
  19. }
  20. func NewSymbol (mod string, sym string) Symbol {
  21. return Symbol {
  22. ModuleName: mod,
  23. SymbolName: sym,
  24. }
  25. }
  26. func Id2String(id node.Identifier) string {
  27. return string(id.Name)
  28. }
  29. func (mod *Module) SymbolFromName(name node.Identifier) Symbol {
  30. var sym_name = Id2String(name)
  31. var _, exists = __PreloadCoreSymbolSet[sym_name]
  32. if exists {
  33. return NewSymbol(CoreModule, sym_name)
  34. } else {
  35. return NewSymbol(Id2String(mod.Node.Name), sym_name)
  36. }
  37. }
  38. func (mod *Module) SymbolFromRef(ref node.Ref) MaybeSymbol {
  39. var ref_mod = Id2String(ref.Module)
  40. var corresponding, exists = mod.ImpMap[ref_mod]
  41. if exists {
  42. return NewSymbol (
  43. Id2String(corresponding.Node.Name),
  44. Id2String(ref.Id),
  45. )
  46. } else {
  47. if ref_mod == "" {
  48. var sym_name = Id2String(ref.Id)
  49. if ref.Specific {
  50. // ::Module <=> Module::Module
  51. return NewSymbol(sym_name, sym_name)
  52. } else {
  53. var _, exists = __PreloadCoreSymbolSet[sym_name]
  54. if exists {
  55. // Core::Int, Core::Float, Core::Effect, ...
  56. return NewSymbol(CoreModule, sym_name)
  57. } else {
  58. // Self::SymbolName
  59. return NewSymbol("", sym_name)
  60. }
  61. }
  62. } else {
  63. return nil
  64. }
  65. }
  66. }
  67. func (mod *Module) TypeSymbolFromRef(ref node.Ref) MaybeSymbol {
  68. var self = Id2String(mod.Node.Name)
  69. var maybe_sym = mod.SymbolFromRef(ref)
  70. var sym, ok = maybe_sym.(Symbol)
  71. if ok {
  72. if sym.ModuleName == "" {
  73. return NewSymbol(self, sym.SymbolName)
  74. } else {
  75. return sym
  76. }
  77. } else {
  78. return nil
  79. }
  80. }
  81. /* should be consistent with `stdlib/core.km` */
  82. var __PreloadCoreSymbols = []string {
  83. "Bit", "Byte", "Word", "Dword", "Qword", "Integer", "Float64",
  84. "Bytes", "String", "Seq", "Array", "Heap", "Set", "Map",
  85. "Effect*", "Effect",
  86. "Int64", "Uint64", "Int32", "Uint32", "Int16", "Uint16", "Int8", "Uint8",
  87. "Char", "Natural", "Float",
  88. "Bool", "Yes", "No",
  89. "Maybe", "Just", "N/A",
  90. "Result", "OK", "NG",
  91. }
  92. var __PreloadCoreSymbolSet = func() map[string] bool {
  93. var set = make(map[string] bool)
  94. for _, name := range __PreloadCoreSymbols {
  95. set[name] = true
  96. }
  97. return set
  98. } ()
  99. func IsPreloadCoreSymbol (sym Symbol) bool {
  100. var _, exists = __PreloadCoreSymbolSet[sym.SymbolName]
  101. if exists {
  102. if sym.ModuleName != CoreModule {
  103. panic("invalid symbol: preload symbol must belong to CoreModule")
  104. }
  105. return true
  106. } else {
  107. return false
  108. }
  109. }