typing.alc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. include "primitives.alh"
  2. include "utils.alh"
  3. Element function get_type_mapping(model : Element):
  4. // Deserialize dictionary as model
  5. Element tm_model
  6. tm_model = dict_create()
  7. Element m
  8. Element mm
  9. Element edge
  10. Element keys
  11. String key
  12. keys = dict_keys(model["type_mapping"])
  13. while (set_len(keys) > 0):
  14. key = set_pop(keys)
  15. m = model["model"][key]
  16. mm = model["metamodel"]["model"][model["type_mapping"][key]]
  17. edge = create_edge(m, mm)
  18. dict_add_fast(tm_model, cast_id2s(m), m)
  19. if (bool_not(dict_in(tm_model, cast_id2s(mm)))):
  20. dict_add_fast(tm_model, cast_id2s(mm), mm)
  21. dict_add_fast(tm_model, cast_id2s(edge), edge)
  22. return tm_model!
  23. Void function set_type_mapping(model : Element, type_mapping_model : Element):
  24. // Serialize model to dictionary
  25. Element type_mapping
  26. Element rev_model
  27. Element rev_metamodel
  28. Element keys
  29. String key
  30. type_mapping = dict_create()
  31. keys = dict_keys(type_mapping_model)
  32. rev_model = make_reverse_dictionary(model["model"])
  33. rev_metamodel = make_reverse_dictionary(model["metamodel"]["model"])
  34. while (set_len(keys) > 0):
  35. key = set_pop(keys)
  36. if (is_edge(type_mapping_model[key])):
  37. if (bool_not(bool_or(dict_in(rev_model, cast_id2s(type_mapping_model[key])), dict_in(rev_metamodel, cast_id2s(type_mapping_model[key]))))):
  38. // Element is in neither model or metamodel
  39. // Must be a typing link!
  40. // So add it
  41. dict_add_fast(type_mapping, rev_model[cast_id2s(read_edge_src(type_mapping_model[key]))], rev_metamodel[cast_id2s(read_edge_dst(type_mapping_model[key]))])
  42. dict_overwrite(model, "type_mapping", type_mapping)
  43. dict_overwrite(model, "type_mapping_model", type_mapping_model)
  44. return!
  45. Element function elements_typed_by(model : Element, type_name : String):
  46. Element result
  47. result = reverseKeyLookupMulti(get_type_mapping_as_dict(model), type_name)
  48. return result!
  49. Element function get_type_mapping_as_dict(model : Element):
  50. return model["type_mapping"]!
  51. Element function get_elements_typed_by(model : Element, type : String):
  52. return reverseKeyLookupMulti(model["type_mapping"], type)!
  53. String function read_type(model : Element, name : String):
  54. String result
  55. Element tm
  56. if (dict_in(model["model"], name)):
  57. if (dict_in(model["type_mapping"], name)):
  58. result = model["type_mapping"][name]
  59. if (dict_in(model["metamodel"]["model"], result)):
  60. return result!
  61. else:
  62. return ""!
  63. else:
  64. return ""!
  65. else:
  66. return ""!
  67. Void function retype(model : Element, element : String, type : String):
  68. // Retype a model, deleting any previous type the element had
  69. // The type string is evaluated in the metamodel previously specified
  70. dict_overwrite(model["type_mapping"], element, type)
  71. // TODO this is a serious problem, which we now want to avoid...
  72. if (cast_id2s(model["model"][element]) == "0"):
  73. return!
  74. // Remove previous type
  75. String elem
  76. elem = cast_id2s(model["model"][element])
  77. if (dict_in(model["type_mapping_model"], elem)):
  78. dict_delete(model["type_mapping_model"], elem)
  79. // Add element of the model
  80. dict_add_fast(model["type_mapping_model"], cast_id2s(model["model"][element]), model["model"][element])
  81. // Add element of metamodel if not yet there
  82. Element type_entry
  83. type_entry = model["metamodel"]["model"][type]
  84. if (bool_not(dict_in(model["type_mapping_model"], cast_id2s(type_entry)))):
  85. dict_add_fast(model["type_mapping_model"], cast_id2s(type_entry), type_entry)
  86. // Draw a link between them: the typing link
  87. Element new_edge
  88. new_edge = create_edge(model["model"][element], type_entry)
  89. dict_add_fast(model["type_mapping_model"], cast_id2s(new_edge), new_edge)
  90. return!
  91. Void function new_type_mapping(model : Element):
  92. dict_overwrite(model, "type_mapping", dict_create())
  93. dict_overwrite(model["type_mapping_model"], "model", dict_create())
  94. return !
  95. Void function remove_type(model : Element, name : String):
  96. dict_delete(model["type_mapping"], name)
  97. String elem
  98. elem = cast_id2s(model["model"][name])
  99. if (dict_in(model["type_mapping"], elem)):
  100. dict_delete(model["type_mapping"], elem)
  101. return !