From 1898115f8bf5c5f64d45d532296ff36a7c07d86a Mon Sep 17 00:00:00 2001 From: Kenneth Lausdahl Date: Thu, 28 Aug 2014 16:10:44 +0200 Subject: [PATCH] fixed #294 change the way mapvalue and valuemap is handled+obtained in compass such that they now are subject to the delay mechanism --- .../interpreter/CmlExpressionVisitor.java | 53 +++++++++++++++- .../values/DelayedUpdatableWrapper.java | 60 +++++++++++++++---- .../src/test/resources/issues/issue-294.cml | 19 ++++++ .../test/resources/issues/issue-294.result | 9 +++ 4 files changed, 128 insertions(+), 13 deletions(-) create mode 100644 core/interpreter/src/test/resources/issues/issue-294.cml create mode 100644 core/interpreter/src/test/resources/issues/issue-294.result diff --git a/core/interpreter/src/main/behaviour/eu/compassresearch/core/interpreter/CmlExpressionVisitor.java b/core/interpreter/src/main/behaviour/eu/compassresearch/core/interpreter/CmlExpressionVisitor.java index 9a3426b55..9fbf944f0 100644 --- a/core/interpreter/src/main/behaviour/eu/compassresearch/core/interpreter/CmlExpressionVisitor.java +++ b/core/interpreter/src/main/behaviour/eu/compassresearch/core/interpreter/CmlExpressionVisitor.java @@ -16,9 +16,11 @@ import org.overture.ast.statements.PStm; import org.overture.interpreter.eval.DelegateExpressionEvaluator; import org.overture.interpreter.runtime.Context; +import org.overture.interpreter.runtime.ObjectContext; import org.overture.interpreter.runtime.ValueException; import org.overture.interpreter.runtime.VdmRuntime; import org.overture.interpreter.runtime.VdmRuntimeError; +import org.overture.interpreter.values.MapValue; import org.overture.interpreter.values.NameValuePair; import org.overture.interpreter.values.NameValuePairList; import org.overture.interpreter.values.OperationValue; @@ -27,6 +29,7 @@ import org.overture.interpreter.values.SetValue; import org.overture.interpreter.values.Value; import org.overture.interpreter.values.ValueList; +import org.overture.interpreter.values.ValueMap; import org.overture.interpreter.values.ValueSet; import eu.compassresearch.ast.analysis.QuestionAnswerCMLAdaptor; @@ -51,6 +54,8 @@ import eu.compassresearch.core.interpreter.api.values.LatticeTopValue; import eu.compassresearch.core.interpreter.api.values.NameValue; import eu.compassresearch.core.interpreter.api.values.RenamingValue; +import eu.compassresearch.core.interpreter.runtime.DelayedWriteContext; +import eu.compassresearch.core.interpreter.runtime.DelayedWriteObjectValue; public class CmlExpressionVisitor extends QuestionAnswerCMLAdaptor @@ -120,14 +125,56 @@ public Value caseAApplyExp(AApplyExp node, Context ctxt) { try { - Value object = node.getRoot().apply(VdmRuntime.getExpressionEvaluator(), ctxt).deref(); + final Value objectRefed = node.getRoot().apply(VdmRuntime.getExpressionEvaluator(), ctxt); + Value object = objectRefed.deref(); if (object instanceof OperationValue) { return StatementInspectionVisitor.invokeOperation(node.getLocation(),node, node.getArgs(), ctxt, (OperationValue)object, this); - } else + } else if(object instanceof MapValue) { - return super.caseAApplyExp(node, ctxt); + Context lCtxt = ctxt; + if(ctxt instanceof ObjectContext) + { + DelayedWriteContext delayedCtxt = null; + Context tmp = lCtxt; + + while (tmp != null) + { + if (tmp instanceof DelayedWriteContext) + { + if (!((DelayedWriteContext) tmp).isDisabled()) + { + delayedCtxt = (DelayedWriteContext) tmp; + + break; + } + } + tmp = tmp.outer; + } + + if(delayedCtxt !=null) + { + //we have to wrap the object context + lCtxt =new ObjectContext(ctxt.assistantFactory, ctxt.location, ctxt.title, ctxt.outer, new DelayedWriteObjectValue(((ObjectContext)lCtxt).self, delayedCtxt)); + } + } + + Value arg = node.getArgs().get(0).apply(VdmRuntime.getExpressionEvaluator(), ctxt); +// MapValue mv = (MapValue) object; +// return mv.lookup(arg, ctxt); + ValueMap mval = objectRefed.mapValue(lCtxt); + + Value v = mval.get(arg); + + if (v == null) + { + throw new ValueException(4061, "No such key value in map: " + arg, ctxt); + } + + return v; + //return super.caseAApplyExp(node, lCtxt); } + return super.caseAApplyExp(node, ctxt); } catch (ValueException e) { return VdmRuntimeError.abort(node.getLocation(), e); diff --git a/core/interpreter/src/main/java/org/overture/interpreter/values/DelayedUpdatableWrapper.java b/core/interpreter/src/main/java/org/overture/interpreter/values/DelayedUpdatableWrapper.java index 740472441..9b2bc9e9f 100644 --- a/core/interpreter/src/main/java/org/overture/interpreter/values/DelayedUpdatableWrapper.java +++ b/core/interpreter/src/main/java/org/overture/interpreter/values/DelayedUpdatableWrapper.java @@ -1,5 +1,7 @@ package org.overture.interpreter.values; +import java.util.Map.Entry; + import org.overture.ast.analysis.AnalysisException; import org.overture.ast.intf.lex.ILexLocation; import org.overture.ast.lex.Dialect; @@ -28,7 +30,13 @@ public class DelayedUpdatableWrapper extends UpdatableValue ILexLocation newLoc = null; Context newContext = null; - protected DelayedUpdatableWrapper(Value value, ValueListenerList listeners, PType type) + /** + * Value maps obtained through {@link DelayedUpdatableWrapper#mapValue(Context)} + */ + ValueMap obtainedMaps = null; + + protected DelayedUpdatableWrapper(Value value, ValueListenerList listeners, + PType type) { super(value, listeners, type); this.original = value; @@ -38,17 +46,15 @@ public DelayedUpdatableWrapper(UpdatableValue val) { this(val, val.listeners, val.restrictedTo); } - - protected DelayedUpdatableWrapper(Value value, ValueListenerList listeners, PType type,Value original, ILexLocation newLoc,Context newContext) + + protected DelayedUpdatableWrapper(Value value, ValueListenerList listeners, + PType type, Value original, ILexLocation newLoc, Context newContext) { super(value, listeners, type); this.original = original; this.newLoc = newLoc; this.newContext = newContext; } - - - @Override public void set(ILexLocation location, Value newval, Context ctxt) @@ -86,13 +92,14 @@ public void set(ILexLocation location, Value newval, Context ctxt) listeners.changedValue(location, value, ctxt); } - /* Useful for debugging, but we don't want to ship with this on. */ + /* Useful for debugging, but we don't want to ship with this on. */ // System.err.println("Setting value(" + toShortString(10) + ") to " - // + newval); + // + newval); } /** * Write transactional value to the original value + * * @throws ValueException * @throws AnalysisException */ @@ -100,11 +107,44 @@ public void set() throws ValueException, AnalysisException { original.set(newLoc, value, newContext); } - + + @Override + public synchronized ValueMap mapValue(Context ctxt) throws ValueException + { + ValueMap m = null; + if (obtainedMaps == null) + { + m = super.mapValue(ctxt); + } else + { + return obtainedMaps; + } + if (m != null) + { + ValueMap mWrapper = new ValueMap(); + + for (Entry entry : m.entrySet()) + { + if (entry.getValue() instanceof UpdatableValue) + { + mWrapper.put(entry.getKey(), new DelayedUpdatableWrapper((UpdatableValue) entry.getValue())); + } else + { + mWrapper.put(entry.getKey(), entry.getValue()); + } + } + obtainedMaps = mWrapper; + this.value = new MapValue(obtainedMaps); + return obtainedMaps; + } + + return m; + } + @Override public synchronized Object clone() { - return new DelayedUpdatableWrapper((Value)value.clone(), listeners, restrictedTo,original,newLoc,newContext); + return new DelayedUpdatableWrapper((Value) value.clone(), listeners, restrictedTo, original, newLoc, newContext); } } diff --git a/core/interpreter/src/test/resources/issues/issue-294.cml b/core/interpreter/src/test/resources/issues/issue-294.cml new file mode 100644 index 000000000..e1fb6df74 --- /dev/null +++ b/core/interpreter/src/test/resources/issues/issue-294.cml @@ -0,0 +1,19 @@ +channels + ping : nat + pair : nat * nat + +process TEST = begin +state + simple : map nat to nat := {1 |-> 0} +actions + TOP = A(1) ||| A(2) + A = val x : nat @ + pair!x!(simple(1)) -> + simple(1) := x; + pair!x!(simple(1)) -> + Skip +@ ping!(simple(1)) -> + TOP; + ping!(simple(1)) -> + Skip +end \ No newline at end of file diff --git a/core/interpreter/src/test/resources/issues/issue-294.result b/core/interpreter/src/test/resources/issues/issue-294.result new file mode 100644 index 000000000..7b8b9128c --- /dev/null +++ b/core/interpreter/src/test/resources/issues/issue-294.result @@ -0,0 +1,9 @@ + + + + FINISHED + + ping.0,pair.(\d).0,(pair.\1.\1,pair.(\d).0,pair.\3.\3,|pair.(\d).0,(pair.\1.\1,pair.\4.\4,|pair.\4.\4,pair.\1.\1,)) +ping.0 + +