/src/tools/interpreter/liberty_interpreter.e

http://github.com/tybor/Liberty · Specman e · 845 lines · 728 code · 103 blank · 14 comment · 15 complexity · 47480b2a228bcee89ba9357233bbe157 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_INTERPRETER
  16. insert
  17. LOGGING
  18. creation {LIBERTYI}
  19. make
  20. feature {LIBERTYI}
  21. run is
  22. local
  23. root_object: LIBERTY_INTERPRETER_OBJECT
  24. do
  25. log.info.put_string(once "Now running {")
  26. log.info.put_string(root_type.full_name)
  27. log.info.put_string(once "}.")
  28. log.info.put_line(root_feature_name.full_name)
  29. root_object := new_object(root_type, errors.unknown_position)
  30. call_feature(root_object, root_feature, root_feature_actuals, errors.unknown_position)
  31. log.info.put_line(once "Finished.")
  32. end
  33. feature {ANY}
  34. root_type: LIBERTY_ACTUAL_TYPE
  35. root_feature_name: LIBERTY_FEATURE_NAME
  36. root_feature: LIBERTY_FEATURE_DEFINITION
  37. frame_lower: INTEGER is
  38. do
  39. Result := call_stack.lower
  40. end
  41. frame_upper: INTEGER is
  42. do
  43. Result := call_stack.upper
  44. end
  45. current_frame: INTEGER
  46. break is
  47. local
  48. done: BOOLEAN
  49. do
  50. from
  51. until
  52. done
  53. loop
  54. readline.set_prompt(once "debug> ")
  55. readline.read_line
  56. done := debugger.break(readline.last_string)
  57. if readline.end_of_input then
  58. die_with_code(0)
  59. end
  60. end
  61. end
  62. show_current_frame (o: OUTPUT_STREAM) is
  63. do
  64. o.put_integer(current_frame + 1)
  65. o.put_character('%T')
  66. call_stack.item(current_frame).show_stack(o)
  67. end
  68. show_stack (o: OUTPUT_STREAM) is
  69. local
  70. i: INTEGER
  71. do
  72. check
  73. call_stack.lower = 0
  74. end
  75. o.put_line(once "===================== [Bottom of stack] =====================")
  76. from
  77. i := call_stack.lower
  78. until
  79. i > call_stack.upper
  80. loop
  81. if i > call_stack.lower then
  82. o.put_line(once "-------------------------------------------------------------")
  83. end
  84. if i = current_frame then
  85. o.put_line(once "Current frame")
  86. end
  87. o.put_integer(i + 1)
  88. o.put_character('%T')
  89. call_stack.item(i).show_stack(o)
  90. i := i + 1
  91. end
  92. o.put_line(once "====================== [Top of stack] =======================")
  93. end
  94. fatal_error (reason: ABSTRACT_STRING; position: LIBERTY_POSITION) is
  95. do
  96. if not gathering_old_values then
  97. std_error.put_new_line
  98. std_error.put_line(once "*** Fatal error!")
  99. std_error.put_new_line
  100. show_stack(std_error)
  101. std_error.put_new_line
  102. std_error.put_string(once "*** ")
  103. std_error.put_line(reason)
  104. if not position.is_unknown then
  105. std_error.put_string(once " ")
  106. position.show(std_error)
  107. end
  108. break
  109. die_with_code(1)
  110. elseif not evaluating_old_value_stack.is_empty then
  111. if old_fatal_error = Void then
  112. old_fatal_error := reason.intern
  113. old_fatal_position := position
  114. end
  115. end
  116. end
  117. gathering_old_values: BOOLEAN is
  118. do
  119. Result := gathering_old_values_counter > 0
  120. end
  121. ensure_built (a_type: LIBERTY_ACTUAL_TYPE) is
  122. do
  123. universe.build_types(root_type, root_feature_name, a_type)
  124. end
  125. instructions: LIBERTY_INTERPRETER_INSTRUCTIONS
  126. expressions_memory: LIBERTY_INTERPRETER_EXPRESSIONS
  127. assertions: LIBERTY_INTERPRETER_ASSERTION_CHECKER
  128. creator: LIBERTY_INTERPRETER_OBJECT_CREATOR
  129. array_creator: LIBERTY_INTERPRETER_NATIVE_ARRAY_CREATOR
  130. builtins: LIBERTY_INTERPRETER_EXTERNAL_BUILTINS
  131. plugins: LIBERTY_INTERPRETER_EXTERNAL_PLUGINS
  132. object_printer: LIBERTY_INTERPRETER_OBJECT_PRINTER
  133. object_converter: LIBERTY_INTERPRETER_OBJECT_CONVERTER
  134. postcondition_browser: LIBERTY_INTERPRETER_POSTCONDITION_BROWSER
  135. debugger: LIBERTY_INTERPRETER_DEBUGGER
  136. universe: LIBERTY_UNIVERSE
  137. expressions: LIBERTY_INTERPRETER_EXPRESSIONS is
  138. do
  139. if gathering_old_values then
  140. Result := postcondition_browser
  141. else
  142. Result := expressions_memory
  143. end
  144. ensure
  145. Result /= Void
  146. end
  147. call_feature (a_target: LIBERTY_INTERPRETER_OBJECT; feature_to_call: LIBERTY_FEATURE_DEFINITION; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION) is
  148. local
  149. call: LIBERTY_INTERPRETER_FEATURE_CALL
  150. do
  151. call := do_call(a_target, feature_to_call, actuals, a_position)
  152. check
  153. call.returned_object = Void
  154. end
  155. end
  156. item_feature (a_target: LIBERTY_INTERPRETER_OBJECT; feature_to_call: LIBERTY_FEATURE_DEFINITION; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  157. local
  158. call: LIBERTY_INTERPRETER_FEATURE_CALL
  159. do
  160. call := do_call(a_target, feature_to_call, actuals, a_position)
  161. Result := call.returned_object
  162. end
  163. call_precursor (a_precursor: LIBERTY_FEATURE; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION) is
  164. local
  165. dummy: LIBERTY_INTERPRETER_FEATURE_CALL
  166. do
  167. dummy := do_precursor(a_precursor, actuals, a_position)
  168. end
  169. item_precursor (a_precursor: LIBERTY_FEATURE; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  170. local
  171. call: LIBERTY_INTERPRETER_FEATURE_CALL
  172. do
  173. call := do_precursor(a_precursor, actuals, a_position)
  174. Result := call.returned_object
  175. end
  176. default_object (type: LIBERTY_ACTUAL_TYPE; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  177. do
  178. ensure_built(type)
  179. if type.is_expanded then
  180. Result := new_object(type, a_position)
  181. elseif type.is_separate then
  182. not_yet_implemented
  183. else
  184. Result := void_object(type, a_position)
  185. end
  186. end
  187. void_object (type: LIBERTY_KNOWN_TYPE; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  188. require
  189. not type.is_expanded
  190. do
  191. create {LIBERTY_INTERPRETER_VOID} Result.make(Current, type, a_position)
  192. end
  193. new_object (object_type: LIBERTY_ACTUAL_TYPE; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  194. do
  195. ensure_built(object_type)
  196. if object_type.is_deferred then
  197. fatal_error("Type " + object_type.full_name + " is deferred. Cannot create an instance of that class.", a_position)
  198. end
  199. debug ("interpreter.creation")
  200. std_output.put_string(once "Creating new object of type ")
  201. std_output.put_line(object_type.full_name)
  202. end
  203. Result := creator.new_object(object_type, a_position)
  204. end
  205. new_array (type: LIBERTY_ACTUAL_TYPE; capacity: INTEGER; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_NATIVE_ARRAY is
  206. do
  207. check
  208. type.parameters.count = 1
  209. end
  210. ensure_built(type)
  211. debug ("interpreter.creation")
  212. std_output.put_string(once "Creating new array of ")
  213. std_output.put_integer(capacity)
  214. std_output.put_character(' ')
  215. std_output.put_line(type.parameters.first.full_name)
  216. end
  217. Result := array_creator.new_array(type, capacity, a_position)
  218. end
  219. array_from_external (type: LIBERTY_ACTUAL_TYPE; capacity: INTEGER; elements: POINTER; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_NATIVE_ARRAY is
  220. do
  221. check
  222. type.parameters.count = 1
  223. end
  224. ensure_built(type)
  225. debug ("interpreter.creation")
  226. std_output.put_string(once "Creating new array of ")
  227. std_output.put_string(type.parameters.first.full_name)
  228. std_output.put_line(once " from external")
  229. end
  230. Result := array_creator.from_external(type, capacity, elements, a_position)
  231. end
  232. new_string (manifest: STRING; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  233. local
  234. the_new_string: LIBERTY_INTERPRETER_OBJECT_STRUCTURE
  235. new_string_capacity, new_string_count: LIBERTY_INTERPRETER_OBJECT
  236. new_string_storage: LIBERTY_INTERPRETER_NATIVE_ARRAY_TYPED[CHARACTER]
  237. do
  238. ensure_built(native_array_of_character)
  239. ensure_built(universe.type_string)
  240. debug ("interpreter.creation")
  241. std_output.put_string(once "Creating manifest string: ")
  242. std_output.put_line(manifest)
  243. end
  244. new_string_capacity := new_integer(manifest.capacity, a_position)
  245. new_string_count := new_integer(manifest.count, a_position)
  246. create new_string_storage.with_storage(Current, native_array_of_character, universe.type_character, manifest, manifest.capacity, a_position)
  247. the_new_string ::= creator.new_object(universe.type_string, a_position)
  248. the_new_string.put_attribute(capacity_name, new_string_capacity)
  249. the_new_string.put_attribute(count_name, new_string_count)
  250. the_new_string.put_attribute(storage_name, new_string_storage)
  251. Result := the_new_string
  252. end
  253. new_boolean (manifest: BOOLEAN; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_BOOLEAN is
  254. do
  255. ensure_built(universe.type_boolean)
  256. create Result.with_item(Current, universe.type_boolean, manifest, a_position)
  257. end
  258. new_integer_64 (manifest: INTEGER_64; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[INTEGER_64] is
  259. do
  260. ensure_built(universe.type_integer_64)
  261. create Result.with_item(Current, universe.type_integer_64, manifest, a_position)
  262. end
  263. new_integer_32 (manifest: INTEGER_32; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[INTEGER_64] is
  264. do
  265. ensure_built(universe.type_integer_32)
  266. create Result.with_item(Current, universe.type_integer_32, manifest, a_position)
  267. end
  268. new_integer (manifest: INTEGER; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[INTEGER_64] is
  269. do
  270. ensure_built(universe.type_integer)
  271. create Result.with_item(Current, universe.type_integer, manifest, a_position)
  272. end
  273. new_integer_16 (manifest: INTEGER_16; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[INTEGER_64] is
  274. do
  275. ensure_built(universe.type_integer_16)
  276. create Result.with_item(Current, universe.type_integer_16, manifest, a_position)
  277. end
  278. new_integer_8 (manifest: INTEGER_8; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[INTEGER_64] is
  279. do
  280. ensure_built(universe.type_integer_8)
  281. create Result.with_item(Current, universe.type_integer_8, manifest, a_position)
  282. end
  283. new_typed_integer (actual_type: LIBERTY_ACTUAL_TYPE; manifest: INTEGER_64; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  284. local
  285. i8: INTEGER_8; i16: INTEGER_16; i32: INTEGER_32
  286. manifest_type: LIBERTY_ACTUAL_TYPE
  287. do
  288. ensure_built(actual_type)
  289. if manifest.fit_integer_8 then
  290. i8 := manifest.to_integer_8
  291. manifest_type := universe.type_integer_8
  292. Result := new_integer_8(i8, a_position)
  293. elseif manifest.fit_integer_16 then
  294. i16 := manifest.to_integer_16
  295. manifest_type := universe.type_integer_16
  296. Result := new_integer_16(i16, a_position)
  297. elseif manifest.fit_integer_32 then
  298. i32 := manifest.to_integer_32
  299. manifest_type := universe.type_integer_32
  300. Result := new_integer_32(i32, a_position)
  301. else
  302. manifest_type := universe.type_integer_64
  303. Result := new_integer_64(manifest, a_position)
  304. end
  305. check
  306. not manifest_type.is_conform_to(actual_type)
  307. end
  308. if manifest_type.converts_to(actual_type) then
  309. Result := object_converter.convert_object(Result, actual_type)
  310. else
  311. fatal_error("Type " + manifest_type.full_name + " does not convert to " + actual_type.full_name, a_position)
  312. end
  313. ensure
  314. Result.result_type = actual_type
  315. end
  316. new_real (manifest: REAL; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[REAL_128] is
  317. do
  318. ensure_built(universe.type_real)
  319. create Result.with_item(Current, universe.type_real, manifest, a_position)
  320. end
  321. new_real_128 (manifest: REAL_128; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[REAL_128] is
  322. do
  323. ensure_built(universe.type_real_128)
  324. create Result.with_item(Current, universe.type_real_128, manifest, a_position)
  325. end
  326. new_real_80 (manifest: REAL_80; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[REAL_128] is
  327. do
  328. ensure_built(universe.type_real_80)
  329. create Result.with_item(Current, universe.type_real_80, manifest, a_position)
  330. end
  331. new_real_64 (manifest: REAL_64; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[REAL_128] is
  332. do
  333. ensure_built(universe.type_real_64)
  334. create Result.with_item(Current, universe.type_real_64, manifest, a_position)
  335. end
  336. new_real_32 (manifest: REAL_32; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[REAL_128] is
  337. do
  338. ensure_built(universe.type_real_32)
  339. create Result.with_item(Current, universe.type_real_32, manifest, a_position)
  340. end
  341. new_character (manifest: CHARACTER; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[CHARACTER] is
  342. do
  343. ensure_built(universe.type_character)
  344. create Result.with_item(Current, universe.type_character, manifest, a_position)
  345. end
  346. new_pointer (manifest: POINTER; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT_HASHABLE[POINTER] is
  347. do
  348. ensure_built(universe.type_pointer)
  349. create Result.with_item(Current, universe.type_pointer, manifest, a_position)
  350. end
  351. new_agent (a_agent: LIBERTY_AGENT): LIBERTY_INTERPRETER_AGENT is
  352. local
  353. agent_type: LIBERTY_ACTUAL_TYPE
  354. arguments: FAST_ARRAY[LIBERTY_INTERPRETER_OBJECT]
  355. actuals: TRAVERSABLE[LIBERTY_EXPRESSION]
  356. i: INTEGER
  357. do
  358. actuals := a_agent.call.actuals
  359. create arguments.with_capacity(actuals.count)
  360. from
  361. i := actuals.lower
  362. until
  363. i > actuals.upper
  364. loop
  365. actuals.item(i).accept(expressions)
  366. arguments.add_last(expressions.eval_as_right_value)
  367. i := i + 1
  368. end
  369. agent_type ::= a_agent.result_type.known_type
  370. ensure_built(agent_type)
  371. Result ::= new_object(agent_type, a_agent.position)
  372. Result.set_call(target, a_agent.call, arguments)
  373. end
  374. new_tuple (a_tuple: LIBERTY_TUPLE): LIBERTY_INTERPRETER_TUPLE is
  375. local
  376. tuple_type: LIBERTY_ACTUAL_TYPE
  377. do
  378. tuple_type ::= a_tuple.result_type.known_type
  379. ensure_built(tuple_type)
  380. Result ::= new_object(tuple_type, a_tuple.position)
  381. end
  382. old_value (a_expression: LIBERTY_EXPRESSION): LIBERTY_INTERPRETER_OBJECT is
  383. local
  384. actual_type: LIBERTY_ACTUAL_TYPE
  385. do
  386. if current_feature.has_old_value(a_expression) then
  387. Result := current_feature.old_value(a_expression)
  388. elseif gathering_old_values then
  389. actual_type ::= a_expression.result_type.known_type -- I dare anyone to write "old Void"
  390. Result := default_object(actual_type, a_expression.position)
  391. else
  392. fatal_error("Missing old value!!!", a_expression.position)
  393. end
  394. end
  395. feature {LIBERTY_INTERPRETER_DEBUGGER_VISITOR_IMPL}
  396. debug_step (number_of_steps: INTEGER) is
  397. require
  398. number_of_steps > 0
  399. do
  400. debugger.steps.after(number_of_steps)
  401. end
  402. debug_step_in is
  403. do
  404. debugger.steps.at_call_entry
  405. end
  406. debug_step_out is
  407. do
  408. debugger.steps.at_call_exit
  409. end
  410. set_current_frame (f: like current_frame) is
  411. require
  412. f.in_range(frame_lower, frame_upper)
  413. do
  414. current_frame := f
  415. ensure
  416. current_frame = f
  417. end
  418. feature {LIBERTY_INTERPRETER_POSTCONDITION_BROWSER}
  419. start_gathering_old_values is
  420. do
  421. gathering_old_values_counter := gathering_old_values_counter + 1
  422. ensure
  423. gathering_old_values
  424. gathering_old_values_counter = old gathering_old_values_counter + 1
  425. end
  426. finished_gathering_old_values is
  427. require
  428. gathering_old_values
  429. do
  430. gathering_old_values_counter := gathering_old_values_counter - 1
  431. ensure
  432. gathering_old_values_counter = old gathering_old_values_counter - 1
  433. end
  434. has_old_value (a_expression: LIBERTY_EXPRESSION): BOOLEAN is
  435. do
  436. Result := current_feature.has_old_value(a_expression)
  437. end
  438. start_evaluating_old_value is
  439. require
  440. gathering_old_values
  441. do
  442. evaluating_old_value_stack.add_last(current_feature)
  443. ensure
  444. gathering_old_values_counter = old gathering_old_values_counter
  445. evaluating_old_value
  446. end
  447. add_old_value (a_expression: LIBERTY_EXPRESSION; a_value: LIBERTY_INTERPRETER_OBJECT) is
  448. require
  449. gathering_old_values
  450. evaluating_old_value
  451. not has_old_value(a_expression)
  452. do
  453. check
  454. evaluating_old_value_stack.last = current_feature
  455. end
  456. current_feature.add_old_value(a_expression, a_value, old_fatal_error, old_fatal_position)
  457. evaluating_old_value_stack.remove_last
  458. if evaluating_old_value_stack.is_empty then
  459. old_fatal_error := Void
  460. end
  461. ensure
  462. gathering_old_values
  463. end
  464. evaluating_old_value: BOOLEAN is
  465. do
  466. Result := not evaluating_old_value_stack.is_empty
  467. end
  468. feature {}
  469. old_fatal_error: FIXED_STRING
  470. old_fatal_position: LIBERTY_POSITION
  471. gathering_old_values_counter: INTEGER
  472. evaluating_old_value_stack: COLLECTION[LIBERTY_INTERPRETER_FEATURE_CALL]
  473. feature {}
  474. do_call (a_target: LIBERTY_INTERPRETER_OBJECT; feature_to_call: LIBERTY_FEATURE_DEFINITION; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_FEATURE_CALL is
  475. do
  476. create Result.make(Current, a_target, feature_to_call, actuals, a_position)
  477. debug ("interpreter.call")
  478. std_output.put_new_line
  479. std_output.put_line(once "----------------------------------------------------------------------")
  480. std_output.put_integer(call_stack.count)
  481. std_output.put_string(once " - Calling ")
  482. Result.show_stack(std_output)
  483. end
  484. debugger.steps.step
  485. call_stack.add_last(Result)
  486. current_frame := frame_upper
  487. Result.call(debugger.steps)
  488. check
  489. current_feature = Result
  490. end
  491. call_stack.remove_last
  492. current_frame := frame_upper
  493. debug ("interpreter.call")
  494. std_output.put_integer(call_stack.count)
  495. std_output.put_string(once " - Returning from ")
  496. Result.show_stack(std_output)
  497. std_output.put_line(once "----------------------------------------------------------------------")
  498. std_output.put_new_line
  499. end
  500. end
  501. do_precursor (a_feature: LIBERTY_FEATURE; actuals: TRAVERSABLE[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_FEATURE_CALL is
  502. do
  503. create Result.make_precursor(Current, current_feature.target, a_feature, actuals, a_position)
  504. debug ("interpreter.call")
  505. std_output.put_new_line
  506. std_output.put_line(once "----------------------------------------------------------------------")
  507. std_output.put_integer(call_stack.count)
  508. std_output.put_string(once " - Calling precursor feature ")
  509. std_output.put_line(Result.name)
  510. end
  511. debugger.steps.step
  512. call_stack.add_last(Result)
  513. current_frame := frame_upper
  514. Result.call(debugger.steps)
  515. check
  516. current_feature = Result
  517. end
  518. call_stack.remove_last
  519. current_frame := frame_upper
  520. debug ("interpreter.call")
  521. std_output.put_integer(call_stack.count)
  522. std_output.put_string(once " - Returning from precursor feature ")
  523. std_output.put_line(Result.name)
  524. if Result.returned_static_type /= Void then
  525. std_output.put_string(once "Result = ")
  526. object_printer.print_object(std_output, Result.returned_object, 0)
  527. end
  528. std_output.put_line(once "----------------------------------------------------------------------")
  529. std_output.put_new_line
  530. end
  531. end
  532. feature {LIBERTY_INTERPRETER_FEATURE_CALL}
  533. set_evaluating_parameters (cf: like current_feature) is
  534. require
  535. cf /= Void
  536. not is_evaluating_parameters(cf)
  537. do
  538. check cf = current_feature end
  539. feature_evaluating_parameters.add_last(cf)
  540. call_stack.remove_last
  541. current_frame := frame_upper
  542. debug ("interpreter.internals")
  543. std_output.put_string(once " {{{ opening parameters evaluation of ")
  544. std_output.put_line(cf.name)
  545. end
  546. ensure
  547. is_evaluating_parameters(cf)
  548. end
  549. unset_evaluating_parameters (cf: like current_feature) is
  550. require
  551. cf /= Void
  552. is_evaluating_parameters(cf)
  553. do
  554. check cf = feature_evaluating_parameters.last end
  555. call_stack.add_last(cf)
  556. current_frame := frame_upper
  557. feature_evaluating_parameters.remove_last
  558. debug ("interpreter.internals")
  559. std_output.put_string(once " }}} closing parameters evaluation of ")
  560. std_output.put_line(cf.name)
  561. end
  562. ensure
  563. not is_evaluating_parameters(cf)
  564. end
  565. is_evaluating_parameters (cf: like current_feature): BOOLEAN is
  566. require
  567. cf /= Void
  568. do
  569. Result := not feature_evaluating_parameters.is_empty and then feature_evaluating_parameters.last = cf
  570. check
  571. Result = feature_evaluating_parameters.fast_has(cf)
  572. end
  573. end
  574. feature {}
  575. feature_evaluating_parameters: COLLECTION[LIBERTY_INTERPRETER_FEATURE_CALL]
  576. current_feature: LIBERTY_INTERPRETER_FEATURE_CALL is
  577. do
  578. Result := call_stack.last
  579. end
  580. debug_value (tag, name, op: ABSTRACT_STRING; value: LIBERTY_INTERPRETER_OBJECT) is
  581. do
  582. std_output.put_string(" **** {")
  583. std_output.put_string(current_feature.definition_type.full_name)
  584. std_output.put_string(once "}.")
  585. std_output.put_string(current_feature.name)
  586. std_output.put_string(once ": ")
  587. std_output.put_string(tag)
  588. std_output.put_string(name)
  589. std_output.put_string(op)
  590. object_printer.print_object(std_output, value, 2)
  591. end
  592. feature {LIBERTY_INTERPRETER_DEBUGGER, LIBERTY_INTERPRETER_EXPRESSIONS, LIBERTY_INTERPRETER_INSTRUCTIONS}
  593. target: LIBERTY_INTERPRETER_OBJECT is
  594. do
  595. Result := current_feature.target
  596. debug ("interpreter.internals")
  597. debug_value(once "Current", once "", once " is ", Result)
  598. end
  599. end
  600. local_value (name: FIXED_STRING): LIBERTY_INTERPRETER_OBJECT is
  601. do
  602. Result := current_feature.local_value(name)
  603. debug ("interpreter.internals")
  604. debug_value(once "Local ", name, once " is ", Result)
  605. end
  606. end
  607. returned_object: LIBERTY_INTERPRETER_OBJECT is
  608. do
  609. Result := current_feature.returned_object
  610. debug ("interpreter.internals")
  611. debug_value(once "Result", once "", once " is ", Result)
  612. end
  613. end
  614. writable_feature (name: LIBERTY_FEATURE_NAME): LIBERTY_INTERPRETER_OBJECT is
  615. do
  616. Result := current_feature.writable_feature(name)
  617. debug ("interpreter.internals")
  618. debug_value(once "Writable feature ", name.full_name, once " is ", Result)
  619. end
  620. end
  621. parameter (name: FIXED_STRING): LIBERTY_INTERPRETER_OBJECT is
  622. do
  623. Result := current_feature.parameter(name)
  624. debug ("interpreter.internals")
  625. debug_value(once "Parameter ", name, once " is ", Result)
  626. end
  627. end
  628. feature {LIBERTY_INTERPRETER_ASSIGNMENT}
  629. local_static_type (name: FIXED_STRING): LIBERTY_ACTUAL_TYPE is
  630. do
  631. Result := current_feature.local_static_type(name)
  632. end
  633. set_local_value (name: FIXED_STRING; value: LIBERTY_INTERPRETER_OBJECT) is
  634. do
  635. current_feature.set_local_value(name, value)
  636. debug ("interpreter.internals")
  637. debug_value(once "Local ", name, once " := ", value)
  638. end
  639. end
  640. returned_static_type: LIBERTY_ACTUAL_TYPE is
  641. do
  642. Result := current_feature.returned_static_type
  643. end
  644. set_returned_object (value: LIBERTY_INTERPRETER_OBJECT) is
  645. do
  646. current_feature.set_returned_object(value)
  647. debug ("interpreter.internals")
  648. debug_value(once "Result", once "", once " := ", value)
  649. end
  650. end
  651. writable_feature_static_type (name: LIBERTY_FEATURE_NAME): LIBERTY_ACTUAL_TYPE is
  652. do
  653. Result := current_feature.writable_feature_static_type(name)
  654. end
  655. set_writable_feature (name: LIBERTY_FEATURE_NAME; value: LIBERTY_INTERPRETER_OBJECT) is
  656. do
  657. current_feature.set_writable_feature(name, value)
  658. debug ("interpreter.internals")
  659. debug_value(once "Writable feature ", name.full_name, once " := ", value)
  660. end
  661. end
  662. feature {LIBERTY_INTERPRETER_ASSERTION_CHECKER}
  663. evaluate_feature_parameters is
  664. do
  665. current_feature.evaluate_parameters
  666. end
  667. feature {}
  668. make (a_universe: like universe; a_root_type: like root_type; a_root_feature_name: like root_feature_name) is
  669. require
  670. a_universe /= Void
  671. do
  672. universe := a_universe
  673. root_type := a_root_type
  674. root_feature_name := a_root_feature_name
  675. ensure_built(a_root_type)
  676. if not a_root_type.has_feature(a_root_feature_name) then
  677. std_error.put_string("Unknown feature ")
  678. std_error.put_string(a_root_feature_name.full_name)
  679. std_error.put_string(" in type ")
  680. std_error.put_line(a_root_type.full_name)
  681. die_with_code(1)
  682. end
  683. root_feature := a_root_type.feature_definition(a_root_feature_name)
  684. create instructions.make(Current)
  685. create expressions_memory.make(Current)
  686. create postcondition_browser.make(Current)
  687. create assertions.make(Current)
  688. create creator.make(Current)
  689. create array_creator.make(Current)
  690. create builtins.make(Current)
  691. create plugins.make(Current)
  692. create object_printer.make(Current)
  693. create object_converter.make(Current)
  694. create debugger.make(Current)
  695. create {FAST_ARRAY[LIBERTY_INTERPRETER_FEATURE_CALL]} call_stack.with_capacity(1024)
  696. create {FAST_ARRAY[LIBERTY_INTERPRETER_FEATURE_CALL]} feature_evaluating_parameters.with_capacity(16)
  697. create {FAST_ARRAY[LIBERTY_INTERPRETER_FEATURE_CALL]} evaluating_old_value_stack.with_capacity(2)
  698. native_array_of_character := universe.type_native_array({FAST_ARRAY[LIBERTY_ACTUAL_TYPE] << universe.type_character >> }, errors.unknown_position)
  699. ensure
  700. universe = a_universe
  701. root_type = a_root_type
  702. root_feature_name = a_root_feature_name
  703. root_feature = a_root_type.feature_definition(a_root_feature_name)
  704. end
  705. native_array_of_character: LIBERTY_ACTUAL_TYPE
  706. root_feature_actuals: COLLECTION[LIBERTY_EXPRESSION] is
  707. once
  708. create {FAST_ARRAY[LIBERTY_EXPRESSION]} Result.with_capacity(0)
  709. ensure
  710. Result.is_empty
  711. end
  712. call_stack: COLLECTION[LIBERTY_INTERPRETER_FEATURE_CALL]
  713. capacity_name: FIXED_STRING is
  714. once
  715. Result := "capacity".intern
  716. end
  717. count_name: FIXED_STRING is
  718. once
  719. Result := "count".intern
  720. end
  721. storage_name: FIXED_STRING is
  722. once
  723. Result := "storage".intern
  724. end
  725. readline: READLINE_INPUT_STREAM is
  726. once
  727. create Result.make
  728. end
  729. errors: LIBERTY_ERRORS
  730. invariant
  731. instructions /= Void
  732. expressions_memory /= Void
  733. assertions /= Void
  734. creator /= Void
  735. call_stack /= Void
  736. universe /= Void
  737. native_array_of_character /= Void
  738. feature_evaluating_parameters /= Void
  739. evaluating_old_value_stack /= Void
  740. postcondition_browser /= Void
  741. debugger /= Void
  742. end -- class LIBERTY_INTERPRETER