1 /********************************************************************************
2 *
3 * Copyright (c) 2008 Fujitsu Services Ltd.
4 *
5 * Author: Nick Battle
6 *
7 * This file is part of VDMJ.
8 *
9 * VDMJ is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * VDMJ is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
21 *
22 ******************************************************************************/
23
24 package org.overturetool.vdmj.expressions;
25
26 import org.overturetool.vdmj.lex.LexToken;
27 import org.overturetool.vdmj.runtime.Context;
28 import org.overturetool.vdmj.runtime.ValueException;
29 import org.overturetool.vdmj.typechecker.Environment;
30 import org.overturetool.vdmj.typechecker.NameScope;
31 import org.overturetool.vdmj.typechecker.TypeComparator;
32 import org.overturetool.vdmj.types.MapType;
33 import org.overturetool.vdmj.types.SetType;
34 import org.overturetool.vdmj.types.Type;
35 import org.overturetool.vdmj.types.TypeList;
36 import org.overturetool.vdmj.values.MapValue;
37 import org.overturetool.vdmj.values.Value;
38 import org.overturetool.vdmj.values.ValueMap;
39 import org.overturetool.vdmj.values.ValueSet;
40
41 public class RangeResByExpression extends BinaryExpression
42 {
43 private static final long serialVersionUID = 1L;
44
45 public RangeResByExpression(Expression left, LexToken op, Expression right)
46 {
47 super(left, op, right);
48 }
49
50 @Override
51 public Type typeCheck(Environment env, TypeList qualifiers, NameScope scope)
52 {
53 ltype = left.typeCheck(env, null, scope);
54 rtype = right.typeCheck(env, null, scope);
55
56 if (!ltype.isMap())
57 {
58 report(3148, "Left of ':->' is not a map");
59 }
60 else if (!rtype.isSet())
61 {
62 report(3149, "Right of ':->' is not a set");
63 }
64 else
65 {
66 MapType map = ltype.getMap();
67 SetType set = rtype.getSet();
68
69 if (!TypeComparator.compatible(set.setof, map.to))
70 {
71 report(3150, "Restriction of map should be set of " + map.to);
72 }
73 }
74
75 return ltype;
76 }
77
78 @Override
79 public Value eval(Context ctxt)
80 {
81 breakpoint.check(location, ctxt);
82
83 ValueSet set = null;
84 ValueMap map = null;
85
86 try
87 {
88 set = right.eval(ctxt).setValue(ctxt);
89 map = left.eval(ctxt).mapValue(ctxt);
90 }
91 catch (ValueException e)
92 {
93 return abort(e);
94 }
95
96 ValueMap modified = new ValueMap(map);
97
98 for (Value k: map.keySet())
99 {
100 if (set.contains(map.get(k)))
101 {
102 modified.remove(k);
103 }
104 }
105
106 return new MapValue(modified);
107 }
108
109 @Override
110 public String kind()
111 {
112 return ":->";
113 }
114 }