Reputation: 143
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
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