Community
Participate
Working Groups
/org.eclipse.qvtd.cs2as.compiler.tests/src/org/eclipse/qvtd/cs2as/compiler/tests/models/example4 has a simple metamodel with unit multiplicity containment. The Composition descent in the schedule needs a 0/1 if test to guard the nested call. It can be fudged by a MappingLoop over 0/1 element, but it's not very elegant.
Bug 500369 suggests a QVTi to QVTa migration. An IfStatement naturally forms part of a testing capability for e.g. a TypeCheckPredicate.
Migrating get dependencies from a domain-level checkingProperties to an AccessStatement requires an IF to enable the AccessStatement to be on a conditional path. This in turn requires the very strong SSA characteristic of all variables are initialized at the point of declaration to be weakened to initialized exactly once before use, allowing declaration outside an IF, with variant initialization inside the IF. This is relatively straightforward in the interpreter but is harder in the CG. For now an 'observe' capability per-statement avoids the need for domains and can probably be narrowed by multiple intermediate temporaries. WIP on IF etc on ewillink/480194
(In reply to Ed Willink from comment #0) > The Composition descent in the schedule needs a 0/1 if test to guard the > nested call. Does it? Surely it can just be invoked and the "check" qualifier will perform the type check automatically.
Bug 506806 demonstrates that conditional execution is mandatory to avoid var csElseIsNull : Boolean[1] := csElse = null; var asElse : astm::Visitable := csElse.ast; var asElse2 : astm::Visitable := if csElseIsNull then null else asElse evaluating csElse.ast when csElse is null. Must do var csElseIsNull : Boolean[1] := csElse = null; var asElse2 : astm::Visitable; if (if csElseIsNull) { asElse2 := null; } else { var asElse : astm::Visitable := csElse.ast; asElse2 := asElse; } We can require a strong exactly-once-on-each-path assignment rule.
(In reply to Ed Willink from comment #4) > Bug 506806 demonstrates that conditional execution is mandatory to avoid The actual Bug 506806 problem was inaccurate analysis of the conditional sub-graphs. Yet another abortive attempt at introducing (CG)IfStatement(CS) is therefore on ewillink/480194a.
An if capability would be needed if we need to be able to implement a single mapping override dispatcher. See Bug 515327.
Two convincing use cases, both soluble inefficiently by multiple mappings with distinct matches. a) merge optimization Given two similar micromappings M1, M2, it may be appropriate to merge them. It may then be necessary to: if (...isM1...) then new-statements of m1 else new-statements of M2 endif. b) recursion termination Given a recursion it may be appropriate to: if (...recursion-done...) then new-statements of end case else new-statements of recursion case recursive call endif Arguably the if-statement is procedual so an else may be redundant. Probably easier to mandate a perhaps empty else in the CS/AS.
A related use case comes from a need to provide a try-catch handler so that what happens following a failure is programmed rather than magically built-in.
(In reply to Ed Willink from comment #7) > a) merge optimization > > Given two similar micromappings M1, M2, it may be appropriate to merge them. This is exactly what is necessary to optimize the override dispatch so that instead of one activator per override creating one derived trace per override and all but one subsequent executions failing, the first stage of each override can be merged to share control variables, create just one trace and execute just one path. While this could be done as a magic bit of CG for a connection dispatcher, that requires considerable insight in the CG. The QVTs graphical visualization has been consistently useful, so better to allow a QVTs merge. This also may offer 'single step' visual debugging. The challenge is providing a conditional control on green edges/nodes. Simplistic extra control edges could be very klunky. A sub-region with a guard could be clearer. The guards could come from conventional and/not logic but each elseif level requires two ands and a not; again klunky. Perhaps a 2-input enable+condition, 2-output then+else diamond. The Boolean enable input is routed to then/else by the Boolean condition input.
(In reply to Ed Willink from comment #9) > Perhaps a 2-input enable+condition, 2-output then+else diamond. Multi-semantic graphical inputs will be confusing. Perhaps an arbitrary number of enable inputs that are and-ed together and a single fail output per sub-region. The fail output can contribute to daisy-chain successors. QVTs: a new graphical sub-region - relatively straightforward. QVTi: a new IfStatement - relatively straightforward. CG: a new IfStatement - relatively straightforward. QVTs2QVTi the sub-region control is reified as boolean expressions. QVTi2Java, the main challenge is the CSE that we need to correctly exploit the shared code. The CSE is poorly documented/hard to understand. Perhaps this can be an early vehicle for auto-generated code. --- The efficient Dispatch region is 'just' the current inefficient realize-all-possible-traces with the local predicate partition for each possuble trace folded into a sub-region with its realize. The sub-regions are linked according to the overrides relationships. If we hoist common code at the QVTs-level, CSE at the CG level can be deferred.
Bug 546617 allows unique activator regions to be folded as unique trace variables.
Surely IfStatement can be adequately emulated by let dummy = if cond-exp then true-exp else false-exp endif in ... No need for syntax bloat.