/src/tools/interpreter/liberty_interpreter_agent.e

http://github.com/tybor/Liberty · Specman e · 235 lines · 191 code · 24 blank · 20 comment · 6 complexity · 3504980637fa2cdbe674f687a3c04e66 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_AGENT
  16. inherit
  17. LIBERTY_INTERPRETER_OBJECT
  18. creation {LIBERTY_INTERPRETER_OBJECT_CREATOR}
  19. make
  20. feature {ANY}
  21. type: LIBERTY_ACTUAL_TYPE
  22. call: LIBERTY_CALL_EXPRESSION
  23. arguments: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]
  24. creation_target: LIBERTY_INTERPRETER_OBJECT
  25. hash_code: INTEGER is
  26. do
  27. Result := to_pointer.hash_code
  28. end
  29. is_equal (other: LIBERTY_INTERPRETER_OBJECT): BOOLEAN is
  30. do
  31. Result := other = Current
  32. end
  33. converted_to (target_type: LIBERTY_ACTUAL_TYPE): LIBERTY_INTERPRETER_OBJECT is
  34. do
  35. not_yet_implemented
  36. end
  37. feature {LIBERTY_INTERPRETER}
  38. set_call (a_target: like creation_target; a_call: like call; args: like arguments) is
  39. require
  40. call = Void
  41. a_call.is_agent_call
  42. args.count = a_call.actuals.count
  43. do
  44. if a_call.target = Void then
  45. creation_target := a_target
  46. else
  47. a_call.target.accept(interpreter.expressions)
  48. creation_target := interpreter.expressions.eval_as_target
  49. end
  50. call := a_call
  51. arguments := args
  52. ensure
  53. call = a_call
  54. arguments = args
  55. end
  56. feature {LIBERTY_INTERPRETER_EXTERNAL_TYPE_FUNCTION_BUILTINS}
  57. item_agent (parameters: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]; call_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  58. local
  59. target, real_target: LIBERTY_INTERPRETER_OBJECT
  60. args: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]
  61. do
  62. if call.target = Void then
  63. real_target := creation_target
  64. args := unpack_tuple_and_closed(parameters, call_position, False)
  65. else
  66. call.target.accept(interpreter.expressions)
  67. target := interpreter.expressions.eval_as_target
  68. real_target := unpack_target(target, parameters, call_position)
  69. args := unpack_tuple_and_closed(parameters, call_position, target.is_open)
  70. end
  71. Result := interpreter.item_feature(real_target, call.entity.feature_definition, args, call_position)
  72. end
  73. feature {LIBERTY_INTERPRETER_EXTERNAL_TYPE_ROUTINE_BUILTINS}
  74. call_agent (parameters: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]; call_position: LIBERTY_POSITION) is
  75. local
  76. lost_object: LIBERTY_INTERPRETER_OBJECT
  77. do
  78. -- Because the `call' feature of a routine may call a function; in that case the result is lost
  79. -- (temporary because of SmartEiffel)
  80. --
  81. -- ECMA instead sets the `last_result' attribute of ROUTINE; but how the hell is `last_result'
  82. -- typed?? (seems not to be specified)
  83. --
  84. lost_object := item_agent(parameters, call_position)
  85. end
  86. feature {}
  87. unpack_target (target: LIBERTY_INTERPRETER_OBJECT; parameters: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]; call_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  88. local
  89. tuple: LIBERTY_INTERPRETER_TUPLE
  90. do
  91. check
  92. parameters.count = 1
  93. tuple ?:= parameters.first
  94. end
  95. if target.is_open then
  96. tuple ::= parameters.first
  97. Result := tuple.first
  98. else
  99. Result := target
  100. end
  101. end
  102. unpack_tuple_and_closed (parameters: TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT]; call_position: LIBERTY_POSITION; target_is_open: BOOLEAN): TRAVERSABLE[LIBERTY_INTERPRETER_OBJECT] is
  103. local
  104. tuple: LIBERTY_INTERPRETER_TUPLE
  105. tuple_index: INTEGER
  106. arg: LIBERTY_INTERPRETER_OBJECT
  107. i: INTEGER
  108. args: FAST_ARRAY[LIBERTY_INTERPRETER_OBJECT]
  109. do
  110. check
  111. parameters.count = 1
  112. tuple ?:= parameters.first
  113. end
  114. tuple ::= parameters.first
  115. tuple_index := tuple.lower
  116. if target_is_open then
  117. tuple_index := tuple_index + 1
  118. end
  119. if arguments.count = 0 then
  120. Result := tuple
  121. else
  122. create args.with_capacity(arguments.count)
  123. Result := args
  124. from
  125. i := arguments.lower
  126. until
  127. i > arguments.upper
  128. loop
  129. arg := arguments.item(i)
  130. if arg.is_open then
  131. arg := tuple.item(tuple_index)
  132. check
  133. arg.type.is_conform_to(arguments.item(i).type)
  134. end
  135. tuple_index := tuple_index + 1
  136. end
  137. check
  138. not arg.is_open
  139. end
  140. args.add_last(arg)
  141. i := i + 1
  142. end
  143. end
  144. end
  145. feature {LIBERTY_INTERPRETER_EXTERNAL_TYPE_ANY_BUILTINS} -- Standard builtings
  146. builtin_is_equal (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION): BOOLEAN is
  147. do
  148. not_yet_implemented
  149. end
  150. builtin_standard_is_equal (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION): BOOLEAN is
  151. do
  152. not_yet_implemented
  153. end
  154. builtin_copy (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION) is
  155. do
  156. not_yet_implemented
  157. end
  158. builtin_twin (a_position: LIBERTY_POSITION): like Current is
  159. do
  160. not_yet_implemented
  161. end
  162. builtin_standard_copy (other: LIBERTY_INTERPRETER_OBJECT; a_position: LIBERTY_POSITION) is
  163. do
  164. not_yet_implemented
  165. end
  166. builtin_standard_twin (a_position: LIBERTY_POSITION): like Current is
  167. do
  168. not_yet_implemented
  169. end
  170. feature {LIBERTY_INTERPRETER_OBJECT}
  171. do_deep_twin (deep_twin_memory: DICTIONARY[LIBERTY_INTERPRETER_OBJECT, LIBERTY_INTERPRETER_OBJECT]; a_position: LIBERTY_POSITION): LIBERTY_INTERPRETER_OBJECT is
  172. do
  173. not_yet_implemented
  174. end
  175. do_deep_equal (object: LIBERTY_INTERPRETER_OBJECT; deep_equal_memory: SET[LIBERTY_INTERPRETER_OBJECT]; a_position: LIBERTY_POSITION): BOOLEAN is
  176. do
  177. not_yet_implemented
  178. end
  179. feature {LIBERTY_INTERPRETER_OBJECT_PRINTER, LIBERTY_INTERPRETER_FEATURE_CALL}
  180. show_stack (o: OUTPUT_STREAM; indent: INTEGER) is
  181. do
  182. o.put_string(once "agent {")
  183. o.put_string(call.entity.target_type.known_type.full_name)
  184. o.put_string(once "}.")
  185. o.put_line(call.entity.feature_name.full_name)
  186. end
  187. feature {}
  188. expanded_twin: like Current is
  189. do
  190. check False end
  191. end
  192. feature {}
  193. make (a_interpreter: like interpreter; a_type: like type; a_position: like position) is
  194. require
  195. a_interpreter /= Void
  196. a_type /= Void
  197. a_position /= Void
  198. do
  199. interpreter := a_interpreter
  200. type := a_type
  201. position := a_position
  202. ensure
  203. interpreter = a_interpreter
  204. type = a_type
  205. position = a_position
  206. end
  207. invariant
  208. call /= Void implies call.is_agent_call
  209. call /= Void implies arguments /= Void
  210. call /= Void implies creation_target /= Void
  211. end -- class LIBERTY_INTERPRETER_AGENT