/* * #%~ * VDM Code Generator Runtime * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.codegen.runtime; import java.util.Collections; public class SeqUtil { public static VDMSeq seq() { return new VDMSeq(); } @SuppressWarnings("unchecked") public static VDMSeq seq(Object... elements) { if (elements == null) { throw new IllegalArgumentException("Cannot instantiate sequence from null"); } VDMSeq seq = seq(); for (Object element : elements) { seq.add(element); } return seq; } @SuppressWarnings("unchecked") public static VDMSeq mod(VDMSeq seq, VDMMap map) { if (map == null) { throw new IllegalArgumentException("Cannot modify sequence from null"); } Maplet[] maplets = MapUtil.toMaplets(map); if (maplets == null) { throw new IllegalArgumentException("Cannot modify sequence from null"); } if (seq == null) { throw new IllegalArgumentException("Cannot modify null"); } for (Maplet maplet : maplets) { Object left = maplet.getLeft(); Object right = maplet.getRight(); if (!(left instanceof Long)) { throw new IllegalArgumentException("Domain values of maplets in a sequence modification must be of type nat1"); } Long key = (Long) left; seq.set(Utils.index(key), right); } return seq; } public static String mod(String string, VDMMap map) { if (map == null) { throw new IllegalArgumentException("Cannot modify sequence from null"); } Maplet[] maplets = MapUtil.toMaplets(map); if (maplets == null) { throw new IllegalArgumentException("Cannot modify sequence from null"); } if (string == null) { throw new IllegalArgumentException("Cannot modify null"); } StringBuilder builder = new StringBuilder(string); for (Maplet maplet : maplets) { Object left = maplet.getLeft(); Object right = maplet.getRight(); if (!(left instanceof Long)) { throw new IllegalArgumentException("Domain values of maplets in a sequence modification must be of type nat1"); } if (!(right instanceof Character)) { throw new IllegalArgumentException("Range values must be characters when modifying a character sequence"); } char rightChar = (Character) right; Long key = (Long) left; builder.setCharAt(Utils.index(key), rightChar); } return builder.toString(); } @SuppressWarnings("unchecked") public static VDMSeq subSeq(VDMSeq seq, Number fromIndex, Number toIndex) { if (fromIndex.longValue() > toIndex.longValue() || toIndex.longValue() < 1) { return seq(); } fromIndex = Utils.index(Math.max(1, fromIndex.longValue())); toIndex = Math.min(seq.size(), toIndex.longValue()); VDMSeq subSeq = seq(); subSeq.addAll(seq.subList(Utils.toInt(fromIndex), Utils.toInt(toIndex))); return subSeq; } public static String subSeq(String seq, Number fromIndex, Number toIndex) { if (fromIndex.longValue() > toIndex.longValue() || toIndex.longValue() < 1) { return ""; } fromIndex = Utils.index(Math.max(1, fromIndex.longValue())); toIndex = Math.min(seq.length(), toIndex.longValue()); return seq.substring(Utils.toInt(fromIndex), Utils.toInt(toIndex)); } @SuppressWarnings("unchecked") public static VDMSet elems(VDMSeq seq) { if (seq == null) { throw new IllegalArgumentException("Cannot get elems of null"); } VDMSet elems = SetUtil.set(); elems.addAll(seq); return elems; } @SuppressWarnings("unchecked") public static VDMSet elems(String string) { if (string == null) { throw new IllegalArgumentException("Cannot get elems of null"); } VDMSet elems = SetUtil.set(); for (int i = 0; i < string.length(); i++) { elems.add(string.charAt(i)); } return elems; } @SuppressWarnings("unchecked") public static VDMSeq reverse(VDMSeq seq) { if (seq == null) { throw new IllegalArgumentException("Cannot reverse null"); } VDMSeq result = seq(); result.addAll(seq); Collections.reverse(result); return result; } @SuppressWarnings("unchecked") public static VDMSeq tail(VDMSeq seq) { if (seq == null) { throw new IllegalArgumentException("Cannot take tail of null"); } if (seq.isEmpty()) { throw new IllegalArgumentException("Cannot take tail of empty sequence"); } VDMSeq tail = new VDMSeq(); for (int i = 1; i < seq.size(); i++) { Object element = seq.get(i); tail.add(element); } return tail; } public static String tail(String seq) { if (seq == null) { throw new IllegalArgumentException("Cannot take tail of null"); } if (seq.isEmpty()) { throw new IllegalArgumentException("Cannot take tail of empty string"); } return seq.substring(1, seq.length()); } @SuppressWarnings("unchecked") public static VDMSet inds(VDMSeq seq) { if (seq == null) { throw new IllegalArgumentException("Cannot get indices of null"); } VDMSet indices = SetUtil.set(); for (long i = 1; i <= seq.size(); i++) { indices.add(i); } return indices; } @SuppressWarnings("unchecked") public static VDMSet inds(String seq) { if (seq == null) { throw new IllegalArgumentException("Cannot get indices of null"); } VDMSet indices = SetUtil.set(); for (long i = 1; i <= seq.length(); i++) { indices.add(i); } return indices; } @SuppressWarnings("unchecked") public static VDMSeq conc(VDMSeq left, VDMSeq right) { if (left == null || right == null) { throw new IllegalArgumentException("Cannot concatenate null"); } VDMSeq result = seq(); result.addAll(left); result.addAll(right); return result; } @SuppressWarnings("unchecked") public static VDMSeq distConc(VDMSeq sequences) { if (sequences == null) { throw new IllegalArgumentException("Distributed concatenation of null is undefined"); } VDMSeq result = seq(); for (Object seq : sequences) { if (seq instanceof String) { char[] charArray = ((String) seq).toCharArray(); for (Character c : charArray) { result.add(c); } } else if (seq instanceof VDMSeq) { VDMSeq vdmSeq = (VDMSeq) seq; result.addAll(vdmSeq); } else { throw new IllegalArgumentException("Distributed concatenation only supports sequences"); } } return result; } public static String distConcStrings(VDMSeq stringSeq) { if (stringSeq == null) { throw new IllegalArgumentException("Distributed string concatenation of null is undefined"); } String result = ""; for (Object str : stringSeq) { if (!(str instanceof String)) { throw new IllegalArgumentException("Distributed string concatenation only supports strings"); } result += str; } return result; } public static String toStr(Object seq) { if (seq instanceof VDMSeq) { VDMSeq vdmSeq = (VDMSeq) seq; if (vdmSeq.isEmpty()) { return ""; } else { return seq.toString(); } } else if (seq instanceof String) { return (String) seq; } else { throw new RuntimeException("String conversion is only supported for VDMSeq"); } } @SuppressWarnings("unchecked") public static VDMSeq toSeq(Object str) { VDMSeq result = seq(); if (str instanceof String) { String string = (String) str; for (Character c : string.toCharArray()) { result.add(c); } return result; } else if (str instanceof VDMSeq) { return ((VDMSeq) str).copy(); } else { throw new RuntimeException("VDMSeq conversion is only supported for strings"); } } }