constant.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package checker
  2. import (
  3. "kumachan/loader"
  4. "kumachan/transformer/node"
  5. . "kumachan/error"
  6. )
  7. type Constant struct {
  8. Node node.Node
  9. IsPublic bool
  10. DeclaredType Type
  11. Value node.ConstValue
  12. }
  13. type ConstantCollection map[loader.Symbol] *Constant
  14. type ConstantStore map[string] ConstantCollection
  15. func CollectConstants(mod *loader.Module, reg TypeRegistry, store ConstantStore) (ConstantCollection, *ConstantError) {
  16. var mod_name = mod.Name
  17. var existing, exists = store[mod_name]
  18. if exists {
  19. return existing, nil
  20. }
  21. var collection = make(ConstantCollection)
  22. for _, imported := range mod.ImpMap {
  23. var imp_mod_name = loader.Id2String(imported.Node.Name)
  24. var imp_col, err = CollectConstants(imported, reg, store)
  25. if err != nil { return nil, err }
  26. for name, constant := range imp_col {
  27. if name.ModuleName == imp_mod_name && constant.IsPublic {
  28. var _, exists = collection[name]
  29. if exists { panic("something went wrong") }
  30. collection[name] = constant
  31. }
  32. }
  33. }
  34. for _, cmd := range mod.Node.Commands {
  35. switch c := cmd.Command.(type) {
  36. case node.DeclConst:
  37. var decl = c
  38. var name = mod.SymbolFromName(decl.Name)
  39. if name.SymbolName == IgnoreMark {
  40. return nil, &ConstantError {
  41. Point: ErrorPoint { AST: mod.AST, Node: c.Name.Node },
  42. Concrete: E_InvalidConstName { name.SymbolName },
  43. }
  44. }
  45. var _, exists = collection[name]
  46. if exists { return nil, &ConstantError {
  47. Point: ErrorPoint { AST: mod.AST, Node: c.Name.Node },
  48. Concrete: E_DuplicateConstDecl {
  49. Name: name.SymbolName,
  50. },
  51. } }
  52. exists, _ = reg.LookupArity(name)
  53. if exists { return nil, &ConstantError {
  54. Point: ErrorPoint { AST: mod.AST, Node: c.Name.Node, },
  55. Concrete: E_ConstConflictWithType {
  56. Name: name.SymbolName,
  57. },
  58. } }
  59. var ctx = TypeContext {
  60. Module: mod,
  61. Params: make([]string, 0),
  62. Ireg: reg,
  63. }
  64. var is_public = decl.IsPublic
  65. var declared_type, err = TypeFrom(decl.Type.Type, ctx)
  66. if err != nil { return nil, &ConstantError {
  67. Point: ErrorPoint { AST: mod.AST, Node: c.Type.Node },
  68. Concrete: E_ConstTypeInvalid {
  69. ConstName: name.String(),
  70. TypeError: err,
  71. },
  72. } }
  73. var value = decl.Value.ConstValue
  74. var constant = &Constant {
  75. Node: c.Node,
  76. IsPublic: is_public,
  77. DeclaredType: declared_type,
  78. Value: value,
  79. }
  80. collection[name] = constant
  81. }
  82. }
  83. store[mod_name] = collection
  84. return collection, nil
  85. }