2

Is there a way to select the head of a list of an optional term while transforming such that if it exists you get the element else you get an empty string or the result of calling the function doesn't return anything? For example, if you had the ADT:

data TakeAction = set(list[OptVal] opt, str expandedId, NumVal numVal)

which corresponded with the syntax:

syntax TakeAction = set: SET OptVal? EXPANDEDID NumVal

and you try to write a function like so:

public str prettyTakeAction(TakeAction::set(list[OptVal] opt, str expandedId, NumVal numVal)) = "SET <prettyOptVal(opt)><expandedId> = <prettyNumVal(numVal)>";

where

public str prettyOptVal(OptVal::optVal()) = "OPTIONAL"

When I try this out, If I omit the OPTIONAL, I get an error, for example

SET a = 8 will throw an error, while SET OPTIONAL a = 3 will work

Wayne
  • 65
  • 7

1 Answers1

2

At the moment we do not have a very clean solution for this but the following hack is being used.

The idea is to (mis?)use the enumeration operator (<-) that will succeed when the option is present and it will fail otherwise. The following tests illustrate this:

syntax OptTestGrammar = A? a B b;

syntax A = "a";
syntax B = "b";

layout L = " "*;

test bool optionalNotPresentIsFalse() = !((A)`a` <- ([OptTestGrammar] "b").a);
test bool optionalPresentIsTrue() = (A)`a` <- ([OptTestGrammar] "ab").a;

This can easily be applied to your example. Hope this solves your problem.

Paul Klint
  • 1,418
  • 7
  • 12
  • I tried to apply this to my use case which uses the ADT and not the concrete syntax but it didn't work. How can I apply this with an ADT model? ```data OptTestGrammar = optTest(list[A] a, B b); data A = aVal(); data B = bVal();``` – Wayne Aug 12 '23 at 11:01
  • 1
    The ADT version also uses list comprehension as follows: `str pretty(optTest(list[A] as, B b)) = pretty(as) + pretty(b); str pretty(aVal()) = "a"; str pretty(bVal()) = "b"; str pretty(list[A] as) = intercalate("", [pretty(a) | a <- as]);` Add an import for `List` to use `intercalate`. An alternative for the last function: `str pretty(list[A] as) = "<}>";` But there are several alternatives to this. – Paul Klint Aug 12 '23 at 12:08