creating variables with one time assignment (like C++ references)

Hi,

I want to create variables in MPS which can be assigned only one time during runtime (in the solution),

so I would like to have something like C++ references (not C++ consts).

Can you point me to how to implement this in MPS (maybe a short example).

I assume I need constraints but am not sure if/what else,

thanks,

Bernhard.

7 comments
Comment actions Permalink

For solving your problem you can do the following:

  1. Create ReadOnlyLocalVariableDeclaration concept extending LocalVariableDeclaration.
  2. Create ReadOnlyLocalVariableReference concept extending Expression.

If you do it, your read-only variables will be able to be initialized only once — in their declarations. Variable references will be readable, but not writable (unless you set lvalue concept property for ReadOnlyLocalVariableReference).

0
Comment actions Permalink

Hi Evgeny,

thanks for your help so far. I think I should have explained it a bit more specific (sorry...)

I have to initialize them only once but not neccesarily in their delcaration (so it is not exactly like C++ references)

As an example think of a sensor which I want to calibrate (to its environment).

I want the calibration value to be like a const, however I have to compute this value during e.g. startup/runtime of the program only once and then set it.(and it shall not be modified afterwards)

The assignment may not be necessarily in the declaration...

So what do I have to do additionally ?

thanks,

Bernhard.

0
Comment actions Permalink

Ah, I see. I didn't understand your correctly.

There is a similar behavior implementated for final variables in baseLanguage. I mean, if you try to assign final variables more than once, it will be marked as error in editor.

Look at check_FinalVariableReferenceNotAssigned non-typesystem rule for implementation details. I hope, this example will help you.

0
Comment actions Permalink

Great ! thanks so much for your help :-)


0
Comment actions Permalink

I searched "ModulesPool-->Languages->jetbrains->mps->baseLanguage->typesystem"

but did not find check_FinalVariableReferenceNotAssigned in any of the nodes (tab Typesystem)

what am I missing ?

0
Comment actions Permalink

I'm working with repository version of MPS and I didn't think that this non-typesystem rule is not present in MPS 1.1. So, I will try to explain how it is implemented myself soon.

0
Comment actions Permalink

check_FinalVariableReferenceNotAssigned is non-typesystem rule for VariableReference, which checks unicity of assignment to final variable. So, it is the same thing you need in your case. It uses isUninitializedOrBad() method from its behavior.

Here is the body of this behavior method:

public boolean isUninitializedOrBad() {

  node<IStatementListContainer> declContainer = this.variableDeclaration.ancestor<concept = IStatementListContainer>;
  if (declContainer == null) { return true; }
  node<IStatementListContainer> currentContainer = this.ancestor<concept = IStatementListContainer>;
  node<IStatementListContainer> ourContainer = null;
    
  node<AssignmentExpression> assignmentExpression = this.parent as AssignmentExpression;
  if (assignmentExpression.lValue != this) { return true; }
    
  while (currentContainer.isNotNull) {
    if (currentContainer == declContainer) {
      ourContainer = currentContainer;
      break;
    }
    currentContainer = currentContainer.ancestor<concept = IStatementListContainer>;
  }
  if (ourContainer.isNotNull) {
    Program program = DataFlowManager.getInstance().buildProgramFor(ourContainer);
    return !(DataFlow.isInitializedRewritten(program, assignmentExpression));
  } else {
    return true;
  }

}

As you can see, this method uses data flow mechanism to find multiple assignment to final variable.

As I have already said, this check is not available in MPS 1.1, but it will be present in next MPS release.

0

Please sign in to leave a comment.