mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-16 16:34:47 -04:00
fixes the concrete circuit creation; see #543
This commit is contained in:
parent
287a6a9975
commit
6c65bccd2e
@ -81,20 +81,20 @@
|
|||||||
<entry>
|
<entry>
|
||||||
<string>generic</string>
|
<string>generic</string>
|
||||||
<string>if (args.direction="right") {
|
<string>if (args.direction="right") {
|
||||||
export circuit:="shift-fixed-right-inc.dig";
|
export circuit:="shift-fixed-right-inc.dig";
|
||||||
} else {
|
} else {
|
||||||
if (args.direction="arith") {
|
if (args.direction="arith") {
|
||||||
export circuit:="shift-fixed-arith-right-inc.dig";
|
export circuit:="shift-fixed-arith-right-inc.dig";
|
||||||
} else {
|
} else {
|
||||||
if (args.direction="left") {
|
if (args.direction="left") {
|
||||||
export circuit:="shift-fixed-left-inc.dig";
|
export circuit:="shift-fixed-left-inc.dig";
|
||||||
} else {
|
} else {
|
||||||
panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!");
|
panic("only \"left\", \"right\" or \"arith\" is allowed as direction, not \""+args.direction+"\"!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export shiftBits:=bitsNeededFor(args.dataBits-1);</string>
|
shiftBits:=bitsNeededFor(args.dataBits-1);</string>
|
||||||
</entry>
|
</entry>
|
||||||
</elementAttributes>
|
</elementAttributes>
|
||||||
<pos x="420" y="120"/>
|
<pos x="420" y="120"/>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<elementAttributes>
|
<elementAttributes>
|
||||||
<entry>
|
<entry>
|
||||||
<string>generic</string>
|
<string>generic</string>
|
||||||
<string>export shift := 1<<(args.shiftBits-1);
|
<string>shift := 1<<(args.shiftBits-1);
|
||||||
setCircuit(args.circuit);</string>
|
setCircuit(args.circuit);</string>
|
||||||
</entry>
|
</entry>
|
||||||
</elementAttributes>
|
</elementAttributes>
|
||||||
@ -87,8 +87,8 @@ setCircuit(args.circuit);</string>
|
|||||||
<entry>
|
<entry>
|
||||||
<string>generic</string>
|
<string>generic</string>
|
||||||
<string>if (args.shiftBits=2) {
|
<string>if (args.shiftBits=2) {
|
||||||
export shift := 1;
|
export shift := 1;
|
||||||
setCircuit(args.circuit);
|
setCircuit(args.circuit);
|
||||||
} else {
|
} else {
|
||||||
export shiftBits := args.shiftBits-1;
|
export shiftBits := args.shiftBits-1;
|
||||||
}</string>
|
}</string>
|
||||||
|
@ -12,10 +12,12 @@ import de.neemann.digital.draw.elements.Circuit;
|
|||||||
import de.neemann.digital.draw.elements.VisualElement;
|
import de.neemann.digital.draw.elements.VisualElement;
|
||||||
import de.neemann.digital.hdl.hgs.*;
|
import de.neemann.digital.hdl.hgs.*;
|
||||||
import de.neemann.digital.hdl.hgs.function.Function;
|
import de.neemann.digital.hdl.hgs.function.Function;
|
||||||
|
import de.neemann.digital.hdl.hgs.function.InnerFunction;
|
||||||
import de.neemann.digital.lang.Lang;
|
import de.neemann.digital.lang.Lang;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@ -25,6 +27,7 @@ import java.util.Objects;
|
|||||||
public class ResolveGenerics {
|
public class ResolveGenerics {
|
||||||
|
|
||||||
private final HashMap<String, Statement> map;
|
private final HashMap<String, Statement> map;
|
||||||
|
private LibraryInterface library;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -44,6 +47,7 @@ public class ResolveGenerics {
|
|||||||
* @throws ElementNotFoundException ElementNotFoundException
|
* @throws ElementNotFoundException ElementNotFoundException
|
||||||
*/
|
*/
|
||||||
public CircuitHolder resolveCircuit(VisualElement visualElement, Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException {
|
public CircuitHolder resolveCircuit(VisualElement visualElement, Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException {
|
||||||
|
this.library = library;
|
||||||
final Args args = createArgs(visualElement, circuit);
|
final Args args = createArgs(visualElement, circuit);
|
||||||
|
|
||||||
Circuit c = circuit.createDeepCopy();
|
Circuit c = circuit.createDeepCopy();
|
||||||
@ -53,18 +57,17 @@ public class ResolveGenerics {
|
|||||||
if (!gen.isEmpty()) {
|
if (!gen.isEmpty()) {
|
||||||
boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom();
|
boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom();
|
||||||
Statement genS = getStatement(gen);
|
Statement genS = getStatement(gen);
|
||||||
|
Context mod = new Context();
|
||||||
if (isCustom) {
|
if (isCustom) {
|
||||||
Context mod = new Context()
|
mod.declareVar("args", args)
|
||||||
.declareVar("args", args)
|
|
||||||
.declareFunc("setCircuit", new SetCircuitFunc(ve));
|
.declareFunc("setCircuit", new SetCircuitFunc(ve));
|
||||||
genS.execute(mod);
|
genS.execute(mod);
|
||||||
ve.setGenericArgs(mod);
|
|
||||||
} else {
|
} else {
|
||||||
Context mod = new Context()
|
mod.declareVar("args", args)
|
||||||
.declareVar("args", args)
|
|
||||||
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
|
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
|
||||||
genS.execute(mod);
|
genS.execute(mod);
|
||||||
}
|
}
|
||||||
|
ve.setGenericArgs(mod);
|
||||||
}
|
}
|
||||||
} catch (HGSEvalException | ParserException | IOException e) {
|
} catch (HGSEvalException | ParserException | IOException e) {
|
||||||
final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), 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.
|
* 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 Circuit circuit;
|
||||||
private final Args args;
|
private final Args args;
|
||||||
|
|
||||||
@ -180,6 +183,70 @@ public class ResolveGenerics {
|
|||||||
public Args getArgs() {
|
public Args getArgs() {
|
||||||
return args;
|
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<String> contentSet = new HashSet<>();
|
||||||
|
addVal(sb, "", args, contentSet);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addVal(StringBuilder sb, String key, Object val, HashSet<String> 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 {
|
private static final class SetCircuitFunc extends Function {
|
||||||
|
@ -1158,14 +1158,15 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
|||||||
try {
|
try {
|
||||||
attributeDialog.fireOk();
|
attributeDialog.fireOk();
|
||||||
ElementAttributes modified = attributeDialog.getModifiedAttributes();
|
ElementAttributes modified = attributeDialog.getModifiedAttributes();
|
||||||
if (modified != null && !isLocked()) {
|
if (modified != null && !isLocked() && !modified.equals(element.getElementAttributes())) {
|
||||||
Modification<Circuit> mod = new ModifyAttributes(element, modified);
|
Modification<Circuit> mod = new ModifyAttributes(element, modified);
|
||||||
modify(checkNetRename(element, modified, mod));
|
modify(checkNetRename(element, modified, mod));
|
||||||
}
|
}
|
||||||
Circuit concreteCircuit = new ResolveGenerics().resolveCircuit(element, getCircuit(), library).getCircuit();
|
|
||||||
for (VisualElement gic : concreteCircuit.getElements(v -> v.equalsDescription(GenericInitCode.DESCRIPTION)))
|
Circuit concreteCircuit = new ResolveGenerics()
|
||||||
concreteCircuit.delete(gic);
|
.resolveCircuit(element, getCircuit(), library)
|
||||||
concreteCircuit.getAttributes().set(Keys.IS_GENERIC, false);
|
.cleanupConcreteCircuit()
|
||||||
|
.getCircuit();
|
||||||
|
|
||||||
new Main.MainBuilder()
|
new Main.MainBuilder()
|
||||||
.setParent(parent)
|
.setParent(parent)
|
||||||
|
@ -281,6 +281,13 @@ public class Context implements HGSMap {
|
|||||||
return map.get(key);
|
return map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the set of all contained values
|
||||||
|
*/
|
||||||
|
public HashSet<String> getKeySet() {
|
||||||
|
return new HashSet<>(map.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
private static final class FunctionPrint extends InnerFunction {
|
private static final class FunctionPrint extends InnerFunction {
|
||||||
private FunctionPrint() {
|
private FunctionPrint() {
|
||||||
super(-1);
|
super(-1);
|
||||||
|
@ -637,14 +637,14 @@ public class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StructLiteral implements Expression {
|
private static final class StructLiteral implements Expression {
|
||||||
private final HashMap<String, Expression> map;
|
private final HashMap<String, Expression> map;
|
||||||
|
|
||||||
private StructLiteral() {
|
private StructLiteral() {
|
||||||
map = new HashMap<>();
|
map = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(String key, Expression exp) {
|
private void add(String key, Expression exp) {
|
||||||
map.put(key, exp);
|
map.put(key, exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user