0

I have a collection of nodes of concept Command that I'm iterating over with a $LOOP$ macro. Command is an abstract concept. I have defined templates and reduction rules for concrete subconcepts, such as Outline:

template tpl_Outline
input    Outline

...

and

reduction rules:
  [concept    Outline ] --> tpl_Outline
  [inheritors false   ]
  [condition  <always>]

Question: How would I invoke the appropriate generator rule for the concrete concept from inside the $LOOP$ macro where the nodes are only known to be of the abstract type Command?

[EDIT] Since the proposed answer is specific to looping over a collection of elements, how would I do the same when there's no looping? That is, how to trigger the configured rule for a given node (e.g. a certain child of the current node).

Note 1: I tried using just $LOOP$[null], hoping for the element nodes to be processed by appropriate rules automatically, but that just produced nulls in the output.

Note 2: I tried $LOOP[$COPY_SRC$[null]], but that produced

textgen error: 'No textgen for Draw.structure.Outline' in [actualArgument] Outline null[847086916111387210] in Draw.sandbox@0

[EDIT 2] This is actually a working solution. What helped was probably invalidating the caches (just Rebuild Project was not working).

Note 3: Previously I used a template switch to call an appropriate template based on concrete concept, but I now want to support custom extensions of Command so I can no longer create an exhaustive template switch.

Tomas Mikula
  • 6,537
  • 25
  • 39
  • 1
    regarding note 3 you can define a template switch, no the inline one, it has a name and other generators can extend this switch by referencing it. That way the switch will become exhaustive at runtime because the contributed extensions are also considered. – Kolja Jul 09 '18 at 16:14
  • 1
    The problem with invalidating caches is usually caused by the fact that your language had no textgen aspect, you added one but it wasn't invoked. This seems to be a issue inside of MPS were it caches language descriptors to eagerly. – Kolja Jul 09 '18 at 16:17

2 Answers2

1

Try using $COPY_SRCL$ (L stands for Loop here), this macro is designed exactly for your situation. Also, template switches are extensible

  • Thanks! This indeed works, but right away I encountered a case where I need to do the same (i.e. invoke configured template) for a single node (i.e. without a loop). I find it strange that `$COPY_SRC$` has different behavior and gives me the `No textgen for ...` error. – Tomas Mikula Jul 09 '18 at 12:55
  • Regarding extensibility of switches, I would then also have to override all the places where the original switch was invoked in order to use the new one, right? Ideally, this would just be a single template, but then I'm still back to the problem of how to invoke the configured template for a node of a given concept. – Tomas Mikula Jul 09 '18 at 13:05
  • 1
    This error seems strange, it should not appear. Please check if you did those things: 1) You have specified the correct node in the inspector of the COPY_SRC 2) You have rebuilt the generator. Regarding the switch: you invoke the single switch. And then the user who wants to extend your language can extend this switch. Then in the process of the generation MPS will choose the correct switch case from both of the switches based on the node's concept – Simon Alperovich Jul 09 '18 at 15:02
  • I was doing _Build_ -> _Rebuild Project_, but that didn't help. What helped was when I checked out a different git branch and then returned to the original branch and did a Rebuild. Now `$COPY_SRC$` behaves as expected and even my attempt from "Note 2" works. – Tomas Mikula Jul 09 '18 at 15:29
1

Regarding your Build --> Rebuild Project problem: sometimes File --> Invalidate caches can help to resolve such problems.

Eugen Schindler
  • 351
  • 1
  • 6