diff --git a/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java b/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java
index 786ea641b..bdd251c33 100644
--- a/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java
+++ b/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java
@@ -18,11 +18,15 @@ import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.draw.model.NetList;
import de.neemann.digital.hdl.hgs.*;
import de.neemann.digital.hdl.hgs.function.Function;
+import de.neemann.digital.hdl.hgs.refs.Reference;
+import de.neemann.digital.hdl.hgs.refs.ReferenceToStruct;
+import de.neemann.digital.hdl.hgs.refs.ReferenceToVar;
import de.neemann.digital.lang.Lang;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
+import java.util.TreeSet;
/**
* The description of a nested element.
@@ -36,6 +40,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
private String description;
private NetList netList;
private boolean isCustom = true;
+ private String declarationDefault;
/**
* Creates a new element
@@ -53,7 +58,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
addAttribute(Keys.ROTATE);
addAttribute(Keys.LABEL);
addAttribute(Keys.SHAPE_TYPE);
- if (circuit.getAttributes().get(Keys.IS_GENERIC))
+ if (isGeneric())
addAttribute(Keys.GENERIC);
}
@@ -118,7 +123,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
if (depth > MAX_DEPTH)
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
- if (circuit.getAttributes().get(Keys.IS_GENERIC)) {
+ if (isGeneric()) {
try {
Context args;
if (containingVisualElement != null) {
@@ -201,4 +206,51 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
isCustom = false;
return this;
}
+
+ /**
+ * @return the generics field default value
+ */
+ public String getDeclarationDefault() {
+ if (declarationDefault == null)
+ declarationDefault = createDeclarationDefault();
+ return declarationDefault;
+ }
+
+ private String createDeclarationDefault() {
+ TreeSet nameSet = new TreeSet<>();
+ for (VisualElement ve : circuit.getElements()) {
+ String gen = ve.getElementAttributes().get(Keys.GENERIC).trim();
+ try {
+ if (!gen.isEmpty()) {
+ Parser p = new Parser(gen);
+ p.enableRefReadCollection();
+ p.parse(false);
+ for (Reference r : p.getRefsRead()) {
+ if (r instanceof ReferenceToStruct) {
+ ReferenceToStruct st = (ReferenceToStruct) r;
+ if (st.getParent() instanceof ReferenceToVar) {
+ ReferenceToVar var = (ReferenceToVar) st.getParent();
+ if (var.getName().equals("args")) {
+ nameSet.add(st.getName());
+ }
+ }
+ }
+ }
+ }
+ } catch (ParserException | IOException e) {
+ return "";
+ }
+ }
+ StringBuilder sb = new StringBuilder();
+ for (String name : nameSet)
+ sb.append(name).append(" := ;\n");
+ return sb.toString();
+ }
+
+ /**
+ * @return true if the circuit is generic
+ */
+ public boolean isGeneric() {
+ return circuit.getAttributes().get(Keys.IS_GENERIC);
+ }
}
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 b74fa95e8..2f3bc8a24 100644
--- a/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
+++ b/src/main/java/de/neemann/digital/gui/components/CircuitComponent.java
@@ -1023,10 +1023,19 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
try {
ArrayList list = getAttributeList(element);
if (list.size() > 0) {
+ ElementTypeDescription elementType = library.getElementType(element.getElementName());
+
+ if (elementType instanceof ElementTypeDescriptionCustom) {
+ ElementTypeDescriptionCustom customDescr = (ElementTypeDescriptionCustom) elementType;
+ if (customDescr.isGeneric()) {
+ if (element.getElementAttributes().get(Keys.GENERIC).isEmpty())
+ element.getElementAttributes().set(Keys.GENERIC, customDescr.getDeclarationDefault());
+ }
+ }
+
Point p = new Point(e.getX(), e.getY());
SwingUtilities.convertPointToScreen(p, CircuitComponent.this);
AttributeDialog attributeDialog = new AttributeDialog(parent, p, list, element.getElementAttributes()).setVisualElement(element);
- ElementTypeDescription elementType = library.getElementType(element.getElementName());
if (elementType instanceof ElementTypeDescriptionCustom) {
attributeDialog.addButton(Lang.get("attr_openCircuitLabel"), new ToolTipAction(Lang.get("attr_openCircuit")) {
@Override
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 5c62c3599..03bac503d 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/Parser.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/Parser.java
@@ -5,6 +5,7 @@
*/
package de.neemann.digital.hdl.hgs;
+import de.neemann.digital.builder.tt2.TT2Exporter;
import de.neemann.digital.core.Bits;
import de.neemann.digital.hdl.hgs.function.FirstClassFunction;
import de.neemann.digital.hdl.hgs.function.FirstClassFunctionCall;
@@ -55,6 +56,7 @@ public class Parser {
}
+ private ArrayList refRead;
private final Tokenizer tok;
private Context staticContext;
@@ -78,6 +80,20 @@ public class Parser {
staticContext = new Context();
}
+ /**
+ * If called all read references are collected.
+ */
+ public void enableRefReadCollection() {
+ refRead = new ArrayList<>();
+ }
+
+ /**
+ * @return returns the references read
+ */
+ public ArrayList getRefsRead() {
+ return refRead;
+ }
+
private Statement lino(Statement statement) {
if (statement instanceof StatementWithLine)
return statement;
@@ -517,6 +533,8 @@ public class Parser {
case IDENT:
String name = tok.getIdent();
Reference r = parseReference(name);
+ if (refRead != null)
+ refRead.add(r);
return r::get;
case NUMBER:
long num = convToLong(tok.getIdent());
diff --git a/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToStruct.java b/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToStruct.java
index cedf2935d..17c101bd5 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToStruct.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToStruct.java
@@ -53,4 +53,17 @@ public class ReferenceToStruct implements Reference {
return value;
}
+ /**
+ * @return the parent reference
+ */
+ public Reference getParent() {
+ return parent;
+ }
+
+ /**
+ * @return the struct field name
+ */
+ public String getName() {
+ return name;
+ }
}
diff --git a/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToVar.java b/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToVar.java
index a8e45926e..8ba8f4ffd 100644
--- a/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToVar.java
+++ b/src/main/java/de/neemann/digital/hdl/hgs/refs/ReferenceToVar.java
@@ -42,4 +42,11 @@ public class ReferenceToVar implements Reference {
public Object get(Context context) throws HGSEvalException {
return context.getVar(name);
}
+
+ /**
+ * @return the var name
+ */
+ public String getName() {
+ return name;
+ }
}
diff --git a/src/test/resources/dig/test/generics/mainMem.dig b/src/test/resources/dig/test/generics/mainMem.dig
index 4494fc432..107545923 100644
--- a/src/test/resources/dig/test/generics/mainMem.dig
+++ b/src/test/resources/dig/test/generics/mainMem.dig
@@ -15,7 +15,7 @@
16
-
+
In
@@ -80,8 +80,11 @@ end loop
# read data
loop(n,1<<8)
-C 0 (n) 0 (n+2)
-end loop
+0 0 (n) 0 (n+2)
+end loop
+
+0 0 (1<<8) 0 (2)
+
@@ -92,8 +95,8 @@ end loop
generic
- bits:=int(16);
-addr:=8;
+ dataBits := 16;
+addrBits := 8;
@@ -105,8 +108,8 @@ addr:=8;
-
-
+
+
@@ -116,6 +119,10 @@ addr:=8;
+
+
+
+
@@ -140,6 +147,10 @@ addr:=8;
+
+
+
+
diff --git a/src/test/resources/dig/test/generics/memLeaf.dig b/src/test/resources/dig/test/generics/memLeaf.dig
index 34ea4e024..b327bf6fa 100644
--- a/src/test/resources/dig/test/generics/memLeaf.dig
+++ b/src/test/resources/dig/test/generics/memLeaf.dig
@@ -13,7 +13,7 @@
generic
- this.Bits=args.bits;
+ this.Bits=int(args.dataBits);
@@ -23,7 +23,7 @@
generic
- this.Bits=args.bits;
+ this.Bits=int(args.dataBits);
@@ -33,7 +33,7 @@
generic
- this.Bits=args.bits;
+ this.Bits=int(args.dataBits);
diff --git a/src/test/resources/dig/test/generics/memNode.dig b/src/test/resources/dig/test/generics/memNode.dig
index 6994fd7ae..dc3f52011 100644
--- a/src/test/resources/dig/test/generics/memNode.dig
+++ b/src/test/resources/dig/test/generics/memNode.dig
@@ -68,7 +68,7 @@
generic
if (isPresent(args)) {
- this.Bits=args.bits;
+ this.Bits=int(args.dataBits);
}
@@ -106,12 +106,12 @@
generic
if (isPresent(args)) {
- if (args.addr<2) {
+ if (args.addrBits<2) {
panic("at least two address bits are necessary!");
}
- this.'Input Splitting'=""+args.addr;
- this.'Output Splitting'=(args.addr-1)+",1";
+ this.'Input Splitting'=""+args.addrBits;
+ this.'Output Splitting'=(args.addrBits-1)+",1";
}
@@ -123,13 +123,13 @@
generic
if (isPresent(args)) {
- export bits:=args.bits;
- export addr:=args.addr-1;
- if (args.addr>2) {
+ export dataBits:=args.dataBits;
+ export addrBits:=args.addrBits-1;
+ if (args.addrBits>2) {
setCircuit("memNode.dig");
}
} else {
- export bits:=int(1);
+ export dataBits:=int(1);
}
@@ -141,13 +141,13 @@
generic
if (isPresent(args)) {
- export bits:=args.bits;
- export addr:=args.addr-1;
- if (args.addr>2) {
+ export dataBits:=args.dataBits;
+ export addrBits:=args.addrBits-1;
+ if (args.addrBits>2) {
setCircuit("memNode.dig");
}
} else {
- export bits:=int(1);
+ export dataBits:=int(1);
}
@@ -161,14 +161,14 @@
-
+
-
+
@@ -185,10 +185,10 @@
-
+
-
+
@@ -212,7 +212,7 @@
-
+
@@ -224,7 +224,7 @@
-
+
@@ -244,7 +244,7 @@
-
+
@@ -268,25 +268,25 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file