PageRenderTime 32ms CodeModel.GetById 14ms app.highlight 10ms RepoModel.GetById 0ms app.codeStats 1ms

/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

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

Large files files are truncated, but you can click here to view the full file