mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-13 06:49:36 -04:00
nested generics are working
This commit is contained in:
parent
665ae6860e
commit
b64ec33b7c
@ -14,6 +14,7 @@ import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.draw.library.LibraryInterface;
|
||||
import de.neemann.digital.hdl.hgs.*;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
@ -121,7 +122,7 @@ public class SubstituteLibrary implements LibraryInterface {
|
||||
|
||||
private static final class Substitute implements SubstituteInterface {
|
||||
private final String filename;
|
||||
private ElementLibrary.ElementTypeDescriptionCustom typeDescriptionCustom;
|
||||
private ElementTypeDescriptionCustom typeDescriptionCustom;
|
||||
|
||||
private Substitute(String filename) {
|
||||
this.filename = filename;
|
||||
|
@ -21,6 +21,7 @@ import de.neemann.digital.core.switching.PFET;
|
||||
import de.neemann.digital.core.wiring.*;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.gui.components.data.DummyElement;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import de.neemann.digital.testing.TestCaseElement;
|
||||
@ -149,8 +150,8 @@ public class Stats {
|
||||
|
||||
int transistors = 0;
|
||||
Circuit childCircuit = null;
|
||||
if (description instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
ElementLibrary.ElementTypeDescriptionCustom c = (ElementLibrary.ElementTypeDescriptionCustom) description;
|
||||
if (description instanceof ElementTypeDescriptionCustom) {
|
||||
ElementTypeDescriptionCustom c = (ElementTypeDescriptionCustom) description;
|
||||
childCircuit = c.getCircuit();
|
||||
transistors = childCircuit.getAttributes().get(Keys.TRANSISTORS);
|
||||
if (transistors > 0)
|
||||
|
@ -13,6 +13,7 @@ import de.neemann.digital.draw.shapes.*;
|
||||
import de.neemann.digital.draw.shapes.Shape;
|
||||
import de.neemann.digital.draw.shapes.custom.CustomShape;
|
||||
import de.neemann.digital.gui.components.CircuitComponent;
|
||||
import de.neemann.digital.hdl.hgs.Context;
|
||||
import de.neemann.gui.Screen;
|
||||
|
||||
import javax.swing.*;
|
||||
@ -39,6 +40,7 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
|
||||
// shapes are recreated if attributes are changed, therefore a factory is necessary and not only a simple shape!
|
||||
private transient ShapeFactory shapeFactory;
|
||||
private transient Transform transform;
|
||||
private transient Context genericArgs;
|
||||
|
||||
// these fields are stored to disk
|
||||
private final String elementName;
|
||||
@ -479,4 +481,19 @@ public class VisualElement implements Drawable, Movable, AttributeListener {
|
||||
public boolean isDecoratingShape() {
|
||||
return getShape() instanceof DecoratingShape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the generic arguments for this element
|
||||
* @param genericArgs the arguments
|
||||
*/
|
||||
public void setGenericArgs(Context genericArgs) {
|
||||
this.genericArgs = genericArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the generic arguments for this element
|
||||
*/
|
||||
public Context getGenericArgs() {
|
||||
return genericArgs;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import de.neemann.digital.draw.model.ModelCreator;
|
||||
* existing circuit. So you can build hierarchical circuits.
|
||||
*/
|
||||
public class CustomElement implements Element {
|
||||
private final ElementLibrary.ElementTypeDescriptionCustom descriptionCustom;
|
||||
private final ElementTypeDescriptionCustom descriptionCustom;
|
||||
private final ElementLibrary library;
|
||||
|
||||
/**
|
||||
@ -29,7 +29,7 @@ public class CustomElement implements Element {
|
||||
* @param descriptionCustom the inner circuit
|
||||
* @param library the library to use.
|
||||
*/
|
||||
public CustomElement(ElementLibrary.ElementTypeDescriptionCustom descriptionCustom, ElementLibrary library) {
|
||||
public CustomElement(ElementTypeDescriptionCustom descriptionCustom, ElementLibrary library) {
|
||||
this.descriptionCustom = descriptionCustom;
|
||||
this.library = library;
|
||||
}
|
||||
@ -40,14 +40,15 @@ public class CustomElement implements Element {
|
||||
*
|
||||
* @param subName name of the circuit, used to name unique elements
|
||||
* @param depth recursion depth, used to detect a circuit which contains itself
|
||||
* @param errorVisualElement visual element used for error indicating
|
||||
* @param containingVisualElement the containing visual element
|
||||
* @return the {@link ModelCreator}
|
||||
* @throws PinException PinException
|
||||
* @throws NodeException NodeException
|
||||
* @throws ElementNotFoundException ElementNotFoundException
|
||||
*/
|
||||
public ModelCreator getModelCreator(String subName, int depth, VisualElement containingVisualElement) throws PinException, NodeException, ElementNotFoundException {
|
||||
return descriptionCustom.getModelCreator(subName, depth, containingVisualElement, library);
|
||||
public ModelCreator getModelCreator(String subName, int depth, VisualElement errorVisualElement, VisualElement containingVisualElement) throws PinException, NodeException, ElementNotFoundException {
|
||||
return descriptionCustom.getModelCreator(subName, depth, errorVisualElement, containingVisualElement, library);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,13 +5,10 @@
|
||||
*/
|
||||
package de.neemann.digital.draw.library;
|
||||
|
||||
import de.neemann.digital.analyse.SubstituteLibrary;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.arithmetic.*;
|
||||
import de.neemann.digital.core.arithmetic.Comparator;
|
||||
import de.neemann.digital.core.basic.*;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.ElementFactory;
|
||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.core.extern.External;
|
||||
@ -27,9 +24,6 @@ import de.neemann.digital.core.wiring.*;
|
||||
import de.neemann.digital.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.Tunnel;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.model.ModelCreator;
|
||||
import de.neemann.digital.draw.model.NetList;
|
||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||
import de.neemann.digital.gui.Settings;
|
||||
import de.neemann.digital.gui.components.data.DummyElement;
|
||||
@ -37,7 +31,6 @@ import de.neemann.digital.gui.components.graphics.GraphicCard;
|
||||
import de.neemann.digital.gui.components.graphics.LedMatrix;
|
||||
import de.neemann.digital.gui.components.terminal.Keyboard;
|
||||
import de.neemann.digital.gui.components.terminal.Terminal;
|
||||
import de.neemann.digital.hdl.hgs.*;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import de.neemann.digital.testing.TestCaseElement;
|
||||
import org.slf4j.Logger;
|
||||
@ -619,141 +612,6 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* The description of a nested element.
|
||||
* This is a complete circuit which is used as a element.
|
||||
*/
|
||||
public static final class ElementTypeDescriptionCustom extends ElementTypeDescription {
|
||||
private static final int MAX_DEPTH = 30;
|
||||
private final File file;
|
||||
private final Circuit circuit;
|
||||
private final HashMap<String, Statement> map;
|
||||
private String description;
|
||||
private NetList netList;
|
||||
|
||||
/**
|
||||
* Creates a new element
|
||||
*
|
||||
* @param file the file which is loaded
|
||||
* @param circuit the circuit
|
||||
* @throws PinException PinException
|
||||
*/
|
||||
private ElementTypeDescriptionCustom(File file, Circuit circuit) throws PinException {
|
||||
super(file.getName(), (ElementFactory) null, circuit.getInputNames());
|
||||
this.file = file;
|
||||
this.circuit = circuit;
|
||||
map = new HashMap<>();
|
||||
setShortName(file.getName());
|
||||
addAttribute(Keys.ROTATE);
|
||||
addAttribute(Keys.LABEL);
|
||||
addAttribute(Keys.SHAPE_TYPE);
|
||||
if (circuit.getAttributes().get(Keys.IS_GENERIC))
|
||||
addAttribute(Keys.GENERIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename
|
||||
* The returned file is opened if the user wants to modify the element
|
||||
*
|
||||
* @return the filename
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the elements attributes
|
||||
*/
|
||||
public ElementAttributes getAttributes() {
|
||||
return circuit.getAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the circuit
|
||||
*/
|
||||
public Circuit getCircuit() {
|
||||
return circuit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom description for this field
|
||||
*
|
||||
* @param description the description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(ElementAttributes elementAttributes) {
|
||||
if (description != null)
|
||||
return description;
|
||||
else
|
||||
return super.getDescription(elementAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link ModelCreator} of this circuit.
|
||||
* Every time this method is called a new {@link ModelCreator} is created.
|
||||
*
|
||||
* @param subName name of the circuit, used to name unique elements
|
||||
* @param depth recursion depth, used to detect a circuit which contains itself
|
||||
* @param containingVisualElement the containing visual element
|
||||
* @param library the library used
|
||||
* @return the {@link ModelCreator}
|
||||
* @throws PinException PinException
|
||||
* @throws NodeException NodeException
|
||||
* @throws ElementNotFoundException ElementNotFoundException
|
||||
*/
|
||||
public ModelCreator getModelCreator(String subName, int depth, VisualElement containingVisualElement, ElementLibrary library) throws PinException, NodeException, ElementNotFoundException {
|
||||
if (netList == null)
|
||||
netList = new NetList(circuit);
|
||||
|
||||
if (depth > MAX_DEPTH)
|
||||
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
|
||||
|
||||
if (circuit.getAttributes().get(Keys.IS_GENERIC)) {
|
||||
String argsCode = containingVisualElement.getElementAttributes().get(Keys.GENERIC);
|
||||
try {
|
||||
Statement s = getStatement(argsCode);
|
||||
Context args = new Context();
|
||||
s.execute(args);
|
||||
|
||||
Circuit c = circuit.createDeepCopy();
|
||||
for (VisualElement ve : c.getElements()) {
|
||||
String gen = ve.getElementAttributes().get(Keys.GENERIC).trim();
|
||||
if (!gen.isEmpty()) {
|
||||
|
||||
Statement genS = getStatement(gen);
|
||||
|
||||
Context mod = new Context()
|
||||
.declareVar("args", args)
|
||||
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
|
||||
genS.execute(mod);
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelCreator(c, library, true, new NetList(netList, containingVisualElement), subName, depth, containingVisualElement);
|
||||
|
||||
} catch (IOException | ParserException | HGSEvalException e) {
|
||||
throw new NodeException(Lang.get("err_parsingGenericsCode"), e);
|
||||
}
|
||||
} else {
|
||||
return new ModelCreator(circuit, library, true, new NetList(netList, containingVisualElement), subName, depth, containingVisualElement);
|
||||
}
|
||||
}
|
||||
|
||||
private Statement getStatement(String code) throws IOException, ParserException {
|
||||
Statement genS = map.get(code);
|
||||
if (genS == null) {
|
||||
genS = new Parser(code).parse(false);
|
||||
map.put(code, genS);
|
||||
}
|
||||
return genS;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to store a elements name and its position in the elements menu.
|
||||
|
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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.draw.library;
|
||||
|
||||
import de.neemann.digital.analyse.SubstituteLibrary;
|
||||
import de.neemann.digital.core.NodeException;
|
||||
import de.neemann.digital.core.element.ElementAttributes;
|
||||
import de.neemann.digital.core.element.ElementFactory;
|
||||
import de.neemann.digital.core.element.ElementTypeDescription;
|
||||
import de.neemann.digital.core.element.Keys;
|
||||
import de.neemann.digital.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.model.ModelCreator;
|
||||
import de.neemann.digital.draw.model.NetList;
|
||||
import de.neemann.digital.hdl.hgs.*;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* The description of a nested element.
|
||||
* This is a complete circuit which is used as a element.
|
||||
*/
|
||||
public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
|
||||
private static final int MAX_DEPTH = 30;
|
||||
private final File file;
|
||||
private final Circuit circuit;
|
||||
private final HashMap<String, Statement> map;
|
||||
private String description;
|
||||
private NetList netList;
|
||||
|
||||
/**
|
||||
* Creates a new element
|
||||
*
|
||||
* @param file the file which is loaded
|
||||
* @param circuit the circuit
|
||||
* @throws PinException PinException
|
||||
*/
|
||||
ElementTypeDescriptionCustom(File file, Circuit circuit) throws PinException {
|
||||
super(file.getName(), (ElementFactory) null, circuit.getInputNames());
|
||||
this.file = file;
|
||||
this.circuit = circuit;
|
||||
map = new HashMap<>();
|
||||
setShortName(file.getName());
|
||||
addAttribute(Keys.ROTATE);
|
||||
addAttribute(Keys.LABEL);
|
||||
addAttribute(Keys.SHAPE_TYPE);
|
||||
if (circuit.getAttributes().get(Keys.IS_GENERIC))
|
||||
addAttribute(Keys.GENERIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename
|
||||
* The returned file is opened if the user wants to modify the element
|
||||
*
|
||||
* @return the filename
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the elements attributes
|
||||
*/
|
||||
public ElementAttributes getAttributes() {
|
||||
return circuit.getAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the circuit
|
||||
*/
|
||||
public Circuit getCircuit() {
|
||||
return circuit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom description for this field
|
||||
*
|
||||
* @param description the description
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(ElementAttributes elementAttributes) {
|
||||
if (description != null)
|
||||
return description;
|
||||
else
|
||||
return super.getDescription(elementAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link ModelCreator} of this circuit.
|
||||
* Every time this method is called a new {@link ModelCreator} is created.
|
||||
*
|
||||
* @param subName name of the circuit, used to name unique elements
|
||||
* @param depth recursion depth, used to detect a circuit which contains itself
|
||||
* @param containingVisualElement the containing visual element
|
||||
* @param library the library used
|
||||
* @return the {@link ModelCreator}
|
||||
* @throws PinException PinException
|
||||
* @throws NodeException NodeException
|
||||
* @throws ElementNotFoundException ElementNotFoundException
|
||||
*/
|
||||
ModelCreator getModelCreator(String subName, int depth, VisualElement errorVisualElement, VisualElement containingVisualElement, ElementLibrary library) throws PinException, NodeException, ElementNotFoundException {
|
||||
if (netList == null)
|
||||
netList = new NetList(circuit);
|
||||
|
||||
if (depth > MAX_DEPTH)
|
||||
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
|
||||
|
||||
if (circuit.getAttributes().get(Keys.IS_GENERIC)) {
|
||||
try {
|
||||
Context args;
|
||||
if (containingVisualElement != null) {
|
||||
args = containingVisualElement.getGenericArgs();
|
||||
if (args==null) {
|
||||
String argsCode = containingVisualElement.getElementAttributes().get(Keys.GENERIC);
|
||||
Statement s = getStatement(argsCode);
|
||||
args = new Context();
|
||||
if (containingVisualElement.getGenericArgs() != null)
|
||||
args.declareVar("args", containingVisualElement.getGenericArgs());
|
||||
s.execute(args);
|
||||
}
|
||||
} else
|
||||
args = new Context();
|
||||
|
||||
Circuit c = circuit.createDeepCopy();
|
||||
for (VisualElement ve : c.getElements()) {
|
||||
String gen = ve.getElementAttributes().get(Keys.GENERIC).trim();
|
||||
if (!gen.isEmpty()) {
|
||||
boolean isCustom = library.getElementType(ve.getElementName()) instanceof ElementTypeDescriptionCustom;
|
||||
Statement genS = getStatement(gen);
|
||||
if (isCustom) {
|
||||
Context mod = new Context()
|
||||
.declareVar("args", args);
|
||||
genS.execute(mod);
|
||||
ve.setGenericArgs(mod);
|
||||
} else {
|
||||
Context mod = new Context()
|
||||
.declareVar("args", args)
|
||||
.declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes()));
|
||||
genS.execute(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ModelCreator(c, library, true, new NetList(netList, errorVisualElement), subName, depth, errorVisualElement);
|
||||
} catch (IOException | ParserException | HGSEvalException e) {
|
||||
throw new NodeException(Lang.get("err_parsingGenericsCode"), e);
|
||||
}
|
||||
} else
|
||||
return new ModelCreator(circuit, library, true, new NetList(netList, errorVisualElement), subName, depth, errorVisualElement);
|
||||
}
|
||||
|
||||
private Statement getStatement(String code) throws IOException, ParserException {
|
||||
Statement genS = map.get(code);
|
||||
if (genS == null) {
|
||||
genS = new Parser(code).parse(false);
|
||||
map.put(code, genS);
|
||||
}
|
||||
return genS;
|
||||
}
|
||||
|
||||
}
|
@ -151,7 +151,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
|
||||
ModelCreator child = ce.getModelCreator(
|
||||
combineNames(subName, me.getVisualElement().getElementAttributes().getLabel()),
|
||||
depth + 1,
|
||||
containingVisualElement != null ? containingVisualElement : me.getVisualElement());
|
||||
containingVisualElement != null ? containingVisualElement : me.getVisualElement(), me.getVisualElement());
|
||||
modelCreators.add(child);
|
||||
|
||||
HashMap<Net, Net> netMatch = new HashMap<>();
|
||||
|
@ -16,7 +16,7 @@ import de.neemann.digital.core.wiring.Clock;
|
||||
import de.neemann.digital.draw.elements.*;
|
||||
import de.neemann.digital.draw.graphics.*;
|
||||
import de.neemann.digital.draw.graphics.Polygon;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
|
||||
import java.awt.*;
|
||||
@ -52,7 +52,7 @@ public class LayoutShape implements Shape {
|
||||
* @throws NodeException NodeException
|
||||
* @throws PinException PinException
|
||||
*/
|
||||
public LayoutShape(ElementLibrary.ElementTypeDescriptionCustom custom, ElementAttributes elementAttributes) throws NodeException, PinException {
|
||||
public LayoutShape(ElementTypeDescriptionCustom custom, ElementAttributes elementAttributes) throws NodeException, PinException {
|
||||
left = new PinList(false);
|
||||
right = new PinList(false);
|
||||
top = new PinList(true);
|
||||
|
@ -20,6 +20,7 @@ import de.neemann.digital.core.wiring.*;
|
||||
import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.Tunnel;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.draw.library.JarComponentManager;
|
||||
import de.neemann.digital.draw.shapes.custom.CustomShape;
|
||||
import de.neemann.digital.draw.shapes.custom.CustomShapeDescription;
|
||||
@ -191,9 +192,9 @@ public final class ShapeFactory {
|
||||
throw new NodeException(Lang.get("err_noShapeFoundFor_N", elementName));
|
||||
else {
|
||||
ElementTypeDescription pt = library.getElementType(elementName);
|
||||
if (pt instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
if (pt instanceof ElementTypeDescriptionCustom) {
|
||||
// Custom component
|
||||
ElementLibrary.ElementTypeDescriptionCustom customDescr = (ElementLibrary.ElementTypeDescriptionCustom) pt;
|
||||
ElementTypeDescriptionCustom customDescr = (ElementTypeDescriptionCustom) pt;
|
||||
CustomCircuitShapeType shapeType = customDescr.getAttributes().get(Keys.SHAPE_TYPE);
|
||||
final CustomCircuitShapeType localShapeType = elementAttributes.get(Keys.SHAPE_TYPE);
|
||||
if (!localShapeType.equals(CustomCircuitShapeType.DEFAULT))
|
||||
|
@ -10,6 +10,7 @@ import de.neemann.digital.draw.elements.Circuit;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.lang.Lang;
|
||||
import de.neemann.gui.ToolTipAction;
|
||||
|
||||
@ -65,8 +66,8 @@ public class ExportZipAction extends ToolTipAction {
|
||||
if (!elementSet.contains(name)) {
|
||||
elementSet.add(name);
|
||||
ElementTypeDescription desc = lib.getElementType(name);
|
||||
if (desc instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
ElementLibrary.ElementTypeDescriptionCustom custom = (ElementLibrary.ElementTypeDescriptionCustom) desc;
|
||||
if (desc instanceof ElementTypeDescriptionCustom) {
|
||||
ElementTypeDescriptionCustom custom = (ElementTypeDescriptionCustom) desc;
|
||||
addFile(zip, custom.getFile(), custom.getCircuit());
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import de.neemann.digital.draw.gif.GifExporter;
|
||||
import de.neemann.digital.draw.graphics.*;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.draw.model.AsyncSequentialClock;
|
||||
import de.neemann.digital.draw.model.ModelCreator;
|
||||
import de.neemann.digital.draw.model.RealTimeClock;
|
||||
@ -368,7 +369,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
|
||||
if (file == null)
|
||||
file = new File(name);
|
||||
try {
|
||||
ElementLibrary.ElementTypeDescriptionCustom description =
|
||||
ElementTypeDescriptionCustom description =
|
||||
ElementLibrary.createCustomDescription(file, circuit, library);
|
||||
description.setShortName(name);
|
||||
description.setDescription(Lang.evalMultilingualContent(circuit.getAttributes().get(Keys.DESCRIPTION)));
|
||||
|
@ -17,10 +17,7 @@ import de.neemann.digital.core.switching.Switch;
|
||||
import de.neemann.digital.draw.elements.*;
|
||||
import de.neemann.digital.draw.graphics.Vector;
|
||||
import de.neemann.digital.draw.graphics.*;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.LibraryListener;
|
||||
import de.neemann.digital.draw.library.LibraryNode;
|
||||
import de.neemann.digital.draw.library.*;
|
||||
import de.neemann.digital.draw.shapes.Drawable;
|
||||
import de.neemann.digital.draw.shapes.InputShape;
|
||||
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||
@ -1030,14 +1027,14 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
||||
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 ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
if (elementType instanceof ElementTypeDescriptionCustom) {
|
||||
attributeDialog.addButton(Lang.get("attr_openCircuitLabel"), new ToolTipAction(Lang.get("attr_openCircuit")) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
attributeDialog.dispose();
|
||||
new Main.MainBuilder()
|
||||
.setParent(parent)
|
||||
.setFileToOpen(((ElementLibrary.ElementTypeDescriptionCustom) elementType).getFile())
|
||||
.setFileToOpen(((ElementTypeDescriptionCustom) elementType).getFile())
|
||||
.setLibrary(library)
|
||||
.denyMostFileActions()
|
||||
.keepPrefMainFile()
|
||||
@ -1225,7 +1222,7 @@ public class CircuitComponent extends JComponent implements ChangedListener, Lib
|
||||
|
||||
private ArrayList<Key> getAttributeList(VisualElement ve) throws ElementNotFoundException {
|
||||
ArrayList<Key> list = library.getElementType(ve.getElementName()).getAttributeList();
|
||||
if (getCircuit().getAttributes().get(Keys.IS_GENERIC)) {
|
||||
if (getCircuit().getAttributes().get(Keys.IS_GENERIC) && !list.contains(Keys.GENERIC)) {
|
||||
list = new ArrayList<>(list);
|
||||
list.add(Keys.GENERIC);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import de.neemann.digital.draw.elements.PinException;
|
||||
import de.neemann.digital.draw.elements.VisualElement;
|
||||
import de.neemann.digital.draw.library.ElementLibrary;
|
||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
||||
import de.neemann.digital.hdl.model2.expression.*;
|
||||
|
||||
@ -59,8 +60,8 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
||||
public HDLNode createNode(VisualElement v, HDLCircuit parent) throws HDLException {
|
||||
try {
|
||||
ElementTypeDescription td = elementLibrary.getElementType(v.getElementName());
|
||||
if (td instanceof ElementLibrary.ElementTypeDescriptionCustom) {
|
||||
ElementLibrary.ElementTypeDescriptionCustom tdc = (ElementLibrary.ElementTypeDescriptionCustom) td;
|
||||
if (td instanceof ElementTypeDescriptionCustom) {
|
||||
ElementTypeDescriptionCustom tdc = (ElementTypeDescriptionCustom) td;
|
||||
|
||||
HDLCircuit c = circuitMap.get(tdc.getCircuit());
|
||||
if (c == null) {
|
||||
|
@ -43,8 +43,8 @@ public class TestExamples extends TestCase {
|
||||
*/
|
||||
public void testTestExamples() throws Exception {
|
||||
File examples = new File(Resources.getRoot(), "/dig/test");
|
||||
assertEquals(162, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(160, testCasesInFiles);
|
||||
assertEquals(164, new FileScanner(this::check).scan(examples));
|
||||
assertEquals(161, testCasesInFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
|
214
src/test/resources/dig/test/generics/mainNest.dig
Normal file
214
src/test/resources/dig/test/generics/mainNest.dig
Normal file
@ -0,0 +1,214 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<attributes/>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>Clock</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>runRealTime</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>C</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Frequency</string>
|
||||
<int>5</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="320" y="280"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>VDD</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="360" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Splitter</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Input Splitting</string>
|
||||
<string>2,3,4</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Output Splitting</string>
|
||||
<string>9</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="520" y="240"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>O</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Bits</string>
|
||||
<int>9</int>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>intFormat</string>
|
||||
<intFormat>hex</intFormat>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="580" y="240"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Testcase</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Testdata</string>
|
||||
<testData>
|
||||
<dataString>C O
|
||||
loop(n,512)
|
||||
C (n+1)
|
||||
end loop</dataString>
|
||||
</testData>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="520" y="320"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>nestError.dig</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>generic</string>
|
||||
<string>bits:=2;</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="380" y="160"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>nestError.dig</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>generic</string>
|
||||
<string>bits:=3;</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="380" y="260"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>nestError.dig</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>generic</string>
|
||||
<string>bits:=4;</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="380" y="360"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="480" y="240"/>
|
||||
<p2 x="520" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="540" y="240"/>
|
||||
<p2 x="580" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="320"/>
|
||||
<p2 x="460" y="320"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="160"/>
|
||||
<p2 x="480" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="160"/>
|
||||
<p2 x="380" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="260"/>
|
||||
<p2 x="520" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="260"/>
|
||||
<p2 x="380" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="180"/>
|
||||
<p2 x="380" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="180"/>
|
||||
<p2 x="460" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="360"/>
|
||||
<p2 x="380" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="360"/>
|
||||
<p2 x="480" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="320" y="280"/>
|
||||
<p2 x="340" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="280"/>
|
||||
<p2 x="460" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="280"/>
|
||||
<p2 x="520" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="280"/>
|
||||
<p2 x="380" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="220"/>
|
||||
<p2 x="460" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="380"/>
|
||||
<p2 x="380" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="280"/>
|
||||
<p2 x="480" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="480" y="160"/>
|
||||
<p2 x="480" y="240"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="180"/>
|
||||
<p2 x="340" y="280"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="280"/>
|
||||
<p2 x="340" y="380"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="140"/>
|
||||
<p2 x="360" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="220"/>
|
||||
<p2 x="360" y="260"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="320"/>
|
||||
<p2 x="360" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="180"/>
|
||||
<p2 x="460" y="220"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="280"/>
|
||||
<p2 x="460" y="320"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<measurementOrdering/>
|
||||
</circuit>
|
105
src/test/resources/dig/test/generics/nestError.dig
Normal file
105
src/test/resources/dig/test/generics/nestError.dig
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<circuit>
|
||||
<version>1</version>
|
||||
<attributes>
|
||||
<entry>
|
||||
<string>isGeneric</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
</attributes>
|
||||
<visualElements>
|
||||
<visualElement>
|
||||
<elementName>In</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>en</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="340" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>count.dig</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>generic</string>
|
||||
<string>bits:=args.bits;</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="380" y="160"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Clock</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>runRealTime</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>C</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>Frequency</string>
|
||||
<int>5</int>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="340" y="180"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>d</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="480" y="140"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Out</elementName>
|
||||
<elementAttributes>
|
||||
<entry>
|
||||
<string>Label</string>
|
||||
<string>ov</string>
|
||||
</entry>
|
||||
</elementAttributes>
|
||||
<pos x="480" y="180"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
<p1 x="440" y="160"/>
|
||||
<p2 x="460" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="160"/>
|
||||
<p2 x="380" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="180"/>
|
||||
<p2 x="380" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="440" y="180"/>
|
||||
<p2 x="480" y="180"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="340" y="140"/>
|
||||
<p2 x="360" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="140"/>
|
||||
<p2 x="480" y="140"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="360" y="140"/>
|
||||
<p2 x="360" y="160"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="460" y="140"/>
|
||||
<p2 x="460" y="160"/>
|
||||
</wire>
|
||||
</wires>
|
||||
<measurementOrdering/>
|
||||
</circuit>
|
Loading…
x
Reference in New Issue
Block a user