diff --git a/src/main/dig/generic/barrelShifter/barrelShifter.dig b/src/main/dig/generic/barrelShifter/barrelShifter.dig
index f7b639d3c..351b7c010 100644
--- a/src/main/dig/generic/barrelShifter/barrelShifter.dig
+++ b/src/main/dig/generic/barrelShifter/barrelShifter.dig
@@ -81,20 +81,20 @@
generic
if (args.direction="right") {
- export circuit:="shift-fixed-right-inc.dig";
- } else {
- if (args.direction="arith") {
- export circuit:="shift-fixed-arith-right-inc.dig";
- } else {
- if (args.direction="left") {
- export circuit:="shift-fixed-left-inc.dig";
- } else {
- panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!");
- }
- }
- }
+ export circuit:="shift-fixed-right-inc.dig";
+} else {
+ if (args.direction="arith") {
+ export circuit:="shift-fixed-arith-right-inc.dig";
+ } else {
+ if (args.direction="left") {
+ export circuit:="shift-fixed-left-inc.dig";
+ } else {
+ panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!");
+ }
+ }
+}
- export shiftBits:=bitsNeededFor(args.dataBits-1);
+shiftBits:=bitsNeededFor(args.dataBits-1);
diff --git a/src/main/dig/generic/barrelShifter/shift-inc.dig b/src/main/dig/generic/barrelShifter/shift-inc.dig
index a96a8b2b0..be976891f 100644
--- a/src/main/dig/generic/barrelShifter/shift-inc.dig
+++ b/src/main/dig/generic/barrelShifter/shift-inc.dig
@@ -13,7 +13,7 @@
generic
- export shift := 1<<(args.shiftBits-1);
+ shift := 1<<(args.shiftBits-1);
setCircuit(args.circuit);
@@ -87,8 +87,8 @@ setCircuit(args.circuit);
generic
if (args.shiftBits=2) {
- export shift := 1;
- setCircuit(args.circuit);
+ export shift := 1;
+ setCircuit(args.circuit);
} else {
export shiftBits := args.shiftBits-1;
}
diff --git a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java
index ffaba3fcb..d8b4da9ca 100644
--- a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java
+++ b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java
@@ -12,10 +12,12 @@ import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.hdl.hgs.*;
import de.neemann.digital.hdl.hgs.function.Function;
+import de.neemann.digital.hdl.hgs.function.InnerFunction;
import de.neemann.digital.lang.Lang;
import java.io.IOException;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -25,6 +27,7 @@ import java.util.Objects;
public class ResolveGenerics {
private final HashMap map;
+ private LibraryInterface library;
/**
* Creates a new instance
@@ -44,6 +47,7 @@ public class ResolveGenerics {
* @throws ElementNotFoundException ElementNotFoundException
*/
public CircuitHolder resolveCircuit(VisualElement visualElement, Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException {
+ this.library = library;
final Args args = createArgs(visualElement, circuit);
Circuit c = circuit.createDeepCopy();
@@ -53,18 +57,17 @@ public class ResolveGenerics {
if (!gen.isEmpty()) {
boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom();
Statement genS = getStatement(gen);
+ Context mod = new Context();
if (isCustom) {
- Context mod = new Context()
- .declareVar("args", args)
+ mod.declareVar("args", args)
.declareFunc("setCircuit", new SetCircuitFunc(ve));
genS.execute(mod);
- ve.setGenericArgs(mod);
} else {
- Context mod = new Context()
- .declareVar("args", args)
+ mod.declareVar("args", args)
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
genS.execute(mod);
}
+ ve.setGenericArgs(mod);
}
} catch (HGSEvalException | ParserException | IOException e) {
final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), e);
@@ -158,7 +161,7 @@ public class ResolveGenerics {
/**
* Holds the circuit and the args that created that circuit.
*/
- public static final class CircuitHolder {
+ public final class CircuitHolder {
private final Circuit circuit;
private final Args args;
@@ -180,6 +183,70 @@ public class ResolveGenerics {
public Args getArgs() {
return args;
}
+
+ /**
+ * Converts a circuit that is only suitable for creating a model
+ * to a circuit that can also be edited and saved.
+ *
+ * @return this for chained calls
+ */
+ public CircuitHolder cleanupConcreteCircuit() {
+ for (VisualElement gic : circuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION)))
+ circuit.delete(gic);
+ for (VisualElement v : circuit.getElements()) {
+ try {
+ boolean isCustom = library.getElementType(v.getElementName(), v.getElementAttributes()).isCustom();
+ if (isCustom)
+ v.getElementAttributes().set(Keys.GENERIC, createGenericCode(v.getGenericArgs()));
+ else
+ v.getElementAttributes().set(Keys.GENERIC, "");
+ } catch (ElementNotFoundException e) {
+ // can not happen
+ e.printStackTrace();
+ }
+ v.setGenericArgs(null);
+ }
+
+ circuit.getAttributes().set(Keys.IS_GENERIC, false);
+
+ return this;
+ }
+ }
+
+ private static String createGenericCode(Context args) {
+ StringBuilder sb = new StringBuilder();
+ HashSet contentSet = new HashSet<>();
+ addVal(sb, "", args, contentSet);
+ return sb.toString();
+ }
+
+ private static void addVal(StringBuilder sb, String key, Object val, HashSet contentSet) {
+ if (contentSet.contains(key))
+ return;
+
+ if (val instanceof InnerFunction)
+ return;
+
+ if (val instanceof Context) {
+ Context c = (Context) val;
+ for (String k : c.getKeySet()) {
+ Object v = c.hgsMapGet(k);
+ if (!(v instanceof Args))
+ addVal(sb, k, v, contentSet);
+ }
+ for (String k : c.getKeySet()) {
+ Object v = c.hgsMapGet(k);
+ if (v instanceof Args)
+ addVal(sb, k, ((Args) v).args, contentSet);
+ }
+ return;
+ }
+
+ contentSet.add(key);
+ if (val instanceof String)
+ sb.append(key).append(":=\"").append(val).append("\";\n");
+ else
+ sb.append(key).append(":=").append(val).append(";\n");
}
private static final class SetCircuitFunc extends Function {
diff --git a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
index b138f6dc1..28515e558 100644
--- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
+++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
@@ -1158,14 +1158,15 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
try {
attributeDialog.fireOk();
ElementAttributes modified = attributeDialog.getModifiedAttributes();
- if (modified != null && !isLocked()) {
+ if (modified != null && !isLocked() && !modified.equals(element.getElementAttributes())) {
Modification mod = new ModifyAttributes(element, modified);
modify(checkNetRename(element, modified, mod));
}
- Circuit concreteCircuit = new ResolveGenerics().resolveCircuit(element, getCircuit(), library).getCircuit();
- for (VisualElement gic : concreteCircuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION)))
- concreteCircuit.delete(gic);
- concreteCircuit.getAttributes().set(Keys.IS_GENERIC, false);
+
+ Circuit concreteCircuit = new ResolveGenerics()
+ .resolveCircuit(element, getCircuit(), library)
+ .cleanupConcreteCircuit()
+ .getCircuit();
new Main.MainBuilder()
.setParent(parent)
diff --git a/src/main/java/de/neemann/digital/hdl/hgs/Context.java b/src/main/java/de/neemann/digital/hdl/hgs/Context.java
index e44cf1b57..a563c0371 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/Context.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/Context.java
@@ -281,6 +281,13 @@ public class Context implements HGSMap {
return map.get(key);
}
+ /**
+ * @return the set of all contained values
+ */
+ public HashSet getKeySet() {
+ return new HashSet<>(map.keySet());
+ }
+
private static final class FunctionPrint extends InnerFunction {
private FunctionPrint() {
super(-1);
diff --git a/src/main/java/de/neemann/digital/hdl/hgs/Parser.java b/src/main/java/de/neemann/digital/hdl/hgs/Parser.java
index 9c0896369..2c24b4f84 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/Parser.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/Parser.java
@@ -637,14 +637,14 @@ public class Parser {
}
}
- private static class StructLiteral implements Expression {
+ private static final class StructLiteral implements Expression {
private final HashMap map;
private StructLiteral() {
map = new HashMap<>();
}
- public void add(String key, Expression exp) {
+ private void add(String key, Expression exp) {
map.put(key, exp);
}