mini_modify.alc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. include "primitives.alh"
  2. include "constructors.alh"
  3. include "object_operations.alh"
  4. include "library.alh"
  5. include "conformance_scd.alh"
  6. include "io.alh"
  7. include "metamodels.alh"
  8. include "modelling.alh"
  9. include "typing.alh"
  10. include "compiler.alh"
  11. include "utils.alh"
  12. Boolean verbose = True
  13. String function cmd_help_m(write : Boolean):
  14. String result
  15. result = ""
  16. result = result + "Allowed operations:\n"
  17. if (write):
  18. result = result + " == READ/WRITE ==\n"
  19. result = result + " instantiate_node -- Create a new model element (node)\n"
  20. result = result + " instantiate_edge -- Create a new model element (edge)\n"
  21. result = result + " delete -- Delete an existing element\n"
  22. result = result + " attr_add -- Add an attribute to an element\n"
  23. result = result + " attr_add_code -- Add a coded attribute to an element\n"
  24. result = result + " attr_del -- Delete an attribute of an element\n"
  25. result = result + " attr_modify -- Modify an attribute of an element\n"
  26. result = result + " retype -- Change the type of an element\n"
  27. result = result + " upload -- Upload a completely new model\n"
  28. else:
  29. result = result + " == READ-ONLY ==\n"
  30. result = result + " read_outgoing -- Prints the list of outgoing links of an element\n"
  31. result = result + " read_incoming -- Prints the list of incoming links to an element\n"
  32. result = result + " list -- Prints the list of elements in the model\n"
  33. result = result + " list_full -- Prints the list of all elements in the model\n"
  34. result = result + " types -- Prints the list of elements that can be instantiated\n"
  35. result = result + " read -- Prints the current state of a model element\n"
  36. result = result + " verify -- Check whether the model conforms to the metamodel\n"
  37. result = result + " exit -- Leave the modification interface\n"
  38. return result!
  39. String function cmd_instantiate_node(write : Boolean, model : Element, mm_type_name : String, element_name : String):
  40. if (write):
  41. if (dict_in(model["metamodel"]["model"], mm_type_name)):
  42. if (dict_in(model["model"], element_name)):
  43. return "Element exists: " + element_name!
  44. else:
  45. if (is_edge(model["metamodel"]["model"][mm_type_name])):
  46. return "Incorrect format: " + mm_type_name + " is an edge instead of a node"!
  47. element_name = instantiate_node(model, mm_type_name, element_name)
  48. return "Success: " + element_name!
  49. else:
  50. return "Element not found: " + mm_type_name!
  51. else:
  52. return "Write permission denied"!
  53. String function cmd_instantiate_edge(write : Boolean, model : Element, mm_type_name : String, element_name : String, source_name : String, target_name : String):
  54. if (write):
  55. if (dict_in(model["metamodel"]["model"], mm_type_name)):
  56. if (dict_in(model["model"], element_name)):
  57. return "Element exists: " + element_name!
  58. else:
  59. if (is_edge(model["metamodel"]["model"][mm_type_name])):
  60. if (dict_in(model["model"], source_name)):
  61. if (dict_in(model["model"], target_name)):
  62. element_name = instantiate_link(model, mm_type_name, element_name, source_name, target_name)
  63. return "Success: " + element_name!
  64. else:
  65. return "Element not found: " + target_name!
  66. else:
  67. return "Element not found: " + source_name!
  68. else:
  69. return "Incorrect format: " + mm_type_name + " is a node instead of an edge"!
  70. else:
  71. return "Element not found: " + mm_type_name!
  72. else:
  73. return "Write permission denied"!
  74. String function cmd_define_attribute(write : Boolean, model : Element, element_name : String, attr_name : String, type : String):
  75. if (write):
  76. if (dict_in(model["model"], element_name)):
  77. if (dict_in(model["model"], type)):
  78. //TODO automatically find name AttributeLink, as this might change with merging...
  79. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  80. Element attrs
  81. attrs = getInstantiatableAttributes(model, element_name, "AttributeLink")
  82. if (bool_not(set_in(dict_keys(attrs), attr_name))):
  83. model_define_attribute(model, element_name, attr_name, False, type)
  84. return "Success"!
  85. else:
  86. return "Attribute exists: " + attr_name!
  87. else:
  88. return "Not a SimpleClassDiagrams model!"!
  89. else:
  90. return "Element not found: " + type!
  91. else:
  92. return "Element not found: " + element_name!
  93. else:
  94. return "Write permission denied"!
  95. String function cmd_attr_add(write : Boolean, model : Element, element_name : String, attr_name : String, value : Element):
  96. if (write):
  97. if (dict_in(model["model"], element_name)):
  98. Element attrs
  99. attrs = getAttributeList(model, element_name)
  100. if (set_in(dict_keys(attrs), attr_name)):
  101. instantiate_attribute(model, element_name, attr_name, value)
  102. return "Success"!
  103. else:
  104. return "Attribute not found: " + attr_name!
  105. else:
  106. return "Element not found: " + element_name!
  107. else:
  108. return "Write permission denied"!
  109. String function cmd_attr_add_code(write : Boolean, model : Element, element_name : String, attr_name : String):
  110. if (write):
  111. if (dict_in(model["model"], element_name)):
  112. Element attrs
  113. attrs = getAttributeList(model, element_name)
  114. if (set_in(dict_keys(attrs), attr_name)):
  115. output("Waiting for code constructors...")
  116. Element compiled
  117. compiled = compile_code(input())
  118. if (is_physical_string(compiled)):
  119. return "Compilation error: " + cast_string(compiled)!
  120. instantiate_attribute_code(model, element_name, attr_name, compiled)
  121. return "Success"!
  122. else:
  123. return "Attribute not found: " + attr_name!
  124. else:
  125. return "Element not found: " + element_name!
  126. else:
  127. return "Write permission denied"!
  128. String function cmd_attr_del(write : Boolean, model : Element, element_name : String, attr_name : String):
  129. if (write):
  130. if (dict_in(model["model"], element_name)):
  131. Element attrs
  132. attrs = getAttributeList(model, element_name)
  133. if (set_in(dict_keys(attrs), attr_name)):
  134. unset_attribute(model, element_name, attr_name)
  135. return "Success"!
  136. else:
  137. return "Attribute not found: " + attr_name!
  138. else:
  139. return "Element not found: " + element_name!
  140. else:
  141. return "Write permission denied"!
  142. String function cmd_attr_name(write : Boolean, model : Element, element_name : String, attr_name : String, new_attr_name : String):
  143. if (write):
  144. if (dict_in(model["model"], element_name)):
  145. Element attrs
  146. // TODO automatically find AttributeLink name
  147. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  148. attrs = getInstantiatableAttributes(model, element_name, "AttributeLink")
  149. if (set_in(dict_keys(attrs), attr_name)):
  150. if (set_in(dict_keys(attrs), attr_name)):
  151. if (bool_not(set_in(dict_keys(attrs), new_attr_name))):
  152. if (dict_in(model["model"][element_name], attr_name)):
  153. Boolean optional
  154. String attr_edge
  155. attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name))
  156. optional = read_attribute(model, attr_edge, "optional")
  157. model_undefine_attribute(model, element_name, attr_name)
  158. model_define_attribute_ID(model, element_name, new_attr_name, optional, attrs[attr_name], attr_edge)
  159. return "Success"!
  160. else:
  161. return "Attribute not defined here: " + new_attr_name!
  162. else:
  163. return "Attribute exists: " + new_attr_name!
  164. else:
  165. return "Attribute not found: " + attr_name!
  166. else:
  167. return "Attribute not found: " + attr_name!
  168. else:
  169. return "Not a SimpleClassDiagrams model!"!
  170. else:
  171. return "Element not found: " + element_name!
  172. else:
  173. return "Write permission denied"!
  174. String function cmd_attr_type(write : Boolean, model : Element, element_name : String, attr_name : String, new_attr_type : String):
  175. if (write):
  176. if (dict_in(model["model"], element_name)):
  177. if (dict_in(model["model"], new_attr_type)):
  178. Element attrs
  179. // TODO automatically find AttributeLink name
  180. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  181. attrs = getInstantiatableAttributes(model, element_name, "AttributeLink")
  182. if (set_in(dict_keys(attrs), attr_name)):
  183. if (set_in(dict_keys(attrs), attr_name)):
  184. if (dict_in(model["model"][element_name], attr_name)):
  185. Boolean optional
  186. String attr_edge
  187. attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name))
  188. optional = read_attribute(model, attr_edge, "optional")
  189. model_undefine_attribute(model, element_name, attr_name)
  190. model_define_attribute_ID(model, element_name, attr_name, optional, new_attr_type, attr_edge)
  191. return "Success"!
  192. else:
  193. return "Attribute not defined here: " + attr_name!
  194. else:
  195. return "Attribute not defined: " + attr_name!
  196. else:
  197. return "Attribute not found: " + attr_name!
  198. else:
  199. return "Not a SimpleClassDiagrams model!"!
  200. else:
  201. return "Element not found: " + new_attr_type!
  202. else:
  203. return "Element not found: " + element_name!
  204. else:
  205. return "Write permission denied"!
  206. String function cmd_attr_optional(write : Boolean, model : Element, element_name : String, attr_name : String, optional : Boolean):
  207. if (write):
  208. if (dict_in(model["model"], element_name)):
  209. Element attrs
  210. // TODO automatically find AttributeLink name
  211. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  212. attrs = getInstantiatableAttributes(model, element_name, "AttributeLink")
  213. if (set_in(dict_keys(attrs), attr_name)):
  214. if (set_in(dict_keys(attrs), attr_name)):
  215. if (dict_in(model["model"][element_name], attr_name)):
  216. String attr_edge
  217. attr_edge = reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_name))
  218. model_undefine_attribute(model, element_name, attr_name)
  219. model_define_attribute_ID(model, element_name, attr_name, optional, attrs[attr_name], attr_edge)
  220. return "Success"!
  221. else:
  222. return "Attribute not defined here: " + attr_name!
  223. else:
  224. return "Attribute not defined: " + attr_name!
  225. else:
  226. return "Attribute not found: " + attr_name!
  227. else:
  228. return "Not a SimpleClassDiagrams model!"!
  229. else:
  230. return "Element not found: " + element_name!
  231. else:
  232. return "Write permission denied"!
  233. String function cmd_undefine_attribute(write : Boolean, model : Element, element_name : String, attr_name : String):
  234. if (write):
  235. if (dict_in(model["model"], element_name)):
  236. //TODO automatically find name AttributeLink, as this might change with merging...
  237. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  238. Element attrs
  239. attrs = getInstantiatableAttributes(model, element_name, "AttributeLink")
  240. if (set_in(dict_keys(attrs), attr_name)):
  241. if (set_in(dict_keys(attrs), attr_name)):
  242. if (dict_in(model["model"][element_name], attr_name)):
  243. model_undefine_attribute(model, element_name, attr_name)
  244. return "Success"!
  245. else:
  246. return "Attribute not defined here: " + attr_name!
  247. else:
  248. return "Attribute not defined: " + attr_name!
  249. else:
  250. return "Attribute not found: " + attr_name!
  251. else:
  252. return "Not a SimpleClassDiagrams model!"!
  253. else:
  254. return "Element not found: " + element_name!
  255. else:
  256. return "Write permission denied"!
  257. String function cmd_delete(write : Boolean, model : Element, element_name : String):
  258. if (write):
  259. if (dict_in(model["model"], element_name)):
  260. model_delete_element(model, element_name)
  261. return "Success"!
  262. else:
  263. return "Element not found: " + element_name!
  264. else:
  265. return "Write permission denied"!
  266. String function cmd_list_full(model : Element):
  267. Element keys_m
  268. String v_m
  269. String result
  270. String typename
  271. result = "Success: "
  272. keys_m = dict_keys(model["model"])
  273. while (set_len(keys_m) > 0):
  274. v_m = set_pop(keys_m)
  275. // Filter out anonymous objects
  276. typename = read_type(model, v_m)
  277. result = result + " " + v_m + " : " + typename + "\n"
  278. return result!
  279. String function cmd_read_outgoing(model : Element, element_name : String, type : String):
  280. String result
  281. Element elems
  282. if (dict_in(model["model"], element_name)):
  283. if (bool_or(dict_in(model["metamodel"]["model"], type), type == "")):
  284. result = "Success: "
  285. elems = allOutgoingAssociationInstances(model, element_name, type)
  286. while (set_len(elems) > 0):
  287. result = string_join(result, set_pop(elems)) + "\n"
  288. return result!
  289. else:
  290. return "Element not found: " + type!
  291. else:
  292. return "Element not found: " + element_name!
  293. String function cmd_read_incoming(model : Element, element_name : String, type : String):
  294. String result
  295. Element elems
  296. if (dict_in(model["model"], element_name)):
  297. if (bool_or(dict_in(model["metamodel"]["model"], type), type == "")):
  298. result = "Success: "
  299. elems = allIncomingAssociationInstances(model, element_name, type)
  300. while (set_len(elems) > 0):
  301. result = string_join(result, set_pop(elems)) + "\n"
  302. return result!
  303. else:
  304. return "Element not found: " + type!
  305. else:
  306. return "Element not found: " + element_name!
  307. String function cmd_connections_between(model : Element, source_name : String, target_name : String):
  308. String result
  309. Element options
  310. if (dict_in(model["model"], source_name)):
  311. if (dict_in(model["model"], target_name)):
  312. result = "Success: "
  313. options = allowedAssociationsBetween(model, source_name, target_name)
  314. while (set_len(options) > 0):
  315. result = string_join(result, set_pop(options)) + "\n"
  316. return result!
  317. else:
  318. return ("Element not found: " + target_name)!
  319. else:
  320. return ("Element not found: " + source_name)!
  321. String function cmd_read(model : Element, element_name : String):
  322. String result
  323. Element attr_list
  324. Element attr_keys
  325. String attr_key
  326. result = "Success: "
  327. if (dict_in(model["model"], element_name)):
  328. result = result + "Type: " + read_type(model, element_name) + "\n"
  329. if (is_edge(model["model"][element_name])):
  330. result = result + "Source: " + reverseKeyLookup(model["model"], read_edge_src(model["model"][element_name])) + "\n"
  331. result = result + "Destination: " + reverseKeyLookup(model["model"], read_edge_dst(model["model"][element_name])) + "\n"
  332. if (has_value(model["model"][element_name])):
  333. result = result + "Value: " + cast_value(model["model"][element_name]) + "\n"
  334. return result!
  335. else:
  336. return "Element not found: " + element_name!
  337. String function cmd_read_attrs(model : Element, element_name : String):
  338. String result
  339. Element attr_list
  340. Element attr_keys
  341. String attr_key
  342. String attr
  343. result = "Success: "
  344. if (dict_in(model["model"], element_name)):
  345. attr_list = getAttributeList(model, element_name)
  346. attr_keys = dict_keys(attr_list)
  347. while (0 < set_len(attr_keys)):
  348. attr_key = set_pop(attr_keys)
  349. attr = read_attribute(model, element_name, attr_key)
  350. if (read_type(model["metamodel"], attr_list[attr_key]) == "ActionLanguage"):
  351. if (element_eq(attr, read_root())):
  352. result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = {\"AL\": \"\"}\n"
  353. else:
  354. result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = {\"AL\": " + cast_value(attr) + "}\n"
  355. else:
  356. result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = " + cast_value(attr) + "\n"
  357. return result!
  358. else:
  359. return "Element not found: " + element_name!
  360. String function cmd_read_defined_attrs(model : Element, element_name : String):
  361. String result
  362. Element attr_list
  363. Element attr_keys
  364. String attr_key
  365. Element optionality
  366. result = "Success: "
  367. if (dict_in(model["model"], element_name)):
  368. //TODO automatically find name AttributeLink, as this might change with merging...
  369. if (dict_in(model["metamodel"]["model"], "AttributeLink")):
  370. attr_list = getInstantiatableAttributes(model, element_name, "AttributeLink")
  371. optionality = getAttributeOptionality(model, element_name, "AttributeLink")
  372. attr_keys = dict_keys(attr_list)
  373. while (0 < set_len(attr_keys)):
  374. attr_key = set_pop(attr_keys)
  375. if (optionality[attr_key]):
  376. result = string_join(result, attr_key) + " ?: " + cast_string(attr_list[attr_key]) + "\n"
  377. else:
  378. result = string_join(result, attr_key) + " : " + cast_string(attr_list[attr_key]) + "\n"
  379. return result!
  380. else:
  381. return "Not a SimpleClassDiagrams model!"!
  382. else:
  383. return "Element not found: " + element_name!
  384. String function cmd_types(model : Element):
  385. Element keys_t
  386. String v_t
  387. String result
  388. keys_t = dict_keys(model["metamodel"]["model"])
  389. result = "Success: "
  390. while (set_len(keys_t) > 0):
  391. v_t = set_pop(keys_t)
  392. result = result + string_join(" " + v_t + " : ", read_type(model["metamodel"], v_t)) + "\n"
  393. return result!
  394. String function cmd_retype(write : Boolean, model : Element, element_name : String, new_type : String):
  395. if (write):
  396. if (dict_in(model["model"], element_name)):
  397. if (dict_in(model["metamodel"]["model"], new_type)):
  398. retype(model, element_name, new_type)
  399. return "Success"!
  400. else:
  401. return "Element not found: " + new_type!
  402. else:
  403. return "Element not found: " + element_name!
  404. else:
  405. return "Write permission denied"!
  406. String function cmd_read_association_source(write : Boolean, model : Element, element_name : String):
  407. if (dict_in(model["model"], element_name)):
  408. if (is_edge(model["model"][element_name])):
  409. return "Success: " + readAssociationSource(model, element_name)!
  410. else:
  411. return "Not an association: " + element_name!
  412. else:
  413. return "Element not found: " + element_name!
  414. String function cmd_read_association_destination(write : Boolean, model : Element, element_name : String):
  415. if (dict_in(model["model"], element_name)):
  416. if (is_edge(model["model"][element_name])):
  417. return "Success: " + readAssociationDestination(model, element_name)!
  418. else:
  419. return "Not an association: " + element_name!
  420. else:
  421. return "Element not found: " + element_name!
  422. String function cmd_all_instances(model : Element, type : String):
  423. String result
  424. Element elems
  425. if (dict_in(model["metamodel"]["model"], type)):
  426. result = "Success: "
  427. elems = allInstances(model, type)
  428. while (set_len(elems) > 0):
  429. result = string_join(result, set_pop(elems)) + "\n"
  430. return result!
  431. else:
  432. return "Element not found: " + type!
  433. Boolean function modify(model : Element, write : Boolean):
  434. String cmd
  435. output("Model loaded, ready for commands!")
  436. while (True):
  437. cmd = input()
  438. if (cmd == "help"):
  439. output(cmd_help_m(write))
  440. elif (cmd == "exit"):
  441. return True!
  442. elif (cmd == "instantiate_node"):
  443. output(cmd_instantiate_node(write, model, single_input("Type?"), single_input("Name?")))
  444. elif (cmd == "instantiate_edge"):
  445. output(cmd_instantiate_edge(write, model, single_input("Type?"), single_input("Name?"), single_input("Source?"), single_input("Target?")))
  446. elif (cmd == "attr_add"):
  447. output(cmd_attr_add(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("Value?")))
  448. elif (cmd == "attr_add_code"):
  449. output(cmd_attr_add_code(write, model, single_input("Name?"), single_input("Attribute name?")))
  450. elif (cmd == "attr_delete"):
  451. output(cmd_attr_del(write, model, single_input("Name?"), single_input("Attribute name?")))
  452. elif (cmd == "attr_name"):
  453. output(cmd_attr_name(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("New name?")))
  454. elif (cmd == "attr_type"):
  455. output(cmd_attr_type(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("Type name?")))
  456. elif (cmd == "attr_optional"):
  457. output(cmd_attr_optional(write, model, single_input("Name?"), single_input("Attribute name?"), input()))
  458. elif (cmd == "delete"):
  459. output(cmd_delete(write, model, single_input("Name?")))
  460. elif (cmd == "list_full"):
  461. output(cmd_list_full(model))
  462. elif (cmd == "JSON"):
  463. output("Success: " + JSON_print(model))
  464. elif (cmd == "read_outgoing"):
  465. output(cmd_read_outgoing(model, single_input("Name?"), single_input("Type?")))
  466. elif (cmd == "read_incoming"):
  467. output(cmd_read_incoming(model, single_input("Name?"), single_input("Type?")))
  468. elif (cmd == "read"):
  469. output(cmd_read(model, single_input("Name?")))
  470. elif (cmd == "read_attrs"):
  471. output(cmd_read_attrs(model, single_input("Name?")))
  472. elif (cmd == "read_defined_attrs"):
  473. output(cmd_read_defined_attrs(model, single_input("Name?")))
  474. elif (cmd == "types"):
  475. output(cmd_types(model))
  476. elif (cmd == "retype"):
  477. output(cmd_retype(write, model, single_input("Name?"), single_input("New type?")))
  478. elif (cmd == "read_association_source"):
  479. output(cmd_read_association_source(write, model, single_input("Name?")))
  480. elif (cmd == "read_association_destination"):
  481. output(cmd_read_association_destination(write, model, single_input("Name?")))
  482. elif (cmd == "connections_between"):
  483. output(cmd_connections_between(model, single_input("Source element?"), single_input("Target element?")))
  484. elif (cmd == "all_instances"):
  485. output(cmd_all_instances(model, single_input("Type?")))
  486. elif (cmd == "define_attribute"):
  487. output(cmd_define_attribute(write, model, single_input("On which element?"), single_input("Attribute name?"), single_input("Type?")))
  488. elif (cmd == "undefine_attribute"):
  489. output(cmd_undefine_attribute(write, model, single_input("On which element?"), single_input("Attribute name?")))
  490. else:
  491. output("Unknown command while modelling: " + cast_value(cmd))
  492. output("Use command 'help' to get a list of available commands")
  493. String function single_input(prompt : String):
  494. if (verbose):
  495. output(prompt)
  496. return input()!
  497. Element function set_input(prompt : String):
  498. Element result
  499. Element inp
  500. if (verbose):
  501. output(prompt)
  502. output("-- Set input: empty string to terminate set")
  503. result = set_create()
  504. while (True):
  505. inp = input()
  506. if (value_eq(inp, "")):
  507. return result!
  508. else:
  509. set_add(result, inp)
  510. Element function dict_input(prompt : String):
  511. Element result
  512. Element key
  513. if (verbose):
  514. output(prompt)
  515. output("-- Dict input: empty key to terminate dict")
  516. result = set_create()
  517. while (True):
  518. key = input()
  519. if (value_eq(key, "")):
  520. return result!
  521. else:
  522. dict_add(result, key, input())
  523. Void function set_verbose(v : Boolean):
  524. verbose = v
  525. return!