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 }