sacko87
sacko87

Reputation: 143

Overloading code generators in Xtext

I have a very simple DSL that consists of a validator element that contains a list of comparators:

Validator:
  'validator' name = ID '{'
    comparisons+=Comparison*
  '}'
;

Comparison:
  LessThan | GreaterThan | EqualTo
;

LessThan:
  'lt' value = INT
;

With this I am trying to generate C code. Where I loop through each validator, create a C file (based on the name of the validator) and place the comparators into a ternary conditional statement. When I loop though each comparator it calls a definition for the class Comparison which outputs the if statement. A cut down example (outputs something similar to CPPUNIT):

int
main(int argc, char **argv)
{
  // parse argv[1] if it exists -> place into i
  printf("%c", i < (comparator_value_1) ? '.' : 'F');
  printf("%c", i > (comparator_value_2) ? '.' : 'F');
  printf("\n");
  return 0;
}

I can get all of this working nicely; however the problem I am having is that I seem to have to do a selection of conditionals within my Comparison generator. I seem unable to override the generator by adding a handler for LessThan.

def compile(Comparison c) '''
  printf("%c",
    i «IF c.eClass.name.equals("LessThan")»...«ENDIF» «c.value»
      ? '.' : 'F');
'''

When I attempt to overload it:

def compile(LessThan lt) '''
  printf("%c", i < «c.value» ? '.' : 'F');
  ...
'''

The overloaded routines don't get called, which is at best unfortunate.

It is called by if this makes any difference:

«FOR c:v.comparisons»
  «c.compile»
«ENDFOR»

Where 'v' is the Validator.

Does Xtext have this ability?

Upvotes: 1

Views: 435

Answers (1)

sacko87
sacko87

Reputation: 143

Xtext can use polymorphic dispatch (courtesy of @SpaceTrucker) in which:

a function or method can be dynamically dispatched based on the run time (dynamic) type of more than one of its arguments.

In order to use this functionality I had to add one word to it dispatch.

def dispatch expandComparator(GreaterThan gt) '''
    printf("%c", i < «gt.value» ? '.' : 'F');
'''

def dispatch expandComparator(EqualTo eq) '''
    printf("%c", i == «eq.value» ? '.' : 'F');
'''

def dispatch expandComparator(LessThan lt) '''
    printf("%c", i < «lt.value» ? '.' : 'F');
'''

And use the following to generate it:

«FOR c:v.comparisons»
    «c.expandComparator»
«ENDFOR»

The name of the function had to change as compile was a single dispatch function.

The following link has more details on this solution. http://dslmeinte.wordpress.com/2012/08/03/polymorphic-dispatch-in-xtend/

Upvotes: 1

Related Questions