diff --git a/src/main/java/de/neemann/digital/builder/ATF150x/ATFDevice.java b/src/main/java/de/neemann/digital/builder/ATF150x/ATFDevice.java index 4ecfa00c0..1304aef43 100644 --- a/src/main/java/de/neemann/digital/builder/ATF150x/ATFDevice.java +++ b/src/main/java/de/neemann/digital/builder/ATF150x/ATFDevice.java @@ -6,6 +6,7 @@ package de.neemann.digital.builder.ATF150x; import de.neemann.digital.builder.ExpressionToFileExporter; +import de.neemann.digital.builder.PinMap; import de.neemann.digital.builder.tt2.StartATF150xFitter; import de.neemann.digital.builder.tt2.TT2Exporter; @@ -121,9 +122,9 @@ public String getMenuName() { private TT2Exporter getTT2Exporter(String projectName) { TT2Exporter tt2 = new TT2Exporter(projectName); - tt2.getPinMapping() - .setClockPin(clockPin) - .setAvailBidirectional(pins); + PinMap pinMap = tt2.getPinMapping(); + pinMap.setClockPin(clockPin); + pinMap.setAvailBidirectional(pins); tt2.setDevice(getTT2DevName()); return tt2; } diff --git a/src/main/java/de/neemann/digital/builder/CleanNameBuilder.java b/src/main/java/de/neemann/digital/builder/CleanNameBuilder.java index 6f3cf5412..862ddf453 100644 --- a/src/main/java/de/neemann/digital/builder/CleanNameBuilder.java +++ b/src/main/java/de/neemann/digital/builder/CleanNameBuilder.java @@ -115,20 +115,115 @@ public interface Filter { String filter(String name); } + /** + * The SimpleFilter class applies multiple CharacterFilter instances to filter the input string. + */ private static final class SimpleFilter implements Filter { + private final CharacterFilter[] filters; + + /** + * Creates a SimpleFilter instance with a predefined set of character filters. + */ + SimpleFilter() { + filters = new CharacterFilter[]{ + new RangeCharacterFilter('A', 'Z'), + new RangeCharacterFilter('a', 'z'), + new RangeCharacterFilter('0', '9'), + new SingleCharacterFilter('_') + }; + } + + /** + * Filters the input string by applying the CharacterFilter instances. + * + * @param name the input string to filter + * @return the filtered string containing only accepted characters + */ @Override public String filter(String name) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < name.length(); i++) { char c = name.charAt(i); - if ((c >= 'A' && c <= 'Z') - || (c >= 'a' && c <= 'z') - || (c >= '0' && c <= '9') - || c == '_') - sb.append(c); + for (CharacterFilter filter : filters) { + if (filter.accept(c)) { + sb.append(c); + break; + } + } } return sb.toString(); } + + /** + * The CharacterFilter interface defines a method to check if a character is accepted by the filter. + */ + private interface CharacterFilter { + /** + * Checks if the given character is accepted by the filter. + * + * @param c the character to check + * @return true if the character is accepted, false otherwise + */ + boolean accept(char c); + } + + /** + * The RangeCharacterFilter class accepts characters within a specified range. + */ + private static class RangeCharacterFilter implements CharacterFilter { + private final char min; + private final char max; + + /** + * Creates a RangeCharacterFilter instance with a specified character range. + * + * @param min the minimum character in the range (inclusive) + * @param max the maximum character in the range (inclusive) + */ + RangeCharacterFilter(char min, char max) { + this.min = min; + this.max = max; + } + + /** + * Checks if the given character is within the specified range. + * + * @param c the character to check + * @return true if the character is within the range, false otherwise + */ + @Override + public boolean accept(char c) { + return c >= min && c <= max; + } + } + + /** + * The SingleCharacterFilter class accepts a single specified character. + */ + private static class SingleCharacterFilter implements CharacterFilter { + private final char target; + + /** + * Creates a SingleCharacterFilter instance with a specified character to accept. + * + * @param target the character to accept + */ + SingleCharacterFilter(char target) { + this.target = target; + } + + /** + * Checks if the given character is equal to the specified target character. + * + * @param c the character to check + * @return true if the character is equal to the target character, false otherwise + */ + @Override + public boolean accept(char c) { + return c == target; + } + } + } } diff --git a/src/main/java/de/neemann/digital/builder/ClockPinManager.java b/src/main/java/de/neemann/digital/builder/ClockPinManager.java new file mode 100644 index 000000000..7569564c7 --- /dev/null +++ b/src/main/java/de/neemann/digital/builder/ClockPinManager.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016 Helmut Neemann + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ +package de.neemann.digital.builder; + +/** + * Manages the clock pin information. + */ +public class ClockPinManager { + private int clockPin; + + /** + * Returns the clock pin number. + * + * @return the clock pin number + */ + public int getClockPin() { + return clockPin; + } + + /** + * Sets the clock pin number. + * + * @param clockPin the clock pin number + */ + public void setClockPin(int clockPin) { + if (clockPin > 0) + this.clockPin = clockPin; + } +} diff --git a/src/main/java/de/neemann/digital/builder/Pin.java b/src/main/java/de/neemann/digital/builder/Pin.java new file mode 100644 index 000000000..7ddbe9fbc --- /dev/null +++ b/src/main/java/de/neemann/digital/builder/Pin.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Helmut Neemann + * Use of this source code is governed by the GPL v3 license + * that can be found in the LICENSE file. + */ + +package de.neemann.digital.builder; + +import de.neemann.digital.core.element.PinDescription; + +/** + * Represents a Pin with a number and a direction. + */ +public class Pin { + private final int num; + private final PinDescription.Direction direction; + + /** + * Constructs a new Pin with the given number and direction. + * + * @param num the pin number + * @param direction the pin direction + */ + public Pin(int num, PinDescription.Direction direction) { + this.num = num; + this.direction = direction; + } + + /** + * Returns the pin number. + * + * @return the pin number + */ + public int getNum() { + return num; + } + + /** + * Returns the pin direction. + * + * @return the pin direction + */ + public PinDescription.Direction getDirection() { + return direction; + } +} diff --git a/src/main/java/de/neemann/digital/builder/PinMap.java b/src/main/java/de/neemann/digital/builder/PinMap.java index ecf2af9b8..a874f6e51 100644 --- a/src/main/java/de/neemann/digital/builder/PinMap.java +++ b/src/main/java/de/neemann/digital/builder/PinMap.java @@ -16,11 +16,11 @@ * A PinMap. * Used to assign a symbolic name to a pin number */ -public class PinMap { +public class PinMap extends ClockPinManager{ private final HashMap pinMap; private final ArrayList availPins; private ArrayList> alias; - private int clockPin; + /** * Creates a new instance @@ -176,10 +176,10 @@ public PinMap addAll(Map pinMap) throws PinMapException { private Integer searchFirstFreePin(PinDescription.Direction direction, String name) { for (Pin pin : availPins) { - if (!pinMap.containsValue(pin.num)) - if (pin.direction.equals(direction) || pin.direction.equals(PinDescription.Direction.both)) { - pinMap.put(name, pin.num); - return pin.num; + if (!pinMap.containsValue(pin.getNum())) + if (pin.getDirection().equals(direction) || pin.getDirection().equals(PinDescription.Direction.both)) { + pinMap.put(name, pin.getNum()); + return pin.getNum(); } } return null; @@ -187,8 +187,8 @@ private Integer searchFirstFreePin(PinDescription.Direction direction, String na private boolean isAvailable(PinDescription.Direction direction, int p) { for (Pin pin : availPins) - if (pin.num == p) - return (pin.direction.equals(direction) || pin.direction.equals(PinDescription.Direction.both)); + if (pin.getNum() == p) + return (pin.getDirection().equals(direction) || pin.getDirection().equals(PinDescription.Direction.both)); return false; } @@ -273,32 +273,4 @@ public String toString() { return sb.toString(); } - /** - * @return the clock pin - */ - public int getClockPin() { - return clockPin; - } - - /** - * Sets the clock pin - * - * @param clockPin the clock pin - * @return this for chained calls - */ - public PinMap setClockPin(int clockPin) { - if (clockPin > 0) - this.clockPin = clockPin; - return this; - } - - private static final class Pin { - private final int num; - private final PinDescription.Direction direction; - - private Pin(int num, PinDescription.Direction direction) { - this.num = num; - this.direction = direction; - } - } } diff --git a/src/main/java/de/neemann/digital/builder/tt2/TT2Exporter.java b/src/main/java/de/neemann/digital/builder/tt2/TT2Exporter.java index d7abf10f5..ae6f17b5f 100644 --- a/src/main/java/de/neemann/digital/builder/tt2/TT2Exporter.java +++ b/src/main/java/de/neemann/digital/builder/tt2/TT2Exporter.java @@ -43,7 +43,8 @@ public TT2Exporter(String projectName) { // if simple aliases are filtered out, a direct input to output connection isn't possible anymore builder = new BuilderCollector(); cleanNameBuilder = new CleanNameBuilder(builder); - pinMap = cleanNameBuilder.createPinMap().setClockPin(43); + pinMap = cleanNameBuilder.createPinMap(); + pinMap.setClockPin(43); device = "f1502ispplcc44"; this.projectName = projectName; }