PageRenderTime 67ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/tools/semantics/code/builders/liberty_semantics_builder.e

http://github.com/tybor/Liberty
Specman e | 1436 lines | 1311 code | 83 blank | 42 comment | 91 complexity | 18b9e9facd4ae3fc6bfc333451a12224 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1, GPL-2.0
  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. deferred class LIBERTY_SEMANTICS_BUILDER
  16. insert
  17. LIBERTY_BUILDER_TOOLS
  18. LIBERTY_ARRAY_MANIFEST_CONSTANTS
  19. feature {ANY}
  20. instruction (inst: LIBERTY_AST_INSTRUCTION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSTRUCTION is
  21. require
  22. inst /= Void
  23. local_context /= Void
  24. local
  25. assignment_or_call: LIBERTY_AST_ASSIGNMENT_OR_CALL
  26. do
  27. inspect
  28. inst.instruction.name
  29. when "Assignment_Or_Call" then
  30. assignment_or_call ::= inst.instruction
  31. if assignment_or_call.is_assignment then
  32. Result := instruction_assignment(assignment_or_call, local_context)
  33. else
  34. Result := instruction_call(assignment_or_call, local_context)
  35. end
  36. when "If_Then_Else" then
  37. Result := instruction_ifthenelse(inst.instruction, local_context)
  38. when "Inspect" then
  39. Result := instruction_inspect(inst.instruction, local_context)
  40. when "Loop" then
  41. Result := instruction_loop(inst.instruction, local_context)
  42. when "Check" then
  43. Result := instruction_check(inst.instruction, local_context)
  44. when "Debug" then
  45. Result := instruction_debug(inst.instruction, local_context)
  46. when "Creation", "Old_Creation" then
  47. Result := instruction_creation(inst.instruction, local_context)
  48. when "Retry" then
  49. Result := instruction_retry(inst.instruction, local_context)
  50. end
  51. ensure
  52. not errors.has_error implies Result /= Void
  53. end
  54. expression (exp: LIBERTY_AST_EXPRESSION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  55. require
  56. exp /= Void
  57. local_context /= Void
  58. do
  59. if exp.is_array then
  60. Result := expression_array(exp.array, local_context)
  61. else
  62. Result := expression_no_array(exp.no_array, local_context)
  63. end
  64. ensure
  65. not errors.has_error implies Result /= Void
  66. end
  67. feature {} -- Instructions
  68. empty_instruction: LIBERTY_EMPTY is
  69. once
  70. create Result.make
  71. end
  72. compound (insts: EIFFEL_LIST_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSTRUCTION is
  73. require
  74. insts /= Void
  75. local_context /= Void
  76. local
  77. i, n: INTEGER; inst: LIBERTY_AST_INSTRUCTION
  78. instructions: COLLECTION[LIBERTY_INSTRUCTION]
  79. pos: LIBERTY_POSITION
  80. do
  81. n := insts.count
  82. inspect
  83. n
  84. when 0 then
  85. Result := empty_instruction
  86. when 1 then
  87. inst ::= insts.first
  88. Result := instruction(inst, local_context)
  89. else
  90. create {FAST_ARRAY[LIBERTY_INSTRUCTION]} instructions.with_capacity(n)
  91. from
  92. i := insts.lower
  93. until
  94. i > insts.upper
  95. loop
  96. inst ::= insts.item(i)
  97. instructions.add_last(instruction(inst, local_context))
  98. i := i + 1
  99. end
  100. pos := instructions.first.position
  101. create {LIBERTY_COMPOUND} Result.make(instructions, pos)
  102. end
  103. ensure
  104. not errors.has_error implies Result /= Void
  105. end
  106. instruction_assignment (a_assignment: LIBERTY_AST_ASSIGNMENT_OR_CALL; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_ASSIGNMENT is
  107. require
  108. a_assignment.is_assignment
  109. local
  110. w: LIBERTY_WRITABLE
  111. exp: LIBERTY_EXPRESSION
  112. do
  113. w := writable(a_assignment.writable, local_context)
  114. exp := expression(a_assignment.expression, local_context)
  115. if a_assignment.is_regular_assignment then
  116. create {LIBERTY_ASSIGNMENT_REGULAR} Result.make(w, exp, w.position)
  117. elseif a_assignment.is_forced_assignment then
  118. create {LIBERTY_ASSIGNMENT_FORCED} Result.make(w, exp, w.position)
  119. elseif a_assignment.is_assignment_attempt then
  120. create {LIBERTY_ASSIGNMENT_ATTEMPT} Result.make(w, exp, w.position)
  121. else
  122. check False end
  123. end
  124. end
  125. instruction_call (a_call: LIBERTY_AST_ASSIGNMENT_OR_CALL; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSTRUCTION is
  126. require
  127. a_call.is_call
  128. local
  129. tgt: LIBERTY_EXPRESSION
  130. fe: LIBERTY_FEATURE_ENTITY
  131. fa: COLLECTION[LIBERTY_EXPRESSION]
  132. r10: LIBERTY_AST_R10
  133. do
  134. r10 := a_call.r10
  135. if r10.is_empty then
  136. Result := implicit_feature_call_instruction(a_call.target, local_context)
  137. else
  138. from
  139. tgt := target_or_implicit_feature_call_expression(a_call.target, local_context)
  140. until
  141. errors.has_error or else Result /= Void
  142. loop
  143. fe ::= entity(tgt.result_type, r10.feature_name.image.image.intern, errors.semantics_position(r10.feature_name.image.index, ast, file), Void)
  144. fa := actuals(r10.actuals, local_context)
  145. r10 := r10.remainder
  146. if r10.is_empty then
  147. Result := create_instruction_call(tgt, fe, fa, tgt.position, local_context)
  148. else
  149. tgt := create_expression_call(tgt, fe, fa, tgt.position, local_context)
  150. end
  151. end
  152. end
  153. check
  154. errors.has_error or else r10.is_empty
  155. end
  156. end
  157. instruction_ifthenelse (a_cond: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CONDITIONAL is
  158. require
  159. a_cond /= Void
  160. {LIBERTY_AST_IF_THEN_ELSE} ?:= a_cond
  161. local
  162. ifthenelse: LIBERTY_AST_IF_THEN_ELSE
  163. ifthen: LIBERTY_AST_IF
  164. conditional: LIBERTY_CONDITIONAL
  165. i: INTEGER
  166. do
  167. ifthenelse ::= a_cond
  168. create conditional.make(semantics_position_at(ifthenelse.then_clause.node_at(0)))
  169. conditional.add_condition(condition(ifthenelse.then_clause, local_context))
  170. from
  171. i := ifthenelse.elseif_list.lower
  172. until
  173. i > ifthenelse.elseif_list.upper
  174. loop
  175. ifthen ::= ifthenelse.elseif_list.item(i)
  176. conditional.add_condition(condition(ifthen, local_context))
  177. i := i + 1
  178. end
  179. conditional.set_else_clause(else_clause(ifthenelse.else_clause, local_context))
  180. Result := conditional
  181. end
  182. condition (a_if: LIBERTY_AST_IF; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CONDITION is
  183. do
  184. create Result.make(expression(a_if.expression, local_context), compound(a_if.instructions, local_context),
  185. semantics_position_at(a_if.node_at(0)))
  186. end
  187. else_clause (a_else: LIBERTY_AST_ELSE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_DEFAULT is
  188. do
  189. if not a_else.is_empty then
  190. create Result.make(compound(a_else.list, local_context),
  191. semantics_position_at(a_else.node_at(0)))
  192. end
  193. end
  194. instruction_inspect (a_inspect: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSPECT is
  195. require
  196. a_inspect /= Void
  197. {LIBERTY_AST_INSPECT} ?:= a_inspect
  198. local
  199. inspct: LIBERTY_AST_INSPECT
  200. insp: LIBERTY_INSPECT
  201. i: INTEGER
  202. do
  203. inspct ::= a_inspect
  204. create insp.make(expression(inspct.expression, local_context), semantics_position_at(inspct.node_at(0)))
  205. from
  206. i := inspct.when_list.lower
  207. until
  208. i > inspct.when_list.upper
  209. loop
  210. insp.add_clause(inspect_clause(inspct.when_list.item(i), local_context))
  211. i := i + 1
  212. end
  213. insp.set_else_clause(else_clause(inspct.else_clause, local_context))
  214. Result := insp
  215. end
  216. inspect_clause (a_clause: EIFFEL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSPECT_CLAUSE is
  217. require
  218. {LIBERTY_AST_WHEN} ?:= a_clause
  219. local
  220. when_clause: LIBERTY_AST_WHEN
  221. when_slice: LIBERTY_AST_WHEN_SLICE
  222. i: INTEGER
  223. low, up: LIBERTY_EXPRESSION
  224. do
  225. when_clause ::= a_clause
  226. create Result.make(compound(when_clause.instructions, local_context), semantics_position_at(when_clause.node_at(0)))
  227. from
  228. i := when_clause.when_slices.lower
  229. until
  230. i > when_clause.when_slices.upper
  231. loop
  232. when_slice ::= when_clause.when_slices.item(i)
  233. low := when_value(when_slice.low_value, local_context)
  234. if when_slice.has_up_value then
  235. up := when_value(when_slice.up_value, local_context)
  236. else
  237. up := Void
  238. end
  239. Result.add_value(create {LIBERTY_INSPECT_SLICE}.make(low, up, low.position))
  240. i := i + 1
  241. end
  242. end
  243. when_value (value: LIBERTY_AST_WHEN_VALUE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  244. local
  245. e: LIBERTY_FEATURE_ENTITY; entity_name: LIBERTY_AST_ENTITY_NAME; name: FIXED_STRING
  246. do
  247. if value.is_number then
  248. Result := number(value.number.image)
  249. elseif value.is_character then
  250. Result := character(value.character.image)
  251. elseif value.is_string then
  252. create {LIBERTY_STRING_MANIFEST} Result.make(universe.type_string, native_array_of_character, decoded_string(value.string), True, semantics_position_at(value.node_at(0)))
  253. elseif value.is_entity_name then
  254. entity_name := value.entity_name
  255. name := entity_name.image.image.intern
  256. -- may be a local or a parameter of a regular feature name
  257. if local_context.is_local(name) then
  258. create {LIBERTY_ENTITY_EXPRESSION} Result.make(local_context.local_var(name), errors.semantics_position(entity_name.image.index, ast, file))
  259. elseif local_context.is_parameter(name) then
  260. create {LIBERTY_ENTITY_EXPRESSION} Result.make(local_context.parameter(name), errors.semantics_position(entity_name.image.index, ast, file))
  261. else
  262. e := feature_entity(type, create {LIBERTY_FEATURE_NAME}.make_regular(name, errors.semantics_position(entity_name.image.index, ast, file)))
  263. Result := create_implicit_expression_call(e, empty_actuals, errors.semantics_position(entity_name.image.index, ast, file))
  264. end
  265. else
  266. check False end
  267. end
  268. ensure
  269. Result /= Void
  270. end
  271. instruction_loop (a_loop: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_LOOP is
  272. require
  273. a_loop /= Void
  274. {LIBERTY_AST_LOOP} ?:= a_loop
  275. local
  276. l00p: LIBERTY_AST_LOOP
  277. init, body: like compound
  278. exp, var: LIBERTY_EXPRESSION
  279. variant_clause: LIBERTY_VARIANT
  280. invariant_clause: LIBERTY_INVARIANT
  281. do
  282. l00p ::= a_loop
  283. init := compound(l00p.from_clause.instructions, local_context)
  284. invariant_clause := loop_invariant(l00p.invariant_clause, local_context)
  285. if l00p.variant_clause.has_expression then
  286. var := expression(l00p.variant_clause.expression, local_context)
  287. create variant_clause.make(var)
  288. end
  289. exp := expression(l00p.expression, local_context)
  290. body := compound(l00p.instructions, local_context)
  291. create Result.make(init, invariant_clause, variant_clause, exp, body, init.position)
  292. end
  293. loop_invariant (invariant_clause: LIBERTY_AST_INVARIANT; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INVARIANT is
  294. require
  295. invariant_clause /= Void
  296. local_context /= Void
  297. local
  298. assertions: COLLECTION[LIBERTY_ASSERTION]
  299. do
  300. assertions := feature_assertions(invariant_clause, local_context)
  301. if not errors.has_error then
  302. create Result.make(assertions)
  303. end
  304. ensure
  305. not errors.has_error implies Result /= Void
  306. end
  307. instruction_check (a_check: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CHECK_INSTRUCTION is
  308. require
  309. a_check /= Void
  310. {LIBERTY_AST_CHECK} ?:= a_check
  311. local
  312. chk: LIBERTY_AST_CHECK; ck: LIBERTY_CHECK
  313. do
  314. chk ::= a_check
  315. create ck.make(feature_assertions(chk, local_context))
  316. create Result.make(ck, semantics_position_at(chk.node_at(0)))
  317. end
  318. instruction_debug (a_debug: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_DEBUG is
  319. require
  320. a_debug /= Void
  321. {LIBERTY_AST_DEBUG} ?:= a_debug
  322. local
  323. dbg: LIBERTY_AST_DEBUG
  324. keys: COLLECTION[FIXED_STRING]; inst: like compound
  325. i: INTEGER
  326. do
  327. dbg ::= a_debug
  328. if dbg.debug_keys.list_count = 0 then
  329. keys := empty_debug_keys
  330. else
  331. create {FAST_ARRAY[FIXED_STRING]} keys.with_capacity(dbg.debug_keys.list_count)
  332. from
  333. i := dbg.debug_keys.list_lower
  334. until
  335. i > dbg.debug_keys.list_upper
  336. loop
  337. keys.add_last(decoded_string(dbg.debug_keys.list_item(i)).intern)
  338. i := i + 1
  339. end
  340. end
  341. inst := compound(dbg.instructions, local_context)
  342. create Result.make(keys, inst, semantics_position_at(dbg.node_at(0)))
  343. ensure
  344. Result /= Void
  345. end
  346. empty_debug_keys: COLLECTION[FIXED_STRING] is
  347. once
  348. create {FAST_ARRAY[FIXED_STRING]} Result.with_capacity(0)
  349. end
  350. instruction_creation (a_creation: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CREATION_INSTRUCTION is
  351. require
  352. a_creation /= Void
  353. {LIBERTY_AST_CREATION} ?:= a_creation
  354. local
  355. creat: LIBERTY_AST_CREATION
  356. w: LIBERTY_WRITABLE
  357. creation_type: LIBERTY_TYPE
  358. fe: LIBERTY_FEATURE_ENTITY
  359. fa: COLLECTION[LIBERTY_EXPRESSION]
  360. do
  361. creat ::= a_creation
  362. w := writable(creat.writable, local_context)
  363. if creat.has_type_definition then
  364. creation_type := type_lookup.resolver.type(creat.type_definition)
  365. else
  366. creation_type := w.result_type
  367. end
  368. if creat.has_creation_feature_call then
  369. fe := feature_entity(creation_type, create {LIBERTY_FEATURE_NAME}.make_regular(creat.creation_feature_name.image.image.intern, errors.semantics_position(creat.creation_feature_name.image.index, ast, file)))
  370. fa := actuals(creat.creation_feature_actuals, local_context)
  371. else
  372. fe := feature_entity(creation_type, default_create_name)
  373. fa := empty_actuals
  374. end
  375. create Result.make(w, creation_type, fe, fa, semantics_position_at(creat.node_at(0)))
  376. end
  377. default_create_name: LIBERTY_FEATURE_NAME is
  378. once
  379. create Result.make_regular("default_create".intern, errors.unknown_position)
  380. end
  381. instruction_retry (a_retry: LIBERTY_AST_NON_TERMINAL_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_RETRY is
  382. require
  383. a_retry /= Void
  384. {LIBERTY_AST_RETRY} ?:= a_retry
  385. local
  386. re: LIBERTY_AST_RETRY
  387. do
  388. re ::= a_retry
  389. Result := local_context.retry_instruction(semantics_position_at(re.node_at(0)))
  390. end
  391. feature {} -- Entities and writables
  392. writable (a_writable: LIBERTY_AST_WRITABLE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_WRITABLE is
  393. local
  394. name: FIXED_STRING
  395. do
  396. if a_writable.is_result then
  397. Result := local_context.result_entity
  398. else
  399. name := a_writable.entity_name.image.image.intern
  400. if local_context.is_local(name) then
  401. Result := local_context.local_var(name)
  402. elseif local_context.is_parameter(name) then
  403. --|*** TODO: error! (not writable)
  404. not_yet_implemented
  405. else
  406. Result := feature_writable(name, errors.semantics_position(a_writable.entity_name.image.index, ast, file))
  407. end
  408. end
  409. ensure
  410. not errors.has_error implies Result /= Void
  411. end
  412. entity (target_type: LIBERTY_TYPE; a_entity_name: FIXED_STRING; a_position: LIBERTY_POSITION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_ENTITY is
  413. require
  414. a_entity_name /= Void
  415. (target_type = Void) /= (local_context = Void)
  416. do
  417. if local_context = Void then
  418. Result := feature_entity(target_type, create {LIBERTY_FEATURE_NAME}.make_regular(a_entity_name, a_position))
  419. else
  420. if a_entity_name.is_equal(once "Current") then
  421. Result := current_entity
  422. elseif a_entity_name.is_equal(once "Result") then
  423. Result := local_context.result_entity
  424. elseif local_context.is_local(a_entity_name) then
  425. Result := local_context.local_var(a_entity_name)
  426. elseif local_context.is_parameter(a_entity_name) then
  427. Result := local_context.parameter(a_entity_name)
  428. else
  429. Result := feature_entity(type, create {LIBERTY_FEATURE_NAME}.make_regular(a_entity_name, a_position))
  430. end
  431. end
  432. ensure
  433. not errors.has_error implies Result /= Void
  434. end
  435. implicit_feature_call_instruction (a_target: LIBERTY_AST_TARGET; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INSTRUCTION is
  436. local
  437. e: LIBERTY_FEATURE_ENTITY; entity_name: LIBERTY_AST_ENTITY_NAME; name: FIXED_STRING
  438. definition_context: LIBERTY_FEATURE_DEFINITION_CONTEXT
  439. do
  440. if a_target.is_current then
  441. --| TODO: error
  442. not_yet_implemented
  443. elseif a_target.is_result then
  444. --| TODO: error
  445. not_yet_implemented
  446. elseif a_target.is_implicit_feature_call then
  447. entity_name := a_target.implicit_feature_name
  448. name := entity_name.image.image.intern
  449. -- may be a local or a parameter of a regular feature name
  450. if local_context.is_local(name) then
  451. --| TODO: error
  452. not_yet_implemented
  453. elseif local_context.is_parameter(name) then
  454. --| TODO: error
  455. not_yet_implemented
  456. else
  457. e := feature_entity(type, create {LIBERTY_FEATURE_NAME}.make_regular(name, errors.semantics_position(entity_name.image.index, ast, file)))
  458. Result := create_implicit_instruction_call(e, actuals(a_target.actuals, local_context), errors.semantics_position(entity_name.image.index, ast, file))
  459. end
  460. elseif a_target.is_precursor then
  461. definition_context ::= local_context
  462. Result := instruction_call_on_precursor(a_target, definition_context)
  463. elseif a_target.is_parenthesized_expression then
  464. --| TODO: error
  465. not_yet_implemented
  466. else
  467. check False end
  468. end
  469. ensure
  470. not errors.has_error implies Result /= Void
  471. end
  472. instruction_call_on_precursor (a_precursor_target: LIBERTY_AST_TARGET; local_context: LIBERTY_FEATURE_DEFINITION_CONTEXT): LIBERTY_PRECURSOR_INSTRUCTION is
  473. require
  474. a_precursor_target.is_precursor
  475. deferred
  476. end
  477. target_or_implicit_feature_call_expression (a_target: LIBERTY_AST_TARGET; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  478. local
  479. e: LIBERTY_FEATURE_ENTITY; entity_name: LIBERTY_AST_ENTITY_NAME; name: FIXED_STRING
  480. definition_context: LIBERTY_FEATURE_DEFINITION_CONTEXT
  481. do
  482. if a_target.is_current then
  483. create {LIBERTY_ENTITY_EXPRESSION} Result.make(current_entity, semantics_position_at(a_target.node_at(0)))
  484. elseif a_target.is_result then
  485. create {LIBERTY_ENTITY_EXPRESSION} Result.make(local_context.result_entity, semantics_position_at(a_target.node_at(0)))
  486. elseif a_target.is_manifest_or_type_test then
  487. Result := typed_manifest_or_type_test(a_target.manifest_or_type_test, local_context)
  488. elseif a_target.is_implicit_feature_call then
  489. entity_name := a_target.implicit_feature_name
  490. name := entity_name.image.image.intern
  491. -- may be a local or a parameter of a regular feature name
  492. if local_context.is_local(name) then
  493. create {LIBERTY_ENTITY_EXPRESSION} Result.make(local_context.local_var(name), errors.semantics_position(entity_name.image.index, ast, file))
  494. --| TODO: check no actuals
  495. elseif local_context.is_parameter(name) then
  496. create {LIBERTY_ENTITY_EXPRESSION} Result.make(local_context.parameter(name), errors.semantics_position(entity_name.image.index, ast, file))
  497. --| TODO: check no actuals
  498. else
  499. e := feature_entity(type, create {LIBERTY_FEATURE_NAME}.make_regular(name, errors.semantics_position(entity_name.image.index, ast, file)))
  500. Result := create_implicit_expression_call(e, actuals(a_target.actuals, local_context), errors.semantics_position(entity_name.image.index, ast, file))
  501. end
  502. elseif a_target.is_precursor then
  503. definition_context ::= local_context
  504. Result := expression_call_on_precursor(a_target, definition_context)
  505. elseif a_target.is_parenthesized_expression then
  506. Result := expression(a_target.parenthesized_expression, local_context)
  507. else
  508. check False end
  509. end
  510. ensure
  511. not errors.has_error implies Result /= Void
  512. end
  513. expression_call_on_precursor (a_precursor_target: LIBERTY_AST_TARGET; local_context: LIBERTY_FEATURE_DEFINITION_CONTEXT): LIBERTY_PRECURSOR_EXPRESSION is
  514. require
  515. a_precursor_target.is_precursor
  516. deferred
  517. end
  518. feature_writable (name: FIXED_STRING; position: LIBERTY_POSITION): LIBERTY_WRITABLE_FEATURE is
  519. require
  520. name = name.intern
  521. do
  522. Result := feature_writables.reference_at(name)
  523. if Result = Void then
  524. create {LIBERTY_WRITABLE_FEATURE} Result.make(feature_entity(type, create {LIBERTY_FEATURE_NAME}.make_regular(name, position)), position)
  525. feature_writables.put(Result, name)
  526. torch.burn
  527. end
  528. ensure
  529. Result.name = name
  530. end
  531. feature_entity (target_type: LIBERTY_TYPE; name: LIBERTY_FEATURE_NAME): LIBERTY_FEATURE_ENTITY is
  532. require
  533. name /= Void
  534. do
  535. create {LIBERTY_FEATURE_ENTITY} Result.make(name, target_type)
  536. ensure
  537. Result.feature_name.is_equal(name)
  538. end
  539. current_entity: LIBERTY_CURRENT is
  540. deferred
  541. ensure
  542. Result /= Void
  543. end
  544. feature_writables: DICTIONARY[LIBERTY_WRITABLE_FEATURE, FIXED_STRING]
  545. feature {} -- Expressions
  546. actuals (a_actuals: LIBERTY_AST_ACTUALS; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): COLLECTION[LIBERTY_EXPRESSION] is
  547. local
  548. i: INTEGER
  549. act: LIBERTY_AST_ACTUAL
  550. do
  551. if a_actuals.list_count= 0 then
  552. Result := empty_actuals
  553. else
  554. create {FAST_ARRAY[LIBERTY_EXPRESSION]} Result.with_capacity(a_actuals.list_count)
  555. from
  556. i := a_actuals.list_lower
  557. until
  558. i > a_actuals.list_upper
  559. loop
  560. act := a_actuals.list_item(i)
  561. if act.is_expression then
  562. Result.add_last(expression(act.expression, local_context))
  563. else
  564. check act.is_ref_to_entity end
  565. Result.add_last(create {LIBERTY_ENTITY_REFERENCE}.make(universe.type_pointer,
  566. entity(Void, act.ref_entity_name.image.image.intern, errors.semantics_position(act.ref_entity_name.image.index, ast, file), local_context),
  567. semantics_position_at(act.node_at(0))))
  568. end
  569. i := i + 1
  570. end
  571. end
  572. ensure
  573. not errors.has_error implies Result /= Void
  574. end
  575. empty_actuals: COLLECTION[LIBERTY_EXPRESSION] is
  576. once
  577. create {FAST_ARRAY[LIBERTY_EXPRESSION]} Result.make(0)
  578. end
  579. expression_array (array: LIBERTY_AST_ARRAY; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_ARRAY_MANIFEST is
  580. require
  581. array /= Void
  582. local_context /= Void
  583. local
  584. i: INTEGER; content: COLLECTION[LIBERTY_EXPRESSION]; separators: COLLECTION[LIBERTY_ARRAY_MANIFEST_SEPARATOR]
  585. exp: LIBERTY_AST_EXPRESSION; t: LIBERTY_TYPE
  586. expr: LIBERTY_EXPRESSION
  587. do
  588. create {FAST_ARRAY[LIBERTY_EXPRESSION]} content.with_capacity(array.content.count)
  589. create {FAST_ARRAY[LIBERTY_ARRAY_MANIFEST_SEPARATOR]} separators.with_capacity(array.content.count)
  590. from
  591. i := array.content.lower
  592. invariant
  593. content.count = separators.count
  594. variant
  595. array.content.count - content.count
  596. until
  597. i > array.content.upper or else errors.has_error
  598. loop
  599. exp ::= array.content.item(i)
  600. expr := expression(exp, local_context)
  601. if not errors.has_error then
  602. content.add_last(expr)
  603. separators.add_last(expression_separator(exp))
  604. end
  605. i := i + 1
  606. end
  607. if not errors.has_error then
  608. t := common_conformant_type(content)
  609. create Result.make_array(t, content, separators, semantics_position_at(array.node_at(0)))
  610. end
  611. ensure
  612. not errors.has_error implies Result /= Void
  613. end
  614. common_conformant_type (a_contents: COLLECTION[LIBERTY_EXPRESSION]): LIBERTY_TYPE is
  615. local
  616. i: INTEGER
  617. do
  618. if a_contents.is_empty then
  619. Result := universe.type_any
  620. else
  621. from
  622. Result := a_contents.first.result_type
  623. i := a_contents.lower + 1
  624. until
  625. i > a_contents.upper
  626. loop
  627. Result := a_contents.item(i).result_type.known_type.common_conformant_parent_with(Result.known_type)
  628. if Result = Void then
  629. --| *** TODO fatal error
  630. not_yet_implemented
  631. end
  632. i := i + 1
  633. end
  634. end
  635. ensure
  636. no_common_parent_is_fatal: Result /= Void
  637. end
  638. expression_no_array (exp: LIBERTY_AST_EXPRESSION_NO_ARRAY; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  639. require
  640. exp /= Void
  641. local_context /= Void
  642. do
  643. if exp.is_binary_expression then
  644. Result := binary_expression_1(exp.binary_expression, local_context)
  645. else
  646. Result := expression_1(exp.simple_expression, local_context)
  647. end
  648. ensure
  649. not errors.has_error implies Result /= Void
  650. end
  651. binary_expression_1 (exp1: LIBERTY_AST_EXP1; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  652. local
  653. left, right: LIBERTY_EXPRESSION
  654. do
  655. if exp1.is_binary then
  656. left := binary_expression_1(exp1.left_binary, local_context)
  657. else
  658. left := expression_1(exp1.left_expression, local_context)
  659. end
  660. right := expression_1(exp1.right_expression, local_context)
  661. if exp1.is_implies then
  662. create {LIBERTY_IMPLIES} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp1.operator1))
  663. end
  664. end
  665. expression_1 (exp: LIBERTY_AST_E1; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  666. require
  667. exp /= Void
  668. local_context /= Void
  669. do
  670. if exp.is_binary_expression then
  671. Result := binary_expression_2(exp.binary_expression, local_context)
  672. else
  673. Result := expression_2(exp.simple_expression, local_context)
  674. end
  675. ensure
  676. not errors.has_error implies Result /= Void
  677. end
  678. binary_expression_2 (exp2: LIBERTY_AST_EXP2; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  679. local
  680. left, right: LIBERTY_EXPRESSION
  681. do
  682. if exp2.is_binary then
  683. left := binary_expression_2(exp2.left_binary, local_context)
  684. else
  685. left := expression_2(exp2.left_expression, local_context)
  686. end
  687. right := expression_2(exp2.right_expression, local_context)
  688. if exp2.is_or_else then
  689. create {LIBERTY_OR_ELSE} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp2.operator1))
  690. elseif exp2.is_or then
  691. create {LIBERTY_OR} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp2.operator1))
  692. elseif exp2.is_xor then
  693. create {LIBERTY_XOR} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp2.operator1))
  694. end
  695. end
  696. expression_2 (exp: LIBERTY_AST_E2; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  697. require
  698. exp /= Void
  699. local_context /= Void
  700. do
  701. if exp.is_binary_expression then
  702. Result := binary_expression_3(exp.binary_expression, local_context)
  703. else
  704. Result := expression_3(exp.simple_expression, local_context)
  705. end
  706. ensure
  707. not errors.has_error implies Result /= Void
  708. end
  709. binary_expression_3 (exp3: LIBERTY_AST_EXP3; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  710. local
  711. left, right: LIBERTY_EXPRESSION
  712. do
  713. if exp3.is_binary then
  714. left := binary_expression_3(exp3.left_binary, local_context)
  715. else
  716. left := expression_3(exp3.left_expression, local_context)
  717. end
  718. right := expression_3(exp3.right_expression, local_context)
  719. if exp3.is_and_then then
  720. create {LIBERTY_AND_THEN} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp3.operator1))
  721. elseif exp3.is_and then
  722. create {LIBERTY_AND} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp3.operator1))
  723. end
  724. end
  725. expression_3 (exp: LIBERTY_AST_E3; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  726. require
  727. exp /= Void
  728. local_context /= Void
  729. do
  730. if exp.is_binary_expression then
  731. Result := binary_expression_4(exp.binary_expression, local_context)
  732. else
  733. Result := expression_4(exp.simple_expression, local_context)
  734. end
  735. ensure
  736. not errors.has_error implies Result /= Void
  737. end
  738. binary_expression_4 (exp4: LIBERTY_AST_EXP4; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  739. local
  740. left, right: LIBERTY_EXPRESSION
  741. do
  742. if exp4.is_binary then
  743. left := binary_expression_4(exp4.left_binary, local_context)
  744. else
  745. left := expression_4(exp4.left_expression, local_context)
  746. end
  747. right := expression_4(exp4.right_expression, local_context)
  748. if exp4.is_eq then
  749. create {LIBERTY_EQUALS} Result.make(left, right, universe.type_boolean, image_semantics_position_at(exp4.operator1))
  750. elseif exp4.is_ne then
  751. create {LIBERTY_NOT_EQUALS} Result.make(left, right, universe.type_boolean, image_semantics_position_at(exp4.operator1))
  752. elseif exp4.is_le then
  753. create {LIBERTY_LESS_OR_EQUAL} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp4.operator1))
  754. elseif exp4.is_lt then
  755. create {LIBERTY_LESS_THAN} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp4.operator1))
  756. elseif exp4.is_ge then
  757. create {LIBERTY_GREATER_OR_EQUAL} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp4.operator1))
  758. elseif exp4.is_gt then
  759. create {LIBERTY_GREATER_THAN} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp4.operator1))
  760. end
  761. end
  762. expression_4 (exp: LIBERTY_AST_E4; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  763. require
  764. exp /= Void
  765. local_context /= Void
  766. do
  767. if exp.is_binary_expression then
  768. Result := binary_expression_5(exp.binary_expression, local_context)
  769. else
  770. Result := expression_5(exp.simple_expression, local_context)
  771. end
  772. ensure
  773. not errors.has_error implies Result /= Void
  774. end
  775. binary_expression_5 (exp5: LIBERTY_AST_EXP5; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  776. local
  777. left, right: LIBERTY_EXPRESSION
  778. do
  779. if exp5.is_binary then
  780. left := binary_expression_5(exp5.left_binary, local_context)
  781. else
  782. left := expression_5(exp5.left_expression, local_context)
  783. end
  784. right := expression_5(exp5.right_expression, local_context)
  785. if exp5.is_plus then
  786. create {LIBERTY_ADD} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp5.operator1))
  787. elseif exp5.is_minus then
  788. create {LIBERTY_SUBTRACT} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp5.operator1))
  789. end
  790. end
  791. expression_5 (exp: LIBERTY_AST_E5; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  792. require
  793. exp /= Void
  794. local_context /= Void
  795. do
  796. if exp.is_binary_expression then
  797. Result := binary_expression_6(exp.binary_expression, local_context)
  798. else
  799. Result := expression_6(exp.simple_expression, local_context)
  800. end
  801. ensure
  802. not errors.has_error implies Result /= Void
  803. end
  804. binary_expression_6 (exp6: LIBERTY_AST_EXP6; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  805. local
  806. left, right: LIBERTY_EXPRESSION
  807. do
  808. if exp6.is_binary then
  809. left := binary_expression_6(exp6.left_binary, local_context)
  810. else
  811. left := expression_6(exp6.left_expression, local_context)
  812. end
  813. right := expression_6(exp6.right_expression, local_context)
  814. if exp6.is_times then
  815. create {LIBERTY_TIMES} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp6.operator1))
  816. elseif exp6.is_divide then
  817. create {LIBERTY_DIVIDE} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp6.operator1))
  818. elseif exp6.is_int_divide then
  819. create {LIBERTY_INT_DIVIDE} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp6.operator1))
  820. elseif exp6.is_int_remainder then
  821. create {LIBERTY_INT_REMAINDER} Result.make(left, right, agent feature_entity, image_semantics_position_at(exp6.operator1))
  822. end
  823. end
  824. expression_6 (exp: LIBERTY_AST_E6; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  825. require
  826. exp /= Void
  827. local_context /= Void
  828. do
  829. Result := expression_7(exp.e7, exp.r7, local_context)
  830. ensure
  831. not errors.has_error implies Result /= Void
  832. end
  833. expression_7 (e7: LIBERTY_AST_E7; r7: LIBERTY_AST_R7; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  834. do
  835. Result := expression_8(e7.e8, e7.r8, local_context)
  836. if r7.is_power then
  837. create {LIBERTY_POWER} Result.make(Result, expression_7(r7.expression, r7.remainder, local_context), agent feature_entity, Result.position)
  838. end
  839. end
  840. expression_8 (e8: LIBERTY_AST_E8; r8: LIBERTY_AST_R8; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  841. local
  842. fn: LIBERTY_FEATURE_NAME
  843. do
  844. if e8.has_prefix_operator then
  845. inspect
  846. e8.prefix_operator.name.out
  847. when "KW +" then
  848. create {LIBERTY_POSITIVE} Result.make(expression_8(e8.prefixed_expression, r8, local_context), agent feature_entity, semantics_position_at(e8.prefix_operator))
  849. when "KW -" then
  850. create {LIBERTY_NEGATIVE} Result.make(expression_8(e8.prefixed_expression, r8, local_context), agent feature_entity, semantics_position_at(e8.prefix_operator))
  851. when "KW not" then
  852. create {LIBERTY_NOT} Result.make(expression_8(e8.prefixed_expression, r8, local_context), agent feature_entity, semantics_position_at(e8.prefix_operator))
  853. else
  854. create fn.make_prefix(e8.prefix_operator.image.image.intern, errors.semantics_position(e8.prefix_operator.image.index, ast, file))
  855. Result := expression_8(e8.prefixed_expression, r8, local_context)
  856. create {LIBERTY_PREFIX_OPERATOR} Result.make(Result, feature_entity(Result.result_type, fn), semantics_position_at(e8.prefix_operator))
  857. end
  858. else
  859. Result := expression_9(e8.e9, local_context)
  860. end
  861. if r8.is_free_operator then
  862. create fn.make_infix(r8.free_operator.image.image.intern, errors.semantics_position(r8.free_operator.image.index, ast, file))
  863. create {LIBERTY_INFIX_OPERATOR} Result.make(Result, expression_8(r8.expression, r8.remainder, local_context), feature_entity(Result.result_type, fn), Result.position)
  864. end
  865. end
  866. expression_9 (e9: LIBERTY_AST_E9; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  867. do
  868. Result := expression_10(e9.e10, local_context)
  869. if e9.has_old then
  870. create {LIBERTY_OLD} Result.make(Result, semantics_position_at(e9.node_at(0)))
  871. end
  872. end
  873. expression_10 (e10: LIBERTY_AST_E10; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  874. local
  875. exp: LIBERTY_EXPRESSION; agent_expression: LIBERTY_CALL_EXPRESSION
  876. do
  877. if e10.is_call then
  878. Result := expression_call(e10.call, local_context)
  879. elseif e10.is_tuple then
  880. Result := expression_tuple(e10.tuple_actuals, local_context, semantics_position_at(e10.node_at(0)))
  881. elseif e10.is_open_argument then
  882. create {LIBERTY_OPEN_ARGUMENT} Result.make(semantics_position_at(e10.node_at(0)))
  883. elseif e10.is_inline_agent then
  884. Result := expression_inline_agent(e10.inline_agent_signature, e10.inline_agent_definition, e10.inline_agent_actuals, local_context)
  885. elseif e10.is_agent_creation then
  886. exp := expression(e10.agent_creation_expression, local_context)
  887. if not agent_expression ?:= exp then
  888. --|*** TODO: error: not a call
  889. not_yet_implemented
  890. end
  891. agent_expression ::= exp
  892. create {LIBERTY_AGENT} Result.make(agent_expression, semantics_position_at(e10.node_at(0)))
  893. elseif e10.is_creation_expression then
  894. Result := expression_creation(e10.creation_expression, local_context)
  895. elseif e10.is_void then
  896. create {LIBERTY_VOID} Result.make(semantics_position_at(e10.node_at(0)))
  897. else
  898. check False end
  899. end
  900. ensure
  901. not errors.has_error implies Result /= Void
  902. end
  903. expression_creation (a_creation: LIBERTY_AST_CREATION_EXPRESSION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  904. require
  905. a_creation /= Void
  906. local
  907. entity_type: LIBERTY_TYPE
  908. creation_type: LIBERTY_ACTUAL_TYPE
  909. tgt: LIBERTY_EXPRESSION
  910. fe: LIBERTY_FEATURE_ENTITY
  911. fa: COLLECTION[LIBERTY_EXPRESSION]
  912. do
  913. entity_type := type_lookup.resolver.type(a_creation.type_definition)
  914. if creation_type ?:= entity_type then
  915. creation_type ::= entity_type
  916. if a_creation.r10.is_empty then
  917. fe := feature_entity(creation_type, default_create_name)
  918. fa := empty_actuals
  919. create {LIBERTY_CREATION_EXPRESSION} Result.make(creation_type, fe, fa, semantics_position_at(a_creation.node_at(0)))
  920. else
  921. fe := feature_entity(creation_type, create {LIBERTY_FEATURE_NAME}.make_regular(a_creation.r10.feature_name.image.image.intern, errors.semantics_position(a_creation.r10.feature_name.image.index, ast, file)))
  922. fa := actuals(a_creation.r10.actuals, local_context)
  923. create {LIBERTY_CREATION_EXPRESSION} tgt.make(creation_type, fe, fa, semantics_position_at(a_creation.node_at(0)))
  924. Result := expression_remainder(tgt, a_creation.r10.remainder, local_context)
  925. end
  926. else
  927. --|*** TODO: error: no anchor in creation type
  928. not_yet_implemented
  929. end
  930. ensure
  931. not errors.has_error implies Result /= Void
  932. end
  933. expression_call (a_call: LIBERTY_AST_CALL; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  934. require
  935. a_call /= Void
  936. do
  937. if a_call.is_call then
  938. Result := target_or_implicit_feature_call_expression(a_call.call_target, local_context)
  939. Result := expression_remainder(Result, a_call.call_r10, local_context)
  940. else
  941. check
  942. a_call.is_assignment_test
  943. end
  944. create {LIBERTY_ASSIGNMENT_TEST} Result.test_entity(entity(Void, a_call.assignment_test_entity_name.image.image.intern, errors.semantics_position(a_call.assignment_test_entity_name.image.index, ast, file), local_context),
  945. expression(a_call.assignment_test_expression, local_context),
  946. universe.type_boolean, semantics_position_at(a_call.assignment_test_entity_name))
  947. end
  948. ensure
  949. not errors.has_error implies Result /= Void
  950. end
  951. expression_remainder (a_target: LIBERTY_EXPRESSION; a_remainder: LIBERTY_AST_R10; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  952. require
  953. a_target /= Void
  954. a_remainder /= Void
  955. local
  956. tgt: LIBERTY_EXPRESSION
  957. fe: LIBERTY_FEATURE_ENTITY
  958. fa: COLLECTION[LIBERTY_EXPRESSION]
  959. do
  960. -- We may derecursivate this thing (algorithm similar to `instruction_call')
  961. -- but I guess modern compilers are smart enough to do that anyway :-)
  962. if not errors.has_error then
  963. if a_remainder.is_empty then
  964. Result := a_target
  965. else
  966. fe ::= entity(a_target.result_type, a_remainder.feature_name.image.image.intern, errors.semantics_position(a_remainder.feature_name.image.index, ast, file), Void)
  967. fa := actuals(a_remainder.actuals, local_context)
  968. tgt := create_expression_call(a_target, fe, fa, a_target.position, local_context) --|*** or semantics_position_at(a_remainder.node_at(0)) ??
  969. Result := expression_remainder(tgt, a_remainder.remainder, local_context)
  970. end
  971. end
  972. ensure
  973. not errors.has_error implies Result /= Void
  974. end
  975. expression_inline_agent (a_signature: LIBERTY_AST_AGENT_SIGNATURE; a_definition: LIBERTY_AST_ROUTINE_DEFINITION; a_actuals: LIBERTY_AST_ACTUALS; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_INLINE_AGENT is
  976. local
  977. routine_execution: LIBERTY_AST_ROUTINE_EXECUTION
  978. do_block: LIBERTY_AST_DO_BLOCK
  979. comp: LIBERTY_INSTRUCTION
  980. closure_context: LIBERTY_INLINE_AGENT_CONTEXT
  981. result_type: LIBERTY_TYPE
  982. type_resolver: LIBERTY_TYPE_RESOLVER_IN_INLINE_AGENT
  983. do
  984. routine_execution := a_definition.execution
  985. if not routine_execution.is_regular then
  986. --|*** TODO: error: an inline agent must be regular
  987. not_yet_implemented
  988. end
  989. do_block := routine_execution.do_block
  990. if do_block.is_deferred then
  991. --|*** TODO: error: an inline agent cannot be deferred
  992. not_yet_implemented
  993. elseif do_block.is_attribute then
  994. --|*** TODO: error: an inline agent cannot be an attribute
  995. not_yet_implemented
  996. elseif do_block.is_once then
  997. --|*** TODO: error: an inline agent cannot be once (technical limitation, to be removed)
  998. not_yet_implemented
  999. end
  1000. if not a_definition.rescue_block.is_empty then
  1001. --|*** TODO
  1002. not_yet_implemented
  1003. end
  1004. create closure_context.make(local_context)
  1005. if a_signature.has_return_type then
  1006. result_type := type_lookup.resolver.type(a_signature.return_type)
  1007. closure_context.set_result_type(result_type)
  1008. end
  1009. create type_resolver.make(closure_context)
  1010. type_lookup.push(type_resolver)
  1011. if a_signature.has_parameters then
  1012. list_parameters(a_signature.parameters, closure_context)
  1013. end
  1014. list_locals(routine_execution.local_block, closure_context)
  1015. comp := compound(do_block.list, closure_context)
  1016. if not errors.has_error then
  1017. create Result.make(comp, actuals(a_actuals, local_context), closure_context)
  1018. end
  1019. type_lookup.pop
  1020. end
  1021. expression_tuple (a_tuple: EIFFEL_LIST_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT; a_position: LIBERTY_POSITION): LIBERTY_TUPLE is
  1022. local
  1023. exp: LIBERTY_AST_ACTUAL
  1024. expr: LIBERTY_EXPRESSION
  1025. expressions: COLLECTION[LIBERTY_EXPRESSION]
  1026. exp_types: COLLECTION[LIBERTY_TYPE]
  1027. i: INTEGER
  1028. do
  1029. if a_tuple = Void then
  1030. create {FAST_ARRAY[LIBERTY_EXPRESSION]} expressions.with_capacity(0)
  1031. create {FAST_ARRAY[LIBERTY_TYPE]} exp_types.with_capacity(0)
  1032. else
  1033. from
  1034. create {FAST_ARRAY[LIBERTY_EXPRESSION]} expressions.with_capacity(a_tuple.count)
  1035. create {FAST_ARRAY[LIBERTY_TYPE]} exp_types.with_capacity(a_tuple.count)
  1036. i := a_tuple.lower
  1037. until
  1038. errors.has_error or else i > a_tuple.upper
  1039. loop
  1040. exp ::= a_tuple.item(i)
  1041. if exp.is_expression then
  1042. expr := expression(exp.expression, local_context)
  1043. else
  1044. --| "$entity" expressions
  1045. not_yet_implemented
  1046. end
  1047. if not errors.has_error then
  1048. expressions.add_last(expr)
  1049. exp_types.add_last(expr.result_type)
  1050. end
  1051. i := i + 1
  1052. end
  1053. end
  1054. if not errors.has_error then
  1055. create Result.make(universe.type_tuple(exp_types, a_position), expressions, a_position)
  1056. end
  1057. ensure
  1058. not errors.has_error implies Result /= Void
  1059. end
  1060. typed_manifest_or_type_test (constant: LIBERTY_AST_MANIFEST_OR_TYPE_TEST; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_EXPRESSION is
  1061. require
  1062. constant /= Void
  1063. local_context /= Void
  1064. local
  1065. openarg: LIBERTY_OPEN_ARGUMENT
  1066. entity_type: LIBERTY_TYPE
  1067. actual_type: LIBERTY_ACTUAL_TYPE
  1068. do
  1069. if constant.is_assignment_test then
  1070. entity_type := type_lookup.resolver.type(constant.assignment_test_type)
  1071. if actual_type ?:= entity_type then
  1072. actual_type ::= entity_type
  1073. create {LIBERTY_ASSIGNMENT_TEST} Result.test_type(actual_type,
  1074. expression(constant.assignment_test_expression, local_context),
  1075. universe.type_boolean, semantics_position_at(constant.node_at(0)))
  1076. else
  1077. --|*** TODO: error: cannot use an anchor for assignment test
  1078. not_yet_implemented
  1079. end
  1080. elseif constant.is_typed_open_argument then
  1081. create openarg.make(semantics_position_at(constant.node_at(0)))
  1082. openarg.set_result_type(type_lookup.resolver.type(constant.open_argument_type))
  1083. Result := openarg
  1084. elseif constant.is_number then
  1085. Result := number(constant.number.image)
  1086. elseif constant.is_true then
  1087. create {LIBERTY_BOOLEAN_MANIFEST} Result.make(universe.type_boolean, True, semantics_position_at(constant.node_at(0)))
  1088. elseif constant.is_false then
  1089. create {LIBERTY_BOOLEAN_MANIFEST} Result.make(universe.type_boolean, False, semantics_position_at(constant.node_at(0)))
  1090. elseif constant.is_character then
  1091. Result := character(constant.character.image)
  1092. elseif constant.is_string then
  1093. create {LIBERTY_STRING_MANIFEST} Result.make(universe.type_string, native_array_of_character, decoded_string(constant.string), False, semantics_position_at(constant.node_at(0)))
  1094. elseif constant.is_once_string then
  1095. create {LIBERTY_STRING_MANIFEST} Result.make(universe.type_string, native_array_of_character, decoded_string(constant.string), True, semantics_position_at(constant.node_at(0)))
  1096. elseif constant.is_number_typed_manifest then
  1097. entity_type := type_lookup.resolver.type(constant.typed_manifest_type)
  1098. if actual_type ?:= entity_type then
  1099. actual_type ::= entity_type
  1100. Result := number_typed_manifest(actual_type,
  1101. constant.typed_manifest_number.image)
  1102. else
  1103. --|*** TODO: error: cannot use an anchor for array type definition
  1104. not_yet_implemented
  1105. end
  1106. elseif constant.is_string_typed_manifest then
  1107. entity_type := type_lookup.resolver.type(constant.typed_manifest_type)
  1108. if actual_type ?:= entity_type then
  1109. actual_type ::= entity_type
  1110. create {LIBERTY_STRING_TYPED_MANIFEST} Result.make(actual_type,
  1111. decoded_string(constant.typed_manifest_string), semantics_position_at(constant.node_at(0)))
  1112. else
  1113. --|*** TODO: error: cannot use an anchor for array type definition
  1114. not_yet_implemented
  1115. end
  1116. elseif constant.is_array_typed_manifest then
  1117. entity_type := type_lookup.resolver.type(constant.typed_manifest_type)
  1118. if actual_type ?:= entity_type then
  1119. actual_type ::= entity_type
  1120. Result := array_typed_manifest(actual_type,
  1121. constant.typed_manifest_array_parameters, constant.typed_manifest_array,
  1122. local_context, semantics_position_at(constant.node_at(0)))
  1123. else
  1124. --|*** TODO: error: cannot use an anchor for array type definition
  1125. not_yet_implemented
  1126. end
  1127. else
  1128. check False end
  1129. end
  1130. ensure
  1131. not errors.has_error implies Result /= Void
  1132. end
  1133. number (number_image: EIFFEL_IMAGE): LIBERTY_EXPRESSION is
  1134. require
  1135. ({TYPED_EIFFEL_IMAGE[INTEGER_64]} ?:= number_image)
  1136. or else ({TYPED_EIFFEL_IMAGE[REAL]} ?:= number_image)
  1137. local
  1138. i: TYPED_EIFFEL_IMAGE[INTEGER_64]
  1139. r: TYPED_EIFFEL_IMAGE[REAL]
  1140. i64: INTEGER_64
  1141. do
  1142. -- That's not pretty! but doing without all those type tests would incur big changes and code
  1143. -- duplication in the eiffel parser :-/
  1144. if i ?:= number_image then
  1145. i ::= number_image
  1146. i64 := i.decoded
  1147. if i64.fit_integer_8 then
  1148. create {LIBERTY_INTEGER_8_MANIFEST} Result.make(universe.type_integer_8, i64.to_integer_8, image_semantics_position_at(number_image))
  1149. elseif i64.fit_integer_16 then
  1150. create {LIBERTY_INTEGER_16_MANIFEST} Result.make(universe.type_integer_16, i64.to_integer_16, image_semantics_position_at(number_image))
  1151. elseif i64.fit_integer_32 then
  1152. create {LIBERTY_INTEGER_32_MANIFEST} Result.make(universe.type_integer_32, i64.to_integer_32, image_semantics_position_at(number_image))
  1153. else
  1154. create {LIBERTY_INTEGER_64_MANIFEST} Result.make(universe.type_integer_64, i64, image_semantics_position_at(number_image))
  1155. end
  1156. else
  1157. check
  1158. r ?:= number_image
  1159. end
  1160. r ::= number_image
  1161. create {LIBERTY_REAL_MANIFEST} Result.make(universe.type_real, r.decoded, image_semantics_position_at(number_image))
  1162. end
  1163. ensure
  1164. not errors.has_error implies Result /= Void
  1165. end
  1166. character (character_image: EIFFEL_IMAGE): LIBERTY_EXPRESSION is
  1167. require
  1168. {TYPED_EIFFEL_IMAGE[CHARACTER]} ?:= character_image
  1169. local
  1170. c: TYPED_EIFFEL_IMAGE[CHARACTER]
  1171. do
  1172. c ::= character_image
  1173. create {LIBERTY_CHARACTER_MANIFEST} Result.make(universe.type_character, c.decoded, image_semantics_position_at(character_image))
  1174. ensure
  1175. not errors.has_error implies Result /= Void
  1176. end
  1177. number_typed_manifest (manifest_type: LIBERTY_ACTUAL_TYPE; number_image: EIFFEL_IMAGE): LIBERTY_EXPRESSION is
  1178. require
  1179. ({TYPED_EIFFEL_IMAGE[INTEGER_64]} ?:= number_image)
  1180. or else ({TYPED_EIFFEL_IMAGE[REAL]} ?:= number_image)
  1181. local
  1182. i: TYPED_EIFFEL_IMAGE[INTEGER_64]
  1183. r: TYPED_EIFFEL_IMAGE[REAL]
  1184. do
  1185. if i ?:= number_image then
  1186. i ::= number_image
  1187. create {LIBERTY_INTEGER_TYPED_MANIFEST} Result.make(manifest_type, i.decoded, image_semantics_position_at(number_image))
  1188. else
  1189. check
  1190. r ?:= number_image
  1191. end
  1192. r ::= number_image
  1193. create {LIBERTY_REAL_TYPED_MANIFEST} Result.make(manifest_type, r.decoded, image_semantics_position_at(number_image))
  1194. end
  1195. ensure
  1196. not errors.has_error implies Result /= Void
  1197. end
  1198. array_typed_manifest (manifest_type: LIBERTY_ACTUAL_TYPE; array_parameters: EIFFEL_LIST_NODE; array: LIBERTY_AST_ARRAY;
  1199. local_context: LIBERTY_FEATURE_LOCAL_CONTEXT;
  1200. a_position: LIBERTY_POSITION): LIBERTY_ARRAY_MANIFEST is
  1201. require
  1202. local_context /= Void
  1203. local
  1204. i: INTEGER; ena: LIBERTY_AST_EXPRESSION_NO_ARRAY; exp: LIBERTY_AST_EXPRESSION
  1205. do
  1206. manifest_type.set_has_manifest_array
  1207. create Result.make(manifest_type, a_position)
  1208. from
  1209. i := array_parameters.lower
  1210. until
  1211. i > array_parameters.upper
  1212. loop
  1213. ena ::= array_parameters.item(i)
  1214. Result.add_parameter(expression_no_array(ena, local_context))
  1215. i := i + 1
  1216. end
  1217. from
  1218. i := array.content.lower
  1219. until
  1220. i > array.content.upper
  1221. loop
  1222. exp ::= array.content.item(i)
  1223. Result.add_content(expression(exp, local_context), expression_separator(exp))
  1224. i := i + 1
  1225. end
  1226. ensure
  1227. not errors.has_error implies Result /= Void
  1228. end
  1229. feature {}
  1230. list_parameters (parameters: EIFFEL_LIST_NODE; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT) is
  1231. local
  1232. i, j: INTEGER; declaration: LIBERTY_AST_DECLARATION; variable: LIBERTY_AST_VARIABLE
  1233. typedef: LIBERTY_TYPE; parameter: LIBERTY_PARAMETER
  1234. do
  1235. if not parameters.is_empty then
  1236. from
  1237. i := parameters.lower
  1238. until
  1239. i > parameters.upper
  1240. loop
  1241. declaration ::= parameters.item(i)
  1242. typedef := type_lookup.resolver.type(declaration.type_definition)
  1243. if typedef /= Void then
  1244. from
  1245. j := declaration.variables.lower
  1246. until
  1247. j > declaration.variables.upper
  1248. loop
  1249. variable ::= declaration.variables.item(j)
  1250. create parameter.make(variable.variable.image.image.intern, typedef, errors.semantics_position(variable.variable.image.index, ast, file))
  1251. local_context.add_parameter(parameter)
  1252. j := j + 1
  1253. end
  1254. end
  1255. i := i + 1
  1256. end
  1257. end
  1258. end
  1259. list_locals (locals: LIBERTY_AST_LOCAL_BLOCK; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT) is
  1260. local
  1261. i, j: INTEGER; declaration: LIBERTY_AST_DECLARATION; variable: LIBERTY_AST_VARIABLE
  1262. typedef: LIBERTY_TYPE; localdef: LIBERTY_LOCAL
  1263. do
  1264. if locals.list_count > 0 then
  1265. from
  1266. i := locals.list_lower
  1267. until
  1268. i > locals.list_upper
  1269. loop
  1270. declaration := locals.list_item(i)
  1271. typedef := type_lookup.resolver.type(declaration.type_definition)
  1272. if typedef /= Void then
  1273. from
  1274. j := declaration.variables.lower
  1275. until
  1276. j > declaration.variables.upper
  1277. loop
  1278. variable ::= declaration.variables.item(j)
  1279. create localdef.make(variable.variable.image.image.intern, typedef, errors.semantics_position(variable.variable.image.index, ast, file))
  1280. local_context.add_local(localdef)
  1281. j := j + 1
  1282. end
  1283. end
  1284. i := i + 1
  1285. end
  1286. end
  1287. end
  1288. feature {}
  1289. create_instruction_call (a_target: LIBERTY_EXPRESSION; a_entity: LIBERTY_FEATURE_ENTITY; a_actuals: COLLECTION[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CALL_INSTRUCTION is
  1290. do
  1291. create Result.make(a_target, a_entity, a_actuals, a_position)
  1292. end
  1293. create_implicit_instruction_call (a_entity: LIBERTY_FEATURE_ENTITY; a_actuals: COLLECTION[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_CALL_INSTRUCTION is
  1294. do
  1295. create Result.implicit_current(a_entity, a_actuals, a_position)
  1296. end
  1297. create_expression_call (a_target: LIBERTY_EXPRESSION; a_entity: LIBERTY_FEATURE_ENTITY; a_actuals: COLLECTION[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): LIBERTY_CALL_EXPRESSION is
  1298. do
  1299. create Result.make(a_target, a_entity, a_actuals, a_position)
  1300. end
  1301. create_implicit_expression_call (a_entity: LIBERTY_FEATURE_ENTITY; a_actuals: COLLECTION[LIBERTY_EXPRESSION]; a_position: LIBERTY_POSITION): LIBERTY_CALL_EXPRESSION is
  1302. do
  1303. create Result.implicit_current(a_entity, a_actuals, a_position)
  1304. end
  1305. feature {} -- Assertions
  1306. empty_feature_assertions: COLLECTION[LIBERTY_ASSERTION] is
  1307. once
  1308. create {FAST_ARRAY[LIBERTY_ASSERTION]} Result.with_capacity(0)
  1309. end
  1310. feature_assertions (assertions: LIBERTY_AST_LIST[LIBERTY_AST_ASSERTION]; local_context: LIBERTY_FEATURE_LOCAL_CONTEXT): COLLECTION[LIBERTY_ASSERTION] is
  1311. require
  1312. assertions /= Void
  1313. local_context /= Void
  1314. local
  1315. i: INTEGER; assertion: LIBERTY_AST_ASSERTION
  1316. tag: FIXED_STRING; exp: LIBERTY_EXPRESSION
  1317. do
  1318. if assertions.list_count = 0 then
  1319. Result := empty_feature_assertions
  1320. else
  1321. create {FAST_ARRAY[LIBERTY_ASSERTION]} Result.with_capacity(assertions.list_count)
  1322. from
  1323. i := assertions.list_lower
  1324. until
  1325. errors.has_error or else i > assertions.list_upper
  1326. loop
  1327. assertion := assertions.list_item(i)
  1328. if assertion.expression.has_expression then
  1329. if assertion.tag.has_tag then
  1330. tag := assertion.tag.tag.image.image.intern
  1331. else
  1332. tag := Void
  1333. end
  1334. if assertion.expression.has_expression then
  1335. exp := expression(assertion.expression.expression, local_context)
  1336. Result.add_last(create {LIBERTY_ASSERTION}.make(tag, exp))
  1337. end
  1338. end
  1339. i := i + 1
  1340. end
  1341. end
  1342. end
  1343. feature {}
  1344. type: LIBERTY_ACTUAL_TYPE is
  1345. deferred
  1346. ensure
  1347. Result /= Void
  1348. end
  1349. native_array_of_character: LIBERTY_ACTUAL_TYPE is
  1350. once
  1351. Result := universe.type_native_array({FAST_ARRAY[LIBERTY_ACTUAL_TYPE] << universe.type_character >> }, errors.unknown_position)
  1352. end
  1353. end -- class LIBERTY_SEMANTICS_BUILDER