Typesystem extension: duck typing/operator overloading

Hi there,

I'm a bit lost with my problem, so I hope someone can help me.

Currently I'm trying to learn more about MPS, so I'm fiddling around with the existing languages, trying to extend them.

My plan was to implement some sort of operator overloading for the base language in a way, that you define all operators of a class just within that class, e.g. like:

public MyClass {
int i = 0;

MyClass operator ++ () {
   this.i++;
   return this;
}
}

You would basically get some kind of duck typing for operators: as long as a class implements a certain operator, the operator can be applied to this class.

I already extended the ClassConcept node (with my own ExtClassConept node) to allow operator definitions, and I already implemented the translation from the operator definition to a function in plain Java code, so that you'll get for the above example:

public MyClass {
int i = 0;

MyClass _operator_inc () {
   this.i++;
   return this;
}
}

Now my problem is, that I need to modify the base languages type system to accept code like this:

MyClass c;
c += 1;

I thought about creating e.g. a new PostIncrementExpression node, which extends the existing PostfixIncrementExpression node, but overrides its type checking.

But honestly: I have NO idea of how to exactly do this. In theory, I first have to check if the type of the nodes expression is a class that is based on the ExtClassConcept (like MyClass in the example above) and if this is true, I have to search the operator list of the class declaration for an increment operator node. However, if the expression type is not based on ExtClassConcept (e.g. if it is a plain int) or if it has no increment operator, the usual type checking (for Numerical types) should apply.

Does anyone have any idea how to accomplish this?

Any help would be highly appreciated. ;)
1 comment
Comment actions Permalink
I'm not sure if we're talking about the same here. ;)

Let me try to explain my current issue from scratch, without unnecessary stuff, just to be sure I'm not wasting your time:

I added two new concepts to my project (which extends baseLanguage), MyClassConcept (extending baseLanguage.ClassConcept) and MyExpression (extending baseLanguage.Expression).

MyClassConcept can be used like a common class declaration in Java, thus instances of a MyClassConcept instantiation may be used in normal expressions.

Then I added an inference rule for MyExpression which first shall check if the concept of its expressions type is MyClassConcept (or a derived concept); if this is the case, the rule shall check if the actual type of the expression (being an instantiation of the MyClassConcept concept) meets certain conditions (like implementing a certain method) and then use a dynamically determined type (based on the actual expression type and the conditions, like the return type of an implemented method) as inferred type of the rule.

To accomplish this, here is my question:

How can I get the concept that a node is based on (e.g. the node "typeof(operation.expression)") within an inference rule (would that be "typeof(operation.expression).concept"?) and how can I compare that dynamically derived concept to a statically known one? Quotations don't seem to be a solution, because they create concrete instances of a concept (if I understood that correctly), but I require a comparison with the concept itself, not an instance of it.

Neither "operation.expression.concept == concept/MyClassConcept/" nor "typeof(operation.expression).concept == concept/MyClassConcept/" is working, although this expressions _seem_ to be what I want (obviously, they are not - is there any in-depth documentation about the whole system and those, well, concepts like concept//, name//, typeof, isInstanceOf, n.concept etc.?)

Any answers or suggestions would be great! ;)
0

Please sign in to leave a comment.