added a tt2 renaming of invalid names, see #101

This commit is contained in:
hneemann 2019-08-10 15:37:06 +02:00
parent 051852f9d0
commit 24df40e67b
3 changed files with 196 additions and 2 deletions

View 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();
}
}
}

View File

@ -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 {

View File

@ -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());
}
}