Method: caseATailUnaryExp(ATailUnaryExp, Context)

1: package org.overture.interpreter.eval;
2:
3: import java.util.Collections;
4: import java.util.List;
5:
6: import org.overture.ast.analysis.AnalysisException;
7: import org.overture.ast.expressions.AAbsoluteUnaryExp;
8: import org.overture.ast.expressions.AAnnotatedUnaryExp;
9: import org.overture.ast.expressions.ACardinalityUnaryExp;
10: import org.overture.ast.expressions.ADistConcatUnaryExp;
11: import org.overture.ast.expressions.ADistIntersectUnaryExp;
12: import org.overture.ast.expressions.ADistMergeUnaryExp;
13: import org.overture.ast.expressions.ADistUnionUnaryExp;
14: import org.overture.ast.expressions.AElementsUnaryExp;
15: import org.overture.ast.expressions.AFloorUnaryExp;
16: import org.overture.ast.expressions.AHeadUnaryExp;
17: import org.overture.ast.expressions.AIndicesUnaryExp;
18: import org.overture.ast.expressions.ALenUnaryExp;
19: import org.overture.ast.expressions.AMapDomainUnaryExp;
20: import org.overture.ast.expressions.AMapInverseUnaryExp;
21: import org.overture.ast.expressions.AMapRangeUnaryExp;
22: import org.overture.ast.expressions.ANotUnaryExp;
23: import org.overture.ast.expressions.APowerSetUnaryExp;
24: import org.overture.ast.expressions.AReverseUnaryExp;
25: import org.overture.ast.expressions.ATailUnaryExp;
26: import org.overture.ast.expressions.AUnaryMinusUnaryExp;
27: import org.overture.ast.expressions.AUnaryPlusUnaryExp;
28: import org.overture.interpreter.annotations.INAnnotation;
29: import org.overture.interpreter.debug.BreakpointManager;
30: import org.overture.interpreter.runtime.Context;
31: import org.overture.interpreter.runtime.ContextException;
32: import org.overture.interpreter.runtime.ValueException;
33: import org.overture.interpreter.runtime.VdmRuntime;
34: import org.overture.interpreter.runtime.VdmRuntimeError;
35: import org.overture.interpreter.values.BooleanValue;
36: import org.overture.interpreter.values.MapValue;
37: import org.overture.interpreter.values.NaturalOneValue;
38: import org.overture.interpreter.values.NaturalValue;
39: import org.overture.interpreter.values.NumericValue;
40: import org.overture.interpreter.values.SeqValue;
41: import org.overture.interpreter.values.SetValue;
42: import org.overture.interpreter.values.Value;
43: import org.overture.interpreter.values.ValueList;
44: import org.overture.interpreter.values.ValueMap;
45: import org.overture.interpreter.values.ValueSet;
46:
47: public class UnaryExpressionEvaluator extends LiteralEvaluator
48: {
49:
50:         @Override
51:         public Value caseAAbsoluteUnaryExp(AAbsoluteUnaryExp node, Context ctxt)
52:                         throws AnalysisException
53:         {
54:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
55:
56:                 try
57:                 {
58:                         return NumericValue.valueOf(Math.abs(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).realValue(ctxt)), ctxt);
59:                 } catch (ValueException e)
60:                 {
61:                         return VdmRuntimeError.abort(node.getLocation(), e);
62:                 }
63:         }
64:         
65:         @Override
66:         public Value caseAAnnotatedUnaryExp(AAnnotatedUnaryExp node, Context ctxt)
67:                         throws AnalysisException
68:         {
69:                 if (node.getAnnotation().getImpl() instanceof INAnnotation)
70:                 {
71:                         INAnnotation impl = (INAnnotation)node.getAnnotation().getImpl();
72:                         impl.inBefore(node, ctxt);
73:                 }
74:
75:                 Value result = node.getExp().apply(THIS, ctxt);
76:                 
77:                 if (node.getAnnotation().getImpl() instanceof INAnnotation)
78:                 {
79:                         INAnnotation impl = (INAnnotation)node.getAnnotation().getImpl();
80:                         impl.inAfter(node, result, ctxt);
81:                 }
82:
83:                 return result;
84:         }
85:
86:         @Override
87:         public Value caseACardinalityUnaryExp(ACardinalityUnaryExp node,
88:                         Context ctxt) throws AnalysisException
89:         {
90:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
91:
92:                 try
93:                 {
94:                         return new NaturalValue(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).setValue(ctxt).size());
95:                 } catch (ValueException e)
96:                 {
97:                         return VdmRuntimeError.abort(node.getLocation(), e);
98:                 } catch (ContextException e)
99:                 {
100:                         throw e; // To avoid case below
101:                 } catch (Exception e)
102:                 {
103:                         return VdmRuntimeError.abort(node.getLocation(), 4065, e.getMessage(), ctxt);
104:                 }
105:         }
106:
107:         @Override
108:         public Value caseADistConcatUnaryExp(ADistConcatUnaryExp node, Context ctxt)
109:                         throws AnalysisException
110:         {
111:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
112:
113:                 try
114:                 {
115:                         ValueList seqseq = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt);
116:                         ValueList result = new ValueList();
117:
118:                         for (Value v : seqseq)
119:                         {
120:                                 result.addAll(v.seqValue(ctxt));
121:                         }
122:
123:                         return new SeqValue(result);
124:                 } catch (ValueException e)
125:                 {
126:                         return VdmRuntimeError.abort(node.getLocation(), e);
127:                 }
128:         }
129:
130:         @Override
131:         public Value caseADistIntersectUnaryExp(ADistIntersectUnaryExp node,
132:                         Context ctxt) throws AnalysisException
133:         {
134:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
135:
136:                 try
137:                 {
138:                         ValueSet setset = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).setValue(ctxt);
139:
140:                         if (setset.isEmpty())
141:                         {
142:                                 return VdmRuntimeError.abort(node.getLocation(), 4151, "Cannot take dinter of empty set", ctxt);
143:                         }
144:
145:                         ValueSet result = null;
146:
147:                         for (Value v : setset)
148:                         {
149:                                 if (result == null)
150:                                 {
151:                                         result = new ValueSet(v.setValue(ctxt));
152:                                 } else
153:                                 {
154:                                         result.retainAll(v.setValue(ctxt));
155:                                 }
156:                         }
157:
158:                         return new SetValue(result);
159:                 } catch (ValueException e)
160:                 {
161:                         return VdmRuntimeError.abort(node.getLocation(), e);
162:                 }
163:         }
164:
165:         @Override
166:         public Value caseADistMergeUnaryExp(ADistMergeUnaryExp node, Context ctxt)
167:                         throws AnalysisException
168:         {
169:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
170:
171:                 try
172:                 {
173:                         ValueSet setmap = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).setValue(ctxt);
174:                         ValueMap result = new ValueMap();
175:
176:                         for (Value v : setmap)
177:                         {
178:                                 ValueMap m = v.mapValue(ctxt);
179:
180:                                 for (Value k : m.keySet())
181:                                 {
182:                                         Value rng = m.get(k);
183:                                         Value old = result.put(k, rng);
184:
185:                                         if (old != null && !old.equals(rng))
186:                                         {
187:                                                 VdmRuntimeError.abort(node.getLocation(), 4021, "Duplicate map keys have different values: "
188:                                                                 + k, ctxt);
189:                                         }
190:                                 }
191:                         }
192:
193:                         return new MapValue(result);
194:                 } catch (ValueException e)
195:                 {
196:                         return VdmRuntimeError.abort(node.getLocation(), e);
197:                 }
198:         }
199:
200:         @Override
201:         public Value caseADistUnionUnaryExp(ADistUnionUnaryExp node, Context ctxt)
202:                         throws AnalysisException
203:         {
204:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
205:
206:                 try
207:                 {
208:                         ValueSet setset = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).setValue(ctxt);
209:                         ValueSet result = new ValueSet();
210:
211:                         for (Value v : setset)
212:                         {
213:                                 result.addAll(v.setValue(ctxt));
214:                         }
215:
216:                         return new SetValue(result);
217:                 } catch (ValueException e)
218:                 {
219:                         return VdmRuntimeError.abort(node.getLocation(), e);
220:                 }
221:         }
222:
223:         @Override
224:         public Value caseAElementsUnaryExp(AElementsUnaryExp node, Context ctxt)
225:                         throws AnalysisException
226:         {
227:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
228:
229:                 try
230:                 {
231:                         ValueList seq = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt);
232:                         ValueSet set = new ValueSet();
233:                         set.addAll(seq);
234:                         return new SetValue(set);
235:                 } catch (ValueException e)
236:                 {
237:                         return VdmRuntimeError.abort(node.getLocation(), e);
238:                 }
239:         }
240:
241:         @Override
242:         public Value caseAFloorUnaryExp(AFloorUnaryExp node, Context ctxt)
243:                         throws AnalysisException
244:         {
245:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
246:
247:                 try
248:                 {
249:                         return NumericValue.valueOf(Math.floor(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).realValue(ctxt)), ctxt);
250:                 } catch (ValueException e)
251:                 {
252:                         return VdmRuntimeError.abort(node.getLocation(), e);
253:                 }
254:         }
255:
256:         @Override
257:         public Value caseAHeadUnaryExp(AHeadUnaryExp node, Context ctxt)
258:                         throws AnalysisException
259:         {
260:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
261:
262:                 try
263:                 {
264:                         ValueList seq = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt);
265:
266:                         if (seq.isEmpty())
267:                         {
268:                                 return VdmRuntimeError.abort(node.getLocation(), 4010, "Cannot take head of empty sequence", ctxt);
269:                         }
270:
271:                         return seq.get(0);
272:                 } catch (ValueException e)
273:                 {
274:                         return VdmRuntimeError.abort(node.getLocation(), e);
275:                 }
276:         }
277:
278:         @Override
279:         public Value caseAIndicesUnaryExp(AIndicesUnaryExp node, Context ctxt)
280:                         throws AnalysisException
281:         {
282:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
283:
284:                 try
285:                 {
286:                         ValueList seq = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt);
287:                         ValueSet result = new ValueSet();
288:
289:                         for (int i = 1; i <= seq.size(); i++)
290:                         {
291:                                 result.addNoCheck(new NaturalOneValue(i));
292:                         }
293:
294:                         return new SetValue(result);
295:                 } catch (ValueException e)
296:                 {
297:                         return VdmRuntimeError.abort(node.getLocation(), e);
298:                 } catch (Exception e)
299:                 {
300:                         return VdmRuntimeError.abort(node.getLocation(), 4065, e.getMessage(), ctxt);
301:                 }
302:         }
303:
304:         @Override
305:         public Value caseALenUnaryExp(ALenUnaryExp node, Context ctxt)
306:                         throws AnalysisException
307:         {
308:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
309:
310:                 try
311:                 {
312:                         return new NaturalValue(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt).size());
313:                 } catch (ValueException e)
314:                 {
315:                         return VdmRuntimeError.abort(node.getLocation(), e);
316:                 } catch (ContextException e)
317:                 {
318:                         throw e; // To avoid case below
319:                 } catch (Exception e)
320:                 {
321:                         return VdmRuntimeError.abort(node.getLocation(), 4065, e.getMessage(), ctxt);
322:                 }
323:         }
324:
325:         @Override
326:         public Value caseAMapDomainUnaryExp(AMapDomainUnaryExp node, Context ctxt)
327:                         throws AnalysisException
328:         {
329:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
330:
331:                 try
332:                 {
333:                         ValueMap map = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).mapValue(ctxt);
334:                         ValueSet result = new ValueSet();
335:                         result.addAll(map.keySet());
336:                         return new SetValue(result);
337:                 } catch (ValueException e)
338:                 {
339:                         return VdmRuntimeError.abort(node.getLocation(), e);
340:                 }
341:         }
342:
343:         @Override
344:         public Value caseAMapInverseUnaryExp(AMapInverseUnaryExp node, Context ctxt)
345:                         throws AnalysisException
346:         {
347:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
348:
349:                 try
350:                 {
351:                         ValueMap map = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).mapValue(ctxt);
352:
353:                         if (!map.isInjective())
354:                         {
355:                                 VdmRuntimeError.abort(node.getLocation(), 4012, "Cannot invert non-injective map", ctxt);
356:                         }
357:
358:                         ValueMap result = new ValueMap();
359:
360:                         for (Value k : map.keySet())
361:                         {
362:                                 result.put(map.get(k), k);
363:                         }
364:
365:                         return new MapValue(result);
366:                 } catch (ValueException e)
367:                 {
368:                         return VdmRuntimeError.abort(node.getLocation(), e);
369:                 }
370:         }
371:
372:         @Override
373:         public Value caseAMapRangeUnaryExp(AMapRangeUnaryExp node, Context ctxt)
374:                         throws AnalysisException
375:         {
376:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
377:
378:                 try
379:                 {
380:                         ValueMap map = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).mapValue(ctxt);
381:                         ValueSet result = new ValueSet();
382:                         result.addAll(map.values());
383:                         return new SetValue(result);
384:                 } catch (ValueException e)
385:                 {
386:                         return VdmRuntimeError.abort(node.getLocation(), e);
387:                 }
388:         }
389:
390:         @Override
391:         public Value caseANotUnaryExp(ANotUnaryExp node, Context ctxt)
392:                         throws AnalysisException
393:         {
394:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
395:
396:                 try
397:                 {
398:                         Value v = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt);
399:                         return v.isUndefined() ? v : new BooleanValue(!v.boolValue(ctxt));
400:                 } catch (ValueException e)
401:                 {
402:                         return VdmRuntimeError.abort(node.getLocation(), e);
403:                 }
404:         }
405:
406:         @Override
407:         public Value caseAPowerSetUnaryExp(APowerSetUnaryExp node, Context ctxt)
408:                         throws AnalysisException
409:         {
410:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
411:
412:                 try
413:                 {
414:                         ValueSet values = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).setValue(ctxt);
415:                         List<ValueSet> psets = values.powerSet();
416:                         ValueSet rs = new ValueSet(psets.size());
417:
418:                         for (ValueSet v : psets)
419:                         {
420:                                 rs.addNoCheck(new SetValue(v));
421:                         }
422:
423:                         return new SetValue(rs);
424:                 } catch (ValueException e)
425:                 {
426:                         return VdmRuntimeError.abort(node.getLocation(), e);
427:                 }
428:         }
429:
430:         @Override
431:         public Value caseAReverseUnaryExp(AReverseUnaryExp node, Context ctxt)
432:                         throws AnalysisException
433:         {
434:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
435:
436:                 ValueList seq = null;
437:
438:                 try
439:                 {
440:                         seq = new ValueList(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt));
441:                         Collections.reverse(seq);
442:                 } catch (ValueException e)
443:                 {
444:                         return VdmRuntimeError.abort(node.getLocation(), e);
445:                 }
446:
447:                 return new SeqValue(seq);
448:         }
449:
450:         @Override
451:         public Value caseATailUnaryExp(ATailUnaryExp node, Context ctxt)
452:                         throws AnalysisException
453:         {
454:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
455:
456:                 ValueList seq = null;
457:
458:                 try
459:                 {
460:                         seq = new ValueList(node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).seqValue(ctxt));
461:                 } catch (ValueException e)
462:                 {
463:                         return VdmRuntimeError.abort(node.getLocation(), e);
464:                 }
465:
466:•                if (seq.isEmpty())
467:                 {
468:                         VdmRuntimeError.abort(node.getLocation(), 4033, "Tail sequence is empty", ctxt);
469:                 }
470:
471:                 seq.remove(0);
472:                 return new SeqValue(seq);
473:         }
474:
475:         @Override
476:         public Value caseAUnaryMinusUnaryExp(AUnaryMinusUnaryExp node, Context ctxt)
477:                         throws AnalysisException
478:         {
479:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
480:
481:                 try
482:                 {
483:                         double v = node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt).realValue(ctxt);
484:                         return NumericValue.valueOf(-v, ctxt);
485:                 } catch (ValueException e)
486:                 {
487:                         return VdmRuntimeError.abort(node.getLocation(), e);
488:                 }
489:         }
490:
491:         @Override
492:         public Value caseAUnaryPlusUnaryExp(AUnaryPlusUnaryExp node, Context ctxt)
493:                         throws AnalysisException
494:         {
495:                 BreakpointManager.getBreakpoint(node).check(node.getLocation(), ctxt);
496:
497:                 return node.getExp().apply(VdmRuntime.getExpressionEvaluator(), ctxt);
498:         }
499:
500: }