/src/tools/liberty_universe.e

http://github.com/tybor/Liberty · Specman e · 1353 lines · 1207 code · 126 blank · 20 comment · 46 complexity · ff46476357431ba4f89d4e8e520646dd MD5 · raw file

  1. -- This file is part of Liberty Eiffel.
  2. --
  3. -- Liberty Eiffel is free software: you can redistribute it and/or modify
  4. -- it under the terms of the GNU General Public License as published by
  5. -- the Free Software Foundation, version 3 of the License.
  6. --
  7. -- Liberty Eiffel is distributed in the hope that it will be useful,
  8. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. -- GNU General Public License for more details.
  11. --
  12. -- You should have received a copy of the GNU General Public License
  13. -- along with Liberty Eiffel. If not, see <http://www.gnu.org/licenses/>.
  14. --
  15. class LIBERTY_UNIVERSE
  16. insert
  17. LIBERTY_ERROR_LEVELS
  18. undefine is_equal
  19. end
  20. LIBERTY_AST_HANDLER
  21. undefine is_equal
  22. end
  23. LIBERTY_ERROR_LEVELS
  24. undefine is_equal
  25. end
  26. SINGLETON
  27. LOGGING
  28. undefine is_equal
  29. end
  30. create {ANY}
  31. make
  32. feature {ANY}
  33. get_type (cluster: LIBERTY_CLUSTER; position: LIBERTY_POSITION; class_name: FIXED_STRING; effective_type_parameters: TRAVERSABLE[LIBERTY_ACTUAL_TYPE]): LIBERTY_ACTUAL_TYPE is
  34. require
  35. position /= Void
  36. do
  37. Result := do_get_type(cluster, position, class_name, effective_type_parameters)
  38. ensure
  39. Result.name.is_equal(class_name)
  40. same_parameters(Result.parameters, effective_type_parameters)
  41. end
  42. parse_expression (a_expression: STRING; when_error: PROCEDURE[TUPLE[PARSE_ERROR]]): LIBERTY_AST_EXPRESSION is
  43. require
  44. a_expression /= Void
  45. when_error /= Void
  46. do
  47. Result ::= partial_parse(a_expression, once "Expression", when_error)
  48. end
  49. parse_instruction (a_instruction: STRING; when_error: PROCEDURE[TUPLE[PARSE_ERROR]]): LIBERTY_AST_INSTRUCTION is
  50. require
  51. a_instruction /= Void
  52. when_error /= Void
  53. do
  54. Result ::= partial_parse(a_instruction, once "Instruction", when_error)
  55. end
  56. build_types (root_type: LIBERTY_ACTUAL_TYPE; root_feature_name: LIBERTY_FEATURE_NAME; target_type: LIBERTY_ACTUAL_TYPE) is
  57. require
  58. target_type /= Void
  59. local
  60. flame: LIBERTY_FLAME
  61. incubator: like types_incubator
  62. do
  63. if not target_type.is_built then
  64. create incubator.with_capacity(1024, 0) --|TODO optim: replace by an attribute
  65. from
  66. until
  67. types_incubator.is_empty or else target_type.is_built
  68. loop
  69. flame := torch.flame
  70. build_to_incubator(incubator, target_type)
  71. mark_reachable_code(root_type, root_feature_name)
  72. resolve_delayed_types
  73. if types_incubator.is_empty then
  74. incubator := check_flame_and_swap_incubator(flame, incubator)
  75. end
  76. end
  77. if not incubator.is_empty then
  78. -- don't lose work
  79. types_incubator.append_traversable(incubator)
  80. end
  81. debug ("type.building")
  82. debug_types(types_incubator)
  83. if target_type.is_built then
  84. log.trace.put_string(once "Type is ready: ")
  85. log.trace.put_line(target_type.full_name)
  86. else
  87. log.trace.put_string(once "Type is NOT READY: ")
  88. log.trace.put_line(target_type.full_name)
  89. breakpoint
  90. end
  91. end
  92. end
  93. ensure
  94. target_type.is_built
  95. end
  96. feature {ANY} -- Kernel types
  97. type_any: LIBERTY_ACTUAL_TYPE is
  98. require
  99. not errors.has_error
  100. once
  101. Result := kernel_type("ANY".intern, visit_type_any)
  102. end
  103. type_arguments: LIBERTY_ACTUAL_TYPE is
  104. require
  105. not errors.has_error
  106. once
  107. Result := kernel_type("ARGUMENTS".intern, visit_type_arguments)
  108. end
  109. type_platform: LIBERTY_ACTUAL_TYPE is
  110. require
  111. not errors.has_error
  112. once
  113. Result := kernel_type("PLATFORM".intern, visit_type_platform)
  114. end
  115. type_pointer: LIBERTY_ACTUAL_TYPE is
  116. require
  117. not errors.has_error
  118. once
  119. Result := kernel_type("POINTER".intern, visit_type_pointer)
  120. end
  121. type_integer_64: LIBERTY_ACTUAL_TYPE is
  122. require
  123. not errors.has_error
  124. once
  125. Result := kernel_type("INTEGER_64".intern, visit_type_integer_64)
  126. Result.add_converter(type_real_128, convert_integer_64_real_128)
  127. Result.add_converter(type_real_80, convert_integer_64_real_80)
  128. Result.set_may_promote_current
  129. end
  130. type_integer, type_integer_32: LIBERTY_ACTUAL_TYPE is
  131. require
  132. not errors.has_error
  133. once
  134. Result := kernel_type("INTEGER_32".intern, visit_type_integer_32)
  135. Result.add_converter(type_integer_64, convert_integer_32_64)
  136. Result.add_converter(type_real_128, convert_integer_32_real_128)
  137. Result.add_converter(type_real_80, convert_integer_32_real_80)
  138. Result.add_converter(type_real_64, convert_integer_32_real_64)
  139. Result.set_may_promote_current
  140. end
  141. type_integer_16: LIBERTY_ACTUAL_TYPE is
  142. require
  143. not errors.has_error
  144. once
  145. Result := kernel_type("INTEGER_16".intern, visit_type_integer_16)
  146. Result.add_converter(type_integer_32, convert_integer_16_32)
  147. Result.add_converter(type_integer_64, convert_integer_16_64)
  148. Result.add_converter(type_real_128, convert_integer_16_real_128)
  149. Result.add_converter(type_real_80, convert_integer_16_real_80)
  150. Result.add_converter(type_real_64, convert_integer_16_real_64)
  151. Result.add_converter(type_real_32, convert_integer_16_real_32)
  152. Result.set_may_promote_current
  153. end
  154. type_integer_8: LIBERTY_ACTUAL_TYPE is
  155. require
  156. not errors.has_error
  157. once
  158. Result := kernel_type("INTEGER_8".intern, visit_type_integer_8)
  159. Result.add_converter(type_integer_16, convert_integer_8_16)
  160. Result.add_converter(type_integer_32, convert_integer_8_32)
  161. Result.add_converter(type_integer_64, convert_integer_8_64)
  162. Result.add_converter(type_real_128, convert_integer_8_real_128)
  163. Result.add_converter(type_real_80, convert_integer_8_real_80)
  164. Result.add_converter(type_real_64, convert_integer_8_real_64)
  165. Result.add_converter(type_real_32, convert_integer_8_real_32)
  166. Result.set_may_promote_current
  167. end
  168. type_real_128: LIBERTY_ACTUAL_TYPE is
  169. require
  170. not errors.has_error
  171. once
  172. Result := kernel_type("REAL_128".intern, visit_type_real_128)
  173. Result.set_may_promote_current
  174. end
  175. type_real_80: LIBERTY_ACTUAL_TYPE is
  176. require
  177. not errors.has_error
  178. once
  179. Result := kernel_type("REAL_80".intern, visit_type_real_80)
  180. Result.add_converter(type_real_128, convert_real_80_128)
  181. Result.set_may_promote_current
  182. end
  183. type_real, type_real_64: LIBERTY_ACTUAL_TYPE is
  184. require
  185. not errors.has_error
  186. once
  187. Result := kernel_type("REAL_64".intern, visit_type_real_64)
  188. Result.add_converter(type_real_80, convert_real_64_80)
  189. Result.add_converter(type_real_128, convert_real_64_128)
  190. Result.set_may_promote_current
  191. end
  192. type_real_32: LIBERTY_ACTUAL_TYPE is
  193. require
  194. not errors.has_error
  195. once
  196. Result := kernel_type("REAL_32".intern, visit_type_real_32)
  197. Result.add_converter(type_real_64, convert_real_32_64)
  198. Result.add_converter(type_real_80, convert_real_32_80)
  199. Result.add_converter(type_real_128, convert_real_32_128)
  200. Result.set_may_promote_current
  201. end
  202. type_character: LIBERTY_ACTUAL_TYPE is
  203. require
  204. not errors.has_error
  205. once
  206. Result := kernel_type("CHARACTER".intern, visit_type_character)
  207. end
  208. type_string: LIBERTY_ACTUAL_TYPE is
  209. require
  210. not errors.has_error
  211. once
  212. Result := kernel_type("STRING".intern, visit_type_string)
  213. end
  214. type_boolean: LIBERTY_ACTUAL_TYPE is
  215. require
  216. not errors.has_error
  217. once
  218. Result := kernel_type("BOOLEAN".intern, visit_type_boolean)
  219. end
  220. type_native_array (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  221. require
  222. not errors.has_error
  223. local
  224. td: LIBERTY_TYPE_DESCRIPTOR
  225. ast: LIBERTY_AST_ONE_CLASS
  226. do
  227. create td.make(native_array_class_descriptor, effective_generics)
  228. Result := types.reference_at(td)
  229. if Result = Void then
  230. ast := parse_class(td.cluster, td.name, Void)
  231. create Result.make(td, standard_generics_checker, ast, visit_type_native_array)
  232. start_to_build_type(Result)
  233. end
  234. ensure
  235. Result /= Void
  236. end
  237. type_tuple (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  238. require
  239. effective_generics /= Void
  240. not errors.has_error
  241. local
  242. td: LIBERTY_TYPE_DESCRIPTOR
  243. tuple_ast: LIBERTY_AST_CLASSES
  244. ast: LIBERTY_AST_ONE_CLASS
  245. tuple_count: INTEGER
  246. do
  247. tuple_count := effective_generics.count
  248. create td.make(tuple_class_descriptor, effective_generics)
  249. Result := types.reference_at(td)
  250. if Result = Void then
  251. tuple_ast := parse_tuple_classes(Void)
  252. check tuple_ast.classes.lower = 0 end
  253. if tuple_count > tuple_ast.classes.upper then
  254. errors.add_position(position)
  255. errors.set(level_fatal_error, "TUPLE does not support more than " + tuple_ast.classes.upper.out
  256. + " generic parameters.%NYou might want a named class with named attributes instead.")
  257. end
  258. ast ::= tuple_ast.classes.item(tuple_count)
  259. create Result.make(td, tuple_generics_checker, ast, visit_type_tuple)
  260. start_to_build_type(Result)
  261. end
  262. ensure
  263. Result /= Void
  264. end
  265. type_routine (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  266. require
  267. effective_generics /= Void
  268. do
  269. Result := agent_type(routine_class_descriptor, {FAST_ARRAY[LIBERTY_TYPE] << type_tuple(effective_generics, position) >> }, position, visit_type_routine)
  270. end
  271. type_procedure (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  272. require
  273. effective_generics /= Void
  274. do
  275. Result := agent_type(procedure_class_descriptor, {FAST_ARRAY[LIBERTY_TYPE] << type_tuple(effective_generics, position) >> }, position, visit_type_procedure)
  276. end
  277. type_function (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; result_type: LIBERTY_TYPE; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  278. require
  279. effective_generics /= Void
  280. result_type /= Void
  281. do
  282. Result := agent_type(function_class_descriptor, {FAST_ARRAY[LIBERTY_TYPE] << type_tuple(effective_generics, position), result_type >> }, position, visit_type_function)
  283. end
  284. type_predicate (effective_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION): LIBERTY_ACTUAL_TYPE is
  285. require
  286. effective_generics /= Void
  287. do
  288. Result := agent_type(predicate_class_descriptor, {FAST_ARRAY[LIBERTY_TYPE] << type_tuple(effective_generics, position) >> }, position, visit_type_predicate)
  289. end
  290. feature {} -- Partial parsing of command-line buffer (for the debugger and REPL)
  291. partial_parse (a_entry, a_root_atom_name: STRING; when_error: PROCEDURE[TUPLE[PARSE_ERROR]]): LIBERTY_AST_NON_TERMINAL_NODE is
  292. require
  293. a_entry /= Void
  294. when_error /= Void
  295. local
  296. evaled: BOOLEAN
  297. do
  298. parser_buffer.initialize_with(a_entry)
  299. eiffel.reset
  300. evaled := parser.eval(parser_buffer, eiffel.table, a_root_atom_name)
  301. if evaled then
  302. if parser.error /= Void then
  303. when_error.call([parser.error])
  304. else
  305. Result ::= eiffel.root_node
  306. end
  307. end
  308. end
  309. feature {}
  310. reachable_counter: COUNTER is
  311. once
  312. create Result
  313. end
  314. mark_reachable_code (root_type: LIBERTY_ACTUAL_TYPE; root_feature_name: LIBERTY_FEATURE_NAME) is
  315. local
  316. root_feature: LIBERTY_FEATURE_DEFINITION
  317. do
  318. reachable_counter.increment
  319. root_type.set_reachable(reachable_counter.value)
  320. if root_type.has_loaded_features then
  321. if not root_type.has_feature(root_feature_name) then
  322. errors.set(level_fatal_error,
  323. "Am I blind or what? I cannot find any method '" + root_feature_name.name
  324. + "' feature in the type " + root_type.full_name + "!")
  325. die_with_code(1)
  326. end
  327. root_feature := root_type.feature_definition(root_feature_name)
  328. reachable_counter.increment
  329. debug ("mark.reachable")
  330. log.trace.put_string(once " +++ Marking reachable code (")
  331. log.trace.put_integer(reachable_counter.value)
  332. log.trace.put_line(once ")...")
  333. end
  334. root_feature.set_reachable(reachable_counter.value)
  335. debug ("mark.reachable")
  336. log.trace.put_line(once " Reachable code marked.")
  337. end
  338. end
  339. end
  340. resolve_delayed_types is
  341. local
  342. delayed_types: COLLECTION[LIBERTY_DELAYED_TYPE]
  343. delayed_type: LIBERTY_DELAYED_TYPE
  344. i, n: INTEGER; more: BOOLEAN
  345. do
  346. delayed_types := type_lookup.resolver.delayed_types
  347. from
  348. more := True
  349. until
  350. not more or else delayed_types.is_empty
  351. loop
  352. more := False
  353. from
  354. n := delayed_types.count
  355. until
  356. n = 0
  357. loop
  358. delayed_type := delayed_types.first
  359. delayed_types.remove_first
  360. check
  361. not delayed_type.is_known
  362. end
  363. if delayed_type.can_resolve then
  364. delayed_type.resolve
  365. debug ("type.resolution")
  366. log.trace.put_string(once " ===> resolved ")
  367. log.trace.put_line(delayed_type.out)
  368. end
  369. more := True
  370. else
  371. delayed_types.add_last(delayed_type)
  372. end
  373. n := n - 1
  374. end
  375. end
  376. debug ("type.resolution")
  377. log.trace.put_line(once "======================================================================")
  378. from
  379. i := delayed_types.lower
  380. until
  381. i > delayed_types.upper
  382. loop
  383. log.trace.put_line(delayed_types.item(i).out)
  384. i := i + 1
  385. end
  386. log.trace.put_string(once " === ")
  387. log.trace.put_integer(delayed_types.count)
  388. if delayed_types.count = 1 then
  389. log.trace.put_line(once " delayed type yet to be resolved.")
  390. else
  391. log.trace.put_line(once " delayed types yet to be resolved.")
  392. end
  393. end
  394. end
  395. build_to_incubator (incubator: like types_incubator; target_type: LIBERTY_ACTUAL_TYPE) is
  396. require
  397. not types_incubator.is_empty
  398. not target_type.is_built
  399. local
  400. type: LIBERTY_ACTUAL_TYPE
  401. do
  402. from
  403. until
  404. types_incubator.is_empty or else target_type.is_built
  405. loop
  406. target_type.build_more
  407. type := types_incubator.first
  408. types_incubator.remove_first
  409. if not type.is_built then
  410. type.build_more
  411. if not type.is_built then
  412. incubator.add_last(type)
  413. end
  414. end
  415. end
  416. end
  417. check_flame_and_swap_incubator (flame: LIBERTY_FLAME; incubator: like types_incubator): like types_incubator is
  418. require
  419. types_incubator.is_empty
  420. do
  421. if not torch.still_burns(flame) then
  422. clean_unreachable_types(incubator)
  423. if not incubator.is_empty then
  424. debug ("error")
  425. debug_types(incubator)
  426. end
  427. errors.set(level_system_error, once "It looks like I miss some data but the hell if I know what.")
  428. check
  429. dead: False
  430. end
  431. end
  432. end
  433. Result := types_incubator
  434. types_incubator := incubator
  435. debug
  436. log.trace.put_line(once "Swapped incubator")
  437. end
  438. ensure
  439. types_incubator = incubator
  440. Result = old types_incubator
  441. end
  442. clean_unreachable_types (incubator: like types_incubator) is
  443. local
  444. i: INTEGER
  445. do
  446. clean_unreachable_types_from_incubator(incubator)
  447. from
  448. i := types.lower
  449. until
  450. i > types.upper
  451. loop
  452. if not types.item(i).is_reachable then
  453. types.fast_remove(types.key(i))
  454. else
  455. i := i + 1
  456. end
  457. end
  458. end
  459. clean_unreachable_types_from_incubator (incubator: like types_incubator) is
  460. local
  461. i: INTEGER
  462. do
  463. from
  464. i := incubator.lower
  465. until
  466. i > incubator.upper
  467. loop
  468. if not incubator.item(i).is_reachable then
  469. debug
  470. log.trace.put_string(once "Removing ")
  471. log.trace.put_string(incubator.item(i).full_name)
  472. log.trace.put_line(once ": not reachable")
  473. end
  474. incubator.remove(i)
  475. else
  476. i := i + 1
  477. end
  478. end
  479. end
  480. feature {} -- debug
  481. debug_types (incubator: like types_incubator) is
  482. local
  483. i: INTEGER
  484. all_types: FAST_ARRAY[LIBERTY_ACTUAL_TYPE]
  485. c: COMPARATOR_COLLECTION_SORTER[LIBERTY_ACTUAL_TYPE]
  486. do
  487. from
  488. create all_types.with_capacity(types.count)
  489. c.set_comparator(agent debug_compare_type_names)
  490. i := types.lower
  491. until
  492. i > types.upper
  493. loop
  494. c.add(all_types, types.item(i))
  495. i := i + 1
  496. end
  497. check
  498. all_types.count = types.count
  499. end
  500. log.trace.put_line(once "--8<--------")
  501. from
  502. i := all_types.lower
  503. until
  504. i > all_types.upper
  505. loop
  506. log.trace.put_integer(i - all_types.lower + 1)
  507. log.trace.put_string(once ": ")
  508. all_types.item(i).debug_display(log.trace, False)
  509. i := i + 1
  510. end
  511. log.trace.put_line(once "-------->8--")
  512. if incubator.is_empty then
  513. log.trace.put_integer(all_types.count)
  514. log.trace.put_line(once " types (total), incubator is empty")
  515. else
  516. log.trace.put_integer(all_types.count)
  517. log.trace.put_string(once " types (total), including ")
  518. log.trace.put_integer(incubator.count)
  519. log.trace.put_line(once " types in incubator:")
  520. log.trace.put_line(once "--8<--------")
  521. from
  522. i := incubator.lower
  523. until
  524. i > incubator.upper
  525. loop
  526. log.trace.put_integer(i - incubator.lower + 1)
  527. log.trace.put_string(once ": ")
  528. incubator.item(i).debug_display(log.trace, False)
  529. i := i + 1
  530. end
  531. log.trace.put_line(once "-------->8--")
  532. end
  533. end
  534. debug_compare_type_names (t1, t2: LIBERTY_ACTUAL_TYPE): BOOLEAN is
  535. do
  536. Result := t1.full_name < t2.full_name
  537. end
  538. feature {}
  539. start_to_build_type (type: LIBERTY_ACTUAL_TYPE) is
  540. require
  541. not types.has(type.descriptor)
  542. do
  543. types.add(type, type.descriptor)
  544. type.start_build(Current)
  545. if not type.is_built then
  546. types_incubator.add_last(type)
  547. end
  548. torch.burn
  549. end
  550. native_array_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  551. local
  552. cluster: LIBERTY_CLUSTER
  553. once
  554. cluster := root.find("NATIVE_ARRAY".intern)
  555. create Result.make(cluster, "NATIVE_ARRAY".intern, Void)
  556. end
  557. tuple_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  558. local
  559. cluster: LIBERTY_CLUSTER
  560. once
  561. cluster := root.find("TUPLE".intern)
  562. create Result.make(cluster, "TUPLE".intern, Void)
  563. end
  564. routine_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  565. local
  566. cluster: LIBERTY_CLUSTER
  567. once
  568. cluster := root.find("ROUTINE".intern)
  569. create Result.make(cluster, "ROUTINE".intern, Void)
  570. end
  571. procedure_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  572. local
  573. cluster: LIBERTY_CLUSTER
  574. once
  575. cluster := root.find("PROCEDURE".intern)
  576. create Result.make(cluster, "PROCEDURE".intern, Void)
  577. end
  578. function_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  579. local
  580. cluster: LIBERTY_CLUSTER
  581. once
  582. cluster := root.find("FUNCTION".intern)
  583. create Result.make(cluster, "FUNCTION".intern, Void)
  584. end
  585. predicate_class_descriptor: LIBERTY_CLASS_DESCRIPTOR is
  586. local
  587. cluster: LIBERTY_CLUSTER
  588. once
  589. cluster := root.find("PREDICATE".intern)
  590. create Result.make(cluster, "PREDICATE".intern, Void)
  591. end
  592. kernel_type (class_name: FIXED_STRING; visit: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]]): LIBERTY_ACTUAL_TYPE is
  593. -- Called only once per kernel type
  594. require
  595. not errors.has_error
  596. local
  597. cd: LIBERTY_CLASS_DESCRIPTOR; td: LIBERTY_TYPE_DESCRIPTOR
  598. ast: LIBERTY_AST_ONE_CLASS
  599. cluster: LIBERTY_CLUSTER
  600. do
  601. cluster := root.find(class_name)
  602. if cluster = Void then
  603. errors.set(level_fatal_error, "What's that installation of yours? I cannot even find the kernel class " + class_name + "!")
  604. end
  605. create cd.make(cluster, class_name.intern, Void)
  606. create td.make(cd, no_parameters)
  607. Result := types.reference_at(td)
  608. if Result = Void then
  609. ast := parse_class(cluster, class_name, Void)
  610. create Result.make(td, standard_generics_checker, ast, visit)
  611. start_to_build_type(Result)
  612. end
  613. ensure
  614. Result /= Void
  615. end
  616. agent_type (class_descriptor: LIBERTY_CLASS_DESCRIPTOR; agent_generics: TRAVERSABLE[LIBERTY_TYPE]; position: LIBERTY_POSITION;
  617. visit: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]]): LIBERTY_ACTUAL_TYPE is
  618. require
  619. class_descriptor /= Void
  620. agent_generics /= Void
  621. local
  622. td: LIBERTY_TYPE_DESCRIPTOR
  623. ast: LIBERTY_AST_ONE_CLASS
  624. do
  625. create td.make(class_descriptor, agent_generics)
  626. Result := types.reference_at(td)
  627. if Result = Void then
  628. ast := parse_class(td.cluster, td.name, position)
  629. create Result.make(td, agent_generics_checker, ast, visit)
  630. start_to_build_type(Result)
  631. end
  632. end
  633. feature {LIBERTY_TYPE_RESOLVER}
  634. get_type_from_descriptor (descriptor: LIBERTY_TYPE_DESCRIPTOR): LIBERTY_ACTUAL_TYPE is
  635. require
  636. not errors.has_error
  637. do
  638. Result := do_get_type_from_descriptor(descriptor)
  639. ensure
  640. Result.cluster.is_equal(descriptor.cluster)
  641. Result.name.is_equal(descriptor.name)
  642. same_parameters(Result.parameters, descriptor.parameters)
  643. end
  644. get_type_from_type_definition (type_definition: LIBERTY_AST_TYPE_DEFINITION; cluster: LIBERTY_CLUSTER): LIBERTY_ACTUAL_TYPE is
  645. require
  646. not type_definition.is_anchor
  647. not errors.has_error
  648. local
  649. class_name: STRING
  650. parameters: TRAVERSABLE[LIBERTY_TYPE]
  651. do
  652. class_name := type_definition.type_name.image.image
  653. inspect
  654. class_name
  655. when "INTEGER" then
  656. Result := type_integer
  657. when "INTEGER_64" then
  658. Result := type_integer_64
  659. when "INTEGER_32" then
  660. Result := type_integer_32
  661. when "INTEGER_16" then
  662. Result := type_integer_16
  663. when "INTEGER_8" then
  664. Result := type_integer_8
  665. when "ANY" then
  666. Result := type_any
  667. when "ARGUMENTS" then
  668. Result := type_arguments
  669. when "PLATFORM" then
  670. Result := type_platform
  671. when "REAL" then
  672. Result := type_real
  673. when "REAL_32" then
  674. Result := type_real_32
  675. when "REAL_64" then
  676. Result := type_real_64
  677. when "REAL_80" then
  678. Result := type_real_80
  679. when "REAL_128" then
  680. Result := type_real_128
  681. when "POINTER" then
  682. Result := type_pointer
  683. when "CHARACTER" then
  684. Result := type_character
  685. when "STRING" then
  686. Result := type_string
  687. when "BOOLEAN" then
  688. Result := type_boolean
  689. when "NATIVE_ARRAY" then
  690. parameters := get_parameters(type_definition.type_parameters)
  691. Result := type_native_array(parameters, type_lookup.resolver.position(type_definition))
  692. when "TUPLE" then
  693. parameters := get_parameters(type_definition.type_parameters)
  694. Result := type_tuple(parameters, type_lookup.resolver.position(type_definition))
  695. when "ROUTINE" then
  696. parameters := get_parameters(type_definition.type_parameters)
  697. check
  698. parameters.count = 1
  699. parameters.first.is_known
  700. end
  701. Result := type_routine(parameters.first.known_type.parameters, type_lookup.resolver.position(type_definition))
  702. when "PROCEDURE" then
  703. parameters := get_parameters(type_definition.type_parameters)
  704. check
  705. parameters.count = 1
  706. parameters.first.is_known
  707. end
  708. Result := type_procedure(parameters.first.known_type.parameters, type_lookup.resolver.position(type_definition))
  709. when "PREDICATE" then
  710. parameters := get_parameters(type_definition.type_parameters)
  711. check
  712. parameters.count = 1
  713. parameters.first.is_known
  714. end
  715. Result := type_predicate(parameters.first.known_type.parameters, type_lookup.resolver.position(type_definition))
  716. when "FUNCTION" then
  717. parameters := get_parameters(type_definition.type_parameters)
  718. check
  719. parameters.count = 2
  720. parameters.first.is_known
  721. end
  722. Result := type_function(parameters.first.known_type.parameters, parameters.last, type_lookup.resolver.position(type_definition))
  723. else
  724. parameters := get_parameters(type_definition.type_parameters)
  725. Result := do_get_type(cluster, type_lookup.resolver.position(type_definition), class_name.intern, parameters)
  726. end
  727. end
  728. feature {}
  729. do_get_type (cluster: LIBERTY_CLUSTER; position: LIBERTY_POSITION; class_name: FIXED_STRING; effective_type_parameters: TRAVERSABLE[LIBERTY_TYPE]): LIBERTY_ACTUAL_TYPE is
  730. require
  731. position /= Void
  732. local
  733. descriptor: LIBERTY_TYPE_DESCRIPTOR
  734. c: like cluster
  735. do
  736. if cluster = Void then
  737. c := root.find(class_name)
  738. else
  739. c := cluster.find(class_name)
  740. end
  741. if c = Void then
  742. errors.add_position(position)
  743. errors.set(level_fatal_error, "Looks like some configuration is missing, or you mistyped something. Anyway I cannot find the class named " + class_name + ".")
  744. end
  745. create descriptor.make(create {LIBERTY_CLASS_DESCRIPTOR}.make(c, class_name.intern, position), effective_type_parameters)
  746. Result := do_get_type_from_descriptor(descriptor)
  747. ensure
  748. Result.name.is_equal(class_name)
  749. same_parameters(Result.parameters, effective_type_parameters)
  750. end
  751. do_get_type_from_descriptor (descriptor: LIBERTY_TYPE_DESCRIPTOR): LIBERTY_ACTUAL_TYPE is
  752. require
  753. not errors.has_error
  754. local
  755. ast: LIBERTY_AST_ONE_CLASS
  756. do
  757. Result := types.reference_at(descriptor)
  758. if Result = Void then
  759. ast := parse_class(descriptor.cluster, descriptor.name, descriptor.position)
  760. create Result.make(descriptor, standard_generics_checker, ast, visit_user_type)
  761. start_to_build_type(Result)
  762. end
  763. ensure
  764. Result.cluster.is_equal(descriptor.cluster)
  765. Result.name.is_equal(descriptor.name)
  766. same_parameters(Result.parameters, descriptor.parameters)
  767. end
  768. feature {}
  769. same_parameters (params1, params2: TRAVERSABLE[LIBERTY_TYPE]): BOOLEAN is
  770. -- Simply doing "params1.is_equal(params2)" does not always work because one or both may actually be
  771. -- a TRAVERSABLE[LIBERTY_ACTUAL_TYPE] - and is_equal has a postcondition that requires the same
  772. -- actual runtime type for both the target and the parameter.
  773. require
  774. params1 /= Void
  775. params2 /= Void
  776. local
  777. i: INTEGER
  778. do
  779. if params1.count = params2.count then
  780. check
  781. params1.lower = params2.lower
  782. end
  783. from
  784. Result := True
  785. i := params1.lower
  786. until
  787. not Result or else i > params1.upper
  788. loop
  789. if params1.item(i) /= params2.item(i) then
  790. Result := params1.item(i).is_known and then params2.item(i).is_known
  791. and then params1.item(i).known_type = params2.item(i).known_type
  792. end
  793. i := i + 1
  794. end
  795. end
  796. end
  797. feature {} -- Type parameters fetching
  798. get_parameters (type_parameters: LIBERTY_AST_EFFECTIVE_TYPE_PARAMETERS): COLLECTION[LIBERTY_TYPE] is
  799. local
  800. type_parameter: LIBERTY_AST_EFFECTIVE_TYPE_PARAMETER
  801. type_definition: LIBERTY_AST_TYPE_DEFINITION
  802. type: LIBERTY_TYPE
  803. i: INTEGER
  804. do
  805. if type_parameters.list_is_empty then
  806. Result := no_parameters
  807. else
  808. create {FAST_ARRAY[LIBERTY_TYPE]} Result.with_capacity(type_parameters.list_count)
  809. from
  810. i := type_parameters.list_lower
  811. until
  812. i > type_parameters.list_upper
  813. loop
  814. type_parameter := type_parameters.list_item(i)
  815. type_definition := type_parameter.type_definition
  816. type := type_lookup.resolver.type(type_definition)
  817. Result.add_last(type)
  818. i := i + 1
  819. end
  820. end
  821. end
  822. no_parameters: COLLECTION[LIBERTY_TYPE] is
  823. once
  824. create {FAST_ARRAY[LIBERTY_TYPE]} Result.with_capacity(0)
  825. end
  826. feature {LIBERTY_TYPE_RESOLVER_IN_TYPE}
  827. parse_class (cluster: LIBERTY_CLUSTER; class_name: FIXED_STRING; pos: LIBERTY_POSITION): LIBERTY_AST_ONE_CLASS is
  828. require
  829. cluster /= Void
  830. class_name /= Void
  831. local
  832. code: STRING; class_descriptor: LIBERTY_CLASS_DESCRIPTOR
  833. ast: LIBERTY_AST_CLASS; actual_cluster: LIBERTY_CLUSTER
  834. evaled: BOOLEAN
  835. do
  836. actual_cluster := cluster.find(class_name)
  837. if actual_cluster = Void then
  838. errors.set(level_fatal_error,
  839. "Looks like some configuration is missing, or you mistyped something. Anyway I cannot find the class named " + class_name + ".")
  840. check
  841. dead: False
  842. end
  843. end
  844. create class_descriptor.make(actual_cluster, class_name, pos)
  845. Result := classes.reference_at(class_descriptor)
  846. if Result = Void then
  847. log.info.put_string(once "Parsing ")
  848. log.info.put_string(cluster.name)
  849. log.info.put_character('.')
  850. log.info.put_line(class_name)
  851. code := once ""
  852. code.clear_count
  853. read_file_in(class_descriptor, code)
  854. parser_buffer.initialize_with(code)
  855. eiffel.reset
  856. evaled := parser.eval(parser_buffer, eiffel.table, once "Class")
  857. if not evaled then
  858. errors.add_position(errors.syntax_position(code.upper, code, class_descriptor.file.intern))
  859. errors.set(level_fatal_error,
  860. "I'm afraid you need to use a bit more those fingers of yours. The code of the class " + class_name
  861. +" is incomplete.")
  862. errors.emit
  863. check
  864. dead: False
  865. end
  866. end
  867. if parser.error /= Void then
  868. errors.emit_syntax_error(parser.error, code, class_descriptor.file.intern)
  869. die_with_code(1)
  870. end
  871. ast ::= eiffel.root_node
  872. Result := ast.one_class
  873. classes.put(Result, class_descriptor)
  874. log.trace.put_string(cluster.name)
  875. log.trace.put_character('.')
  876. log.trace.put_string(class_name)
  877. log.trace.put_line(once " parsed.")
  878. end
  879. ensure
  880. Result /= Void
  881. end
  882. feature {} -- AST building
  883. read_file_in (descriptor: LIBERTY_CLASS_DESCRIPTOR; code: STRING) is
  884. require
  885. descriptor /= Void
  886. code.is_empty
  887. local
  888. file: FIXED_STRING
  889. do
  890. file := descriptor.file
  891. parser_file.connect_to(file)
  892. if not parser_file.is_connected then
  893. std_error.put_string(" *** Could not read file " + file)
  894. die_with_code(1)
  895. end
  896. from
  897. parser_file.read_line
  898. until
  899. parser_file.end_of_input
  900. loop
  901. code.append(parser_file.last_string)
  902. code.extend('%N')
  903. parser_file.read_line
  904. end
  905. code.append(parser_file.last_string)
  906. parser_file.disconnect
  907. end
  908. parse_tuple_classes (pos: LIBERTY_POSITION): LIBERTY_AST_CLASSES is
  909. local
  910. code: STRING; class_descriptor: LIBERTY_CLASS_DESCRIPTOR
  911. tuple_cluster: LIBERTY_CLUSTER
  912. i: INTEGER; file: FIXED_STRING
  913. one_class: LIBERTY_AST_ONE_CLASS
  914. evaled: BOOLEAN
  915. once
  916. log.info.put_line(once "Parsing TUPLE")
  917. tuple_cluster := root.find("TUPLE".intern)
  918. if tuple_cluster = Void then
  919. errors.set(level_fatal_error, "What's that installation of yours? I cannot even find the kernel class TUPLE!")
  920. end
  921. create class_descriptor.make(tuple_cluster, "TUPLE".intern, pos)
  922. code := once ""
  923. code.clear_count
  924. read_file_in(class_descriptor, code)
  925. parser_buffer.initialize_with(code)
  926. eiffel.reset
  927. evaled := parser.eval(parser_buffer, eiffel.table, once "Classes")
  928. if not evaled then
  929. errors.add_position(errors.syntax_position(code.upper, code, class_descriptor.file.intern))
  930. errors.set(level_fatal_error,
  931. "The code of the class TUPLE is incomplete. Maybe you could try installing Liberty again?")
  932. errors.emit
  933. check
  934. dead: False
  935. end
  936. end
  937. if parser.error /= Void then
  938. errors.emit_syntax_error(parser.error, code, class_descriptor.file.intern)
  939. die_with_code(1)
  940. end
  941. Result ::= eiffel.root_node
  942. file := class_descriptor.file.intern
  943. from
  944. i := Result.classes.lower
  945. check i = 0 end
  946. until
  947. i > Result.classes.upper
  948. loop
  949. one_class ::= Result.classes.item(i)
  950. check_tuple_class(one_class, i, Result, file)
  951. i := i + 1
  952. end
  953. log.trace.put_line(once "TUPLE parsed.")
  954. ensure
  955. Result /= Void
  956. end
  957. check_tuple_class (a_tuple_class: LIBERTY_AST_ONE_CLASS; generics_count: INTEGER; ast: LIBERTY_AST_CLASSES; file: FIXED_STRING) is
  958. -- minimal integrity check
  959. local
  960. classname: STRING
  961. gencount: INTEGER
  962. do
  963. classname := a_tuple_class.class_header.class_name.image.image
  964. if not classname.is_equal(once "TUPLE") then
  965. errors.add_position(errors.semantics_position(a_tuple_class.class_header.class_name.image.index, ast, file))
  966. errors.set(level_fatal_error, "Invalid TUPLE class text: strangely enough it does not contain TUPLE. Maybe you could try installing Liberty again?")
  967. end
  968. gencount := a_tuple_class.class_header.type_parameters.list_count
  969. if gencount /= generics_count then
  970. errors.add_position(errors.semantics_position(a_tuple_class.class_header.class_name.image.index, ast, file))
  971. if generics_count = 1 then
  972. errors.set(level_fatal_error,
  973. "Invalid TUPLE class text: expected 1 generic parameter but got " + gencount.out
  974. + ". Maybe you could try installing Liberty again?")
  975. else
  976. errors.set(level_fatal_error,
  977. "Invalid TUPLE class text: expected " + generics_count.out + " generic parameters but got " + gencount.out
  978. + ". Maybe you could try installing Liberty again)?")
  979. end
  980. end
  981. ensure
  982. not errors.has_error
  983. end
  984. parser_file: TEXT_FILE_READ is
  985. once
  986. create Result.make
  987. end
  988. parser_buffer: MINI_PARSER_BUFFER is
  989. once
  990. create Result
  991. end
  992. parser: DESCENDING_PARSER is
  993. once
  994. create Result.make
  995. end
  996. eiffel: EIFFEL_GRAMMAR is
  997. once
  998. create Result.make(create {LIBERTY_NODE_FACTORY}.make)
  999. end
  1000. feature {}
  1001. default_type_capacity: INTEGER is 4096
  1002. make is
  1003. local
  1004. tr: LIBERTY_TYPE_RESOLVER_IN_UNIVERSE
  1005. do
  1006. type_lookup.set_universe(Current)
  1007. create root.make_root
  1008. create {HASHED_DICTIONARY[LIBERTY_AST_ONE_CLASS, LIBERTY_CLASS_DESCRIPTOR]} classes.with_capacity(default_type_capacity)
  1009. create {HASHED_DICTIONARY[LIBERTY_ACTUAL_TYPE, LIBERTY_TYPE_DESCRIPTOR]} types.with_capacity(default_type_capacity)
  1010. create types_incubator.with_capacity(default_type_capacity, 0)
  1011. create tr.make(Current)
  1012. type_lookup.push(tr)
  1013. end
  1014. root: LIBERTY_CLUSTER
  1015. classes: DICTIONARY[LIBERTY_AST_ONE_CLASS, LIBERTY_CLASS_DESCRIPTOR]
  1016. types: DICTIONARY[LIBERTY_ACTUAL_TYPE, LIBERTY_TYPE_DESCRIPTOR]
  1017. types_incubator: RING_ARRAY[LIBERTY_ACTUAL_TYPE]
  1018. errors: LIBERTY_ERRORS
  1019. torch: LIBERTY_ENLIGHTENING_THE_WORLD
  1020. type_lookup: LIBERTY_TYPE_LOOKUP
  1021. standard_generics_checker: LIBERTY_GENERICS_CONFORMANCE_CHECKER is
  1022. once
  1023. create {LIBERTY_STANDARD_GENERICS_CONFORMANCE_CHECKER} Result.make
  1024. end
  1025. tuple_generics_checker: LIBERTY_GENERICS_CONFORMANCE_CHECKER is
  1026. once
  1027. create {LIBERTY_TUPLE_CONFORMANCE_CHECKER} Result.make
  1028. end
  1029. agent_generics_checker: LIBERTY_GENERICS_CONFORMANCE_CHECKER is
  1030. once
  1031. create {LIBERTY_AGENT_CONFORMANCE_CHECKER} Result.make
  1032. end
  1033. feature {}
  1034. visit_type_any: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1035. once
  1036. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_any
  1037. end
  1038. visit_type_arguments: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1039. once
  1040. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_arguments
  1041. end
  1042. visit_type_platform: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1043. once
  1044. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_platform
  1045. end
  1046. visit_type_pointer: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1047. once
  1048. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_pointer
  1049. end
  1050. visit_type_integer_64: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1051. once
  1052. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_integer_64
  1053. end
  1054. visit_type_integer_32: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1055. once
  1056. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_integer_32
  1057. end
  1058. visit_type_integer_16: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1059. once
  1060. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_integer_16
  1061. end
  1062. visit_type_integer_8: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1063. once
  1064. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_integer_8
  1065. end
  1066. visit_type_real_64: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1067. once
  1068. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_real_64
  1069. end
  1070. visit_type_real_32: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1071. once
  1072. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_real_32
  1073. end
  1074. visit_type_real_80: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1075. once
  1076. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_real_80
  1077. end
  1078. visit_type_real_128: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1079. once
  1080. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_real_128
  1081. end
  1082. visit_type_character: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1083. once
  1084. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_character
  1085. end
  1086. visit_type_string: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1087. once
  1088. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_string
  1089. end
  1090. visit_type_boolean: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1091. once
  1092. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_boolean
  1093. end
  1094. visit_type_native_array: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1095. once
  1096. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_native_array
  1097. end
  1098. visit_type_tuple: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1099. once
  1100. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_tuple
  1101. end
  1102. visit_type_routine: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1103. once
  1104. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_routine
  1105. end
  1106. visit_type_procedure: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1107. once
  1108. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_procedure
  1109. end
  1110. visit_type_function: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1111. once
  1112. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_function
  1113. end
  1114. visit_type_predicate: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1115. once
  1116. Result := agent {LIBERTY_TYPE_VISITOR}.visit_type_predicate
  1117. end
  1118. visit_user_type: PROCEDURE[TUPLE[LIBERTY_TYPE_VISITOR, LIBERTY_ACTUAL_TYPE]] is
  1119. once
  1120. Result := agent {LIBERTY_TYPE_VISITOR}.visit_user_type
  1121. end
  1122. feature {}
  1123. convert_integer_8_16: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1124. once
  1125. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_16
  1126. end
  1127. convert_integer_8_32: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1128. once
  1129. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_32
  1130. end
  1131. convert_integer_8_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1132. once
  1133. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_64
  1134. end
  1135. convert_integer_16_32: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1136. once
  1137. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_32
  1138. end
  1139. convert_integer_16_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1140. once
  1141. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_64
  1142. end
  1143. convert_integer_32_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1144. once
  1145. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_32_64
  1146. end
  1147. convert_real_32_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1148. once
  1149. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_32_64
  1150. end
  1151. convert_real_32_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1152. once
  1153. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_32_80
  1154. end
  1155. convert_real_32_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1156. once
  1157. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_32_128
  1158. end
  1159. convert_real_64_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1160. once
  1161. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_64_80
  1162. end
  1163. convert_real_64_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1164. once
  1165. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_64_128
  1166. end
  1167. convert_real_80_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1168. once
  1169. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_real_80_128
  1170. end
  1171. convert_integer_64_real_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1172. once
  1173. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_64_real_128
  1174. end
  1175. convert_integer_64_real_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1176. once
  1177. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_64_real_80
  1178. end
  1179. convert_integer_32_real_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1180. once
  1181. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_32_real_128
  1182. end
  1183. convert_integer_32_real_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1184. once
  1185. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_32_real_80
  1186. end
  1187. convert_integer_32_real_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1188. once
  1189. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_32_real_64
  1190. end
  1191. convert_integer_16_real_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1192. once
  1193. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_real_128
  1194. end
  1195. convert_integer_16_real_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1196. once
  1197. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_real_80
  1198. end
  1199. convert_integer_16_real_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1200. once
  1201. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_real_64
  1202. end
  1203. convert_integer_16_real_32: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1204. once
  1205. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_16_real_32
  1206. end
  1207. convert_integer_8_real_128: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1208. once
  1209. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_real_128
  1210. end
  1211. convert_integer_8_real_80: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1212. once
  1213. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_real_80
  1214. end
  1215. convert_integer_8_real_64: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1216. once
  1217. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_real_64
  1218. end
  1219. convert_integer_8_real_32: PROCEDURE[TUPLE[LIBERTY_TYPE_CONVERTER]] is
  1220. once
  1221. Result := agent {LIBERTY_TYPE_CONVERTER}.convert_integer_8_real_32
  1222. end
  1223. invariant
  1224. types /= Void
  1225. classes /= Void
  1226. types_incubator /= Void
  1227. end