mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 07:17:13 -04:00
added a tt2 renaming of invalid names, see #101
This commit is contained in:
parent
051852f9d0
commit
24df40e67b
111
src/main/java/de/neemann/digital/builder/CleanNameBuilder.java
Normal file
111
src/main/java/de/neemann/digital/builder/CleanNameBuilder.java
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.analyse.expression.Expression;
|
||||
import de.neemann.digital.analyse.expression.Variable;
|
||||
import de.neemann.digital.analyse.expression.modify.ExpressionModifier;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Builder which performs a name cleanup
|
||||
*/
|
||||
public class CleanNameBuilder implements BuilderInterface<CleanNameBuilder> {
|
||||
|
||||
private final BuilderInterface parent;
|
||||
private final Filter filter;
|
||||
private final HashMap<String, String> nameMap;
|
||||
|
||||
/**
|
||||
* Creates a new instance which allows only characters, numbers and the the underscore.
|
||||
*
|
||||
* @param parent the parent builder
|
||||
*/
|
||||
public CleanNameBuilder(BuilderInterface parent) {
|
||||
this(parent, new SimpleFilter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ne instance
|
||||
*
|
||||
* @param parent the parent builder
|
||||
* @param filter the name filter to use
|
||||
*/
|
||||
public CleanNameBuilder(BuilderInterface parent, Filter filter) {
|
||||
this.parent = parent;
|
||||
this.filter = filter;
|
||||
nameMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CleanNameBuilder addCombinatorial(String name, Expression expression) throws BuilderException {
|
||||
parent.addCombinatorial(checkName(name), checkName(expression));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CleanNameBuilder addSequential(String name, Expression expression) throws BuilderException {
|
||||
parent.addSequential(checkName(name), checkName(expression));
|
||||
return this;
|
||||
}
|
||||
|
||||
private Expression checkName(Expression expression) {
|
||||
return ExpressionModifier.modifyExpression(expression, exp -> {
|
||||
if (exp instanceof Variable) {
|
||||
return new Variable(checkName(((Variable) exp).getIdentifier()));
|
||||
} else
|
||||
return exp;
|
||||
});
|
||||
}
|
||||
|
||||
private String checkName(String name) {
|
||||
String n = nameMap.get(name);
|
||||
if (n == null) {
|
||||
n = filter.filter(name);
|
||||
if (n == null || n.isEmpty())
|
||||
n = "X";
|
||||
if (nameMap.containsValue(n)) {
|
||||
int num = 1;
|
||||
while (nameMap.containsValue(n + num))
|
||||
num++;
|
||||
n = n + num;
|
||||
}
|
||||
nameMap.put(name, n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter interface
|
||||
*/
|
||||
public interface Filter {
|
||||
/**
|
||||
* Has to return a legal name
|
||||
*
|
||||
* @param name the eventually non legal name
|
||||
* @return the legal name
|
||||
*/
|
||||
String filter(String name);
|
||||
}
|
||||
|
||||
private static final class SimpleFilter implements Filter {
|
||||
@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);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import de.neemann.digital.lang.Lang;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@ -20,6 +21,7 @@ import java.util.*;
|
||||
*/
|
||||
public class TT2Exporter implements ExpressionExporter<TT2Exporter> {
|
||||
private final BuilderCollector builder;
|
||||
private final CleanNameBuilder cleanNameBuilder;
|
||||
private final PinMap pinMap;
|
||||
private String projectName;
|
||||
private String device;
|
||||
@ -40,6 +42,7 @@ public class TT2Exporter implements ExpressionExporter<TT2Exporter> {
|
||||
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 = new PinMap().setClockPin(43);
|
||||
device = "f1502ispplcc44";
|
||||
this.projectName = projectName;
|
||||
@ -47,7 +50,7 @@ public class TT2Exporter implements ExpressionExporter<TT2Exporter> {
|
||||
|
||||
@Override
|
||||
public BuilderInterface getBuilder() {
|
||||
return builder;
|
||||
return cleanNameBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +71,7 @@ public class TT2Exporter implements ExpressionExporter<TT2Exporter> {
|
||||
|
||||
@Override
|
||||
public void writeTo(OutputStream out) throws FuseMapFillerException, IOException, PinMapException {
|
||||
writeTo(new OutputStreamWriter(out, "ISO-8859-1"));
|
||||
writeTo(new OutputStreamWriter(out, StandardCharsets.ISO_8859_1));
|
||||
}
|
||||
|
||||
private void writeTo(OutputStreamWriter writer) throws IOException, FuseMapFillerException, PinMapException {
|
||||
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2019 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.analyse.expression.Expression;
|
||||
import de.neemann.digital.analyse.expression.Operation;
|
||||
import de.neemann.digital.analyse.expression.Variable;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CleanNameBuilderTest extends TestCase {
|
||||
|
||||
public void testSimple() throws BuilderException {
|
||||
BuilderCollector bc = new BuilderCollector();
|
||||
CleanNameBuilder cnb = new CleanNameBuilder(bc);
|
||||
|
||||
String n0 = "z###0";
|
||||
String n1 = "z#'#0";
|
||||
|
||||
cnb.addCombinatorial(n0, Operation.and(new Variable(n0), new Variable(n1)));
|
||||
cnb.addCombinatorial(n1, Operation.or(new Variable(n0), new Variable(n1)));
|
||||
|
||||
Map<String, Expression> comb = bc.getCombinatorial();
|
||||
assertEquals(2, comb.size());
|
||||
assertEquals("and(z0,z01)", comb.get("z0").toString());
|
||||
assertEquals("or(z0,z01)", comb.get("z01").toString());
|
||||
}
|
||||
|
||||
public void testSimple2() throws BuilderException {
|
||||
BuilderCollector bc = new BuilderCollector();
|
||||
CleanNameBuilder cnb = new CleanNameBuilder(bc);
|
||||
|
||||
String n0 = "z_0^n";
|
||||
String n1 = "z_1^n";
|
||||
|
||||
cnb.addCombinatorial(n0, Operation.and(new Variable(n0), new Variable(n1)));
|
||||
cnb.addCombinatorial(n1, Operation.or(new Variable(n0), new Variable(n1)));
|
||||
|
||||
Map<String, Expression> comb = bc.getCombinatorial();
|
||||
assertEquals(2, comb.size());
|
||||
assertEquals("and(z_0n,z_1n)", comb.get("z_0n").toString());
|
||||
assertEquals("or(z_0n,z_1n)", comb.get("z_1n").toString());
|
||||
}
|
||||
|
||||
public void testEmpty() throws BuilderException {
|
||||
BuilderCollector bc = new BuilderCollector();
|
||||
CleanNameBuilder cnb = new CleanNameBuilder(bc, name -> null);
|
||||
|
||||
String n0 = "z_0^n";
|
||||
String n1 = "z_1^n";
|
||||
|
||||
cnb.addCombinatorial(n0, Operation.and(new Variable(n0), new Variable(n1)));
|
||||
cnb.addCombinatorial(n1, Operation.or(new Variable(n0), new Variable(n1)));
|
||||
|
||||
Map<String, Expression> comb = bc.getCombinatorial();
|
||||
assertEquals(2, comb.size());
|
||||
assertEquals("and(X,X1)", comb.get("X").toString());
|
||||
assertEquals("or(X,X1)", comb.get("X1").toString());
|
||||
}
|
||||
|
||||
public void testSequential() throws BuilderException {
|
||||
BuilderCollector bc = new BuilderCollector();
|
||||
CleanNameBuilder cnb = new CleanNameBuilder(bc);
|
||||
|
||||
String n0 = "z_0^n";
|
||||
String n1 = "z_1^n";
|
||||
|
||||
cnb.addSequential(n0 + "+1", Operation.and(new Variable(n0), new Variable(n1)));
|
||||
cnb.addSequential(n1 + "+1", Operation.or(new Variable(n0), new Variable(n1)));
|
||||
|
||||
Map<String, Expression> reg = bc.getRegistered();
|
||||
assertEquals(2, reg.size());
|
||||
assertEquals("and(z_0n,z_1n)", reg.get("z_0n1").toString());
|
||||
assertEquals("or(z_0n,z_1n)", reg.get("z_1n1").toString());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user