Assigning values to concept properties
I have a language which extends BaseLanguage.
I've defined a concept which has several properties.
This concept is represented by its name (it extends INamedConcept) as its properties values should be initiated by an external code.
I've followed the generic guide-lines on "how extend the DotExpression with references to your own concepts" created by Vaclav Pech: https://confluence.jetbrains.com/display/MPSD32/Common+language+patterns#Commonlanguagepatterns-ExtendingtheDotExpressionforyourownreferences
This enabled me to refer to the concept properties values, e.g. in an ifStatement.
I also want to be able to assign values to those properties.
Therefore I've defined a concept reference for each property, which extends VariableReference and has my original concept in its "references:" section.
e.g. my original concept is
concept Person extends BaseConcept
implements INamedConcept
properties:
name : string
age : integer
credit : integer
and the reference concept for the credit property:
concept PersonCreditVarRef extends VariableReference
implements <none>
person : Person[1]
and the editor for the reference concept:
[- ( % person % -> { name } ) .credit -]
I've also created an inference rule for it:
typeof(personCreditVarRef) :==: <int>;
In the sandbox I have:
myPerson
if (myPerson.age > 65) {
myPerson .credit = 60;
} else
myPerson .credit = 50;
}
and there are errors for the assignment:
"Error: No reference in role "variableDeclaration" (declared cardinality is 1)"
"Incompatible types: int and null" although if you check the node explorer you see that myPerson .credit is identified as PersonCreditVarRef and that its type is {int}
The first error is probably due to the fact that the reference concept extends VariableReference which has variableDeclaration [1] in its reference section.
So extending VariableReference is not the way to do this?
I'm sure there's an easy way to achieve assignment to properties (hopefully without having to create a separate concept reference for each property), I just don't know how to do this and would appreciate any help.
I've defined a concept which has several properties.
This concept is represented by its name (it extends INamedConcept) as its properties values should be initiated by an external code.
I've followed the generic guide-lines on "how extend the DotExpression with references to your own concepts" created by Vaclav Pech: https://confluence.jetbrains.com/display/MPSD32/Common+language+patterns#Commonlanguagepatterns-ExtendingtheDotExpressionforyourownreferences
This enabled me to refer to the concept properties values, e.g. in an ifStatement.
I also want to be able to assign values to those properties.
Therefore I've defined a concept reference for each property, which extends VariableReference and has my original concept in its "references:" section.
e.g. my original concept is
concept Person extends BaseConcept
implements INamedConcept
properties:
name : string
age : integer
credit : integer
and the reference concept for the credit property:
concept PersonCreditVarRef extends VariableReference
implements <none>
person : Person[1]
and the editor for the reference concept:
[- ( % person % -> { name } ) .credit -]
I've also created an inference rule for it:
typeof(personCreditVarRef) :==: <int>;
In the sandbox I have:
myPerson
if (myPerson.age > 65) {
myPerson .credit = 60;
} else
myPerson .credit = 50;
}
and there are errors for the assignment:
"Error: No reference in role "variableDeclaration" (declared cardinality is 1)"
"Incompatible types: int and null" although if you check the node explorer you see that myPerson .credit is identified as PersonCreditVarRef and that its type is {int}
The first error is probably due to the fact that the reference concept extends VariableReference which has variableDeclaration [1] in its reference section.
So extending VariableReference is not the way to do this?
I'm sure there's an easy way to achieve assignment to properties (hopefully without having to create a separate concept reference for each property), I just don't know how to do this and would appreciate any help.
Please sign in to leave a comment.
"Error: unexpected in left part or assignment"
I think this error is because if I extend Expression then the assignment is not a Statement and ifStatement expects Statement (only ifStatement condition is an Expression).
You need to override the lvalue() behaviour method for your reference:
public static boolean lvalue() overrides Expression.lvalue { return true; }"unexpected in left part or assignment"
This error origin is the check_BaseAssignmentExpression rule which checks the isLValue() method.
So I've overridden the isLValue() method too:
public boolean isLValue()
overrides Expression.isLValue {
return true;
}
Yet even though I've rebuilt my Language I still get the same error ("unexpected in left part or assignment").
I think I'm not extending Expression correctly. How should such a reference concept look like?
and the behaviour:
concept behavior ItemReference { constructor { <no statements> } public static boolean lvalue() overrides Expression.lvalue { true; } }I can't see a problem in your code, but perhaps I'm missing some part.
https://youtrack.jetbrains.com/issue/MPS-22154
The left side of the assignment contains the DotExpression from BaseLanguage and thus its isLValue() gets called:
public boolean isLValue()
overrides Expression.isLValue {
this.operation.isLValue();
}
The DotExpression calls isLValue() on the operation, which is PersonCreditOperation - this concept needs to override the isLValue() or lvalue() behaviour methods.