improved error messages

This commit is contained in:
hneemann 2017-07-22 11:51:52 +02:00
parent 1e64844442
commit 98a7459d39
20 changed files with 646 additions and 50 deletions

View File

@ -6,10 +6,6 @@
<string>Description</string>
<string>Three digit BCD counter with seven seg displays.</string>
</entry>
<entry>
<string>lockedMode</string>
<boolean>true</boolean>
</entry>
</attributes>
<visualElements>
<visualElement>

View File

@ -1,5 +1,7 @@
package de.neemann.digital.core;
import de.neemann.digital.draw.elements.VisualElement;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
@ -10,6 +12,7 @@ import java.util.Set;
*/
public class ExceptionWithOrigin extends Exception {
private File origin;
private VisualElement visualElement;
/**
* Returns the file or the files that caused the given exception.
@ -99,4 +102,21 @@ public class ExceptionWithOrigin extends Exception {
}
}
/**
* Sets the visual element which caused this error
*
* @param visualElement the visual element
* @return this for chained calls
*/
public ExceptionWithOrigin setVisualElement(VisualElement visualElement) {
this.visualElement = visualElement;
return this;
}
/**
* @return the visual element which caused this error
*/
public VisualElement getVisualElement() {
return visualElement;
}
}

View File

@ -9,18 +9,17 @@ import de.neemann.digital.draw.model.Net;
* @author hneemann
*/
public class PinException extends ExceptionWithOrigin {
private VisualElement element;
private Net net;
/**
* Creates a new instance
*
* @param message the message
* @param element the visual element affected
* @param message the message
* @param visualElement the visual element affected
*/
public PinException(String message, VisualElement element) {
public PinException(String message, VisualElement visualElement) {
super(message);
this.element = element;
setVisualElement(visualElement);
}
/**
@ -33,6 +32,7 @@ public class PinException extends ExceptionWithOrigin {
super(message);
this.net = net;
setOrigin(net.getOrigin());
setVisualElement(net.getVisualElement());
}
/**
@ -44,13 +44,6 @@ public class PinException extends ExceptionWithOrigin {
super(message);
}
/**
* @return the effected element
*/
public VisualElement getVisualElement() {
return element;
}
/**
* @return the effected net
*/

View File

@ -6,6 +6,7 @@ import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.Element;
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.lang.Lang;
@ -39,21 +40,22 @@ public class CustomElement implements Element {
* 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 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
* @return the {@link ModelCreator}
* @throws PinException PinException
* @throws NodeException NodeException
* @throws ElementNotFoundException ElementNotFoundException
*/
public ModelCreator getModelDescription(String subName, int depth) throws PinException, NodeException, ElementNotFoundException {
public ModelCreator getModelCreator(String subName, int depth, VisualElement containingVisualElement) 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()));
return new ModelCreator(circuit, library, true, new NetList(netList), subName, depth);
return new ModelCreator(circuit, library, true, new NetList(netList, containingVisualElement), subName, depth, containingVisualElement);
}
@Override

View File

@ -59,23 +59,24 @@ public class ModelCreator implements Iterable<ModelEntry> {
* @throws ElementNotFoundException ElementNotFoundException
*/
public ModelCreator(Circuit circuit, ElementLibrary library, boolean readAsCustom) throws PinException, NodeException, ElementNotFoundException {
this(circuit, library, readAsCustom, new NetList(circuit), "", 0);
this(circuit, library, readAsCustom, new NetList(circuit), "", 0, null);
}
/**
* Creates a new instance
*
* @param circuit the circuit to use
* @param library the library to use
* @param isNestedCircuit if true the model is created for use as nested element
* @param netList the NetList of the model. If known it is not necessary to create it.
* @param subName name of the circuit, used to name unique elements
* @param depth recursion depth, used to detect a circuit which contains itself
* @param circuit the circuit to use
* @param library the library to use
* @param isNestedCircuit if true the model is created for use as nested element
* @param netList the NetList of the model. If known it is not necessary to create it.
* @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 th topmost containig visual element
* @throws PinException PinException
* @throws NodeException NodeException
* @throws ElementNotFoundException ElementNotFoundException
*/
public ModelCreator(Circuit circuit, ElementLibrary library, boolean isNestedCircuit, NetList netList, String subName, int depth) throws PinException, NodeException, ElementNotFoundException {
public ModelCreator(Circuit circuit, ElementLibrary library, boolean isNestedCircuit, NetList netList, String subName, int depth, VisualElement containingVisualElement) throws PinException, NodeException, ElementNotFoundException {
this.circuit = circuit;
this.netList = netList;
entries = new ArrayList<>();
@ -86,6 +87,10 @@ public class ModelCreator implements Iterable<ModelEntry> {
try {
for (VisualElement ve : circuit.getElements()) {
VisualElement cve = ve;
if (containingVisualElement != null)
cve = containingVisualElement;
Pins pins = ve.getPins();
ElementTypeDescription elementType = library.getElementType(ve.getElementName());
ElementAttributes attr = ve.getElementAttributes();
@ -108,11 +113,11 @@ public class ModelCreator implements Iterable<ModelEntry> {
if (elementType == In.DESCRIPTION || elementType == Out.DESCRIPTION || elementType == Clock.DESCRIPTION) {
String label = ve.getElementAttributes().getLabel();
if (label == null || label.length() == 0)
throw new PinException(Lang.get("err_pinWithoutName", circuit.getOrigin()));
throw new PinException(Lang.get("err_pinWithoutName", circuit.getOrigin()), cve);
if (pins.size() != 1)
throw new PinException(Lang.get("err_N_isNotInputOrOutput", label, circuit.getOrigin()));
throw new PinException(Lang.get("err_N_isNotInputOrOutput", label, circuit.getOrigin()), cve);
if (ioMap.containsKey(label))
throw new PinException(Lang.get("err_duplicatePinLabel", label, circuit.getOrigin()));
throw new PinException(Lang.get("err_duplicatePinLabel", label, circuit.getOrigin()), cve);
ioMap.put(label, pins.get(0));
isNotAIO = false;
@ -120,7 +125,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
}
if (isNotAIO)
entries.add(new ModelEntry(element, pins, ve, elementType.getInputDescription(ve.getElementAttributes()), isNestedCircuit, circuit.getOrigin()));
entries.add(new ModelEntry(element, pins, ve, elementType.getInputDescription(ve.getElementAttributes()), isNestedCircuit, circuit.getOrigin(), cve));
for (Pin p : pins)
netList.add(p);
@ -133,7 +138,10 @@ public class ModelCreator implements Iterable<ModelEntry> {
ModelEntry me = it.next();
if (me.getElement() instanceof CustomElement) { // at first look for custom elements
CustomElement ce = (CustomElement) me.getElement();
ModelCreator child = ce.getModelDescription(combineNames(subName, me.getVisualElement().getElementAttributes().getCleanLabel()), depth + 1);
ModelCreator child = ce.getModelCreator(
combineNames(subName, me.getVisualElement().getElementAttributes().getCleanLabel()),
depth + 1,
containingVisualElement != null ? containingVisualElement : me.getVisualElement());
modelCreators.add(child);
HashMap<Net, Net> netMatch = new HashMap<>();
@ -189,6 +197,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
}
} catch (PinException | NodeException e) {
e.setOrigin(circuit.getOrigin());
e.setVisualElement(containingVisualElement);
throw e;
}
}
@ -281,7 +290,7 @@ public class ModelCreator implements Iterable<ModelEntry> {
for (ModelEntry me : entries) {
Element element = me.getElement();
if (element instanceof Node && nodeSet.contains(element))
highLighted.add(me.getVisualElement());
highLighted.add(me.getContainingVisualElement());
}
}

View File

@ -27,27 +27,30 @@ public class ModelEntry {
private final Pins pins;
private final PinDescriptions inputNames;
private final boolean isNestedElement;
private final File origin; // Only used to create better error messages
private final File origin; // Only used to create better error messages
private final VisualElement containingVisualElement; // Only used to create better error messages
private final VisualElement visualElement;
private IOState ioState;
/**
* Creates a new instance
*
* @param element the element which is created
* @param pins the pins transformed in the circuits coordinate system
* @param visualElement the visual element which has created the element
* @param inputNames the pin descriptions of the inputs.
* @param isNestedElement true if this visual element is a nested included element
* @param origin Used to create better error messages
* @param element the element which is created
* @param pins the pins transformed in the circuits coordinate system
* @param visualElement the visual element which has created the element
* @param inputNames the pin descriptions of the inputs.
* @param isNestedElement true if this visual element is a nested included element
* @param origin Used to create better error messages
* @param containingVisualElement only used to create better error messages
*/
public ModelEntry(Element element, Pins pins, VisualElement visualElement, PinDescriptions inputNames, boolean isNestedElement, File origin) {
public ModelEntry(Element element, Pins pins, VisualElement visualElement, PinDescriptions inputNames, boolean isNestedElement, File origin, VisualElement containingVisualElement) {
this.element = element;
this.pins = pins;
this.visualElement = visualElement;
this.inputNames = inputNames;
this.isNestedElement = isNestedElement;
this.origin = origin;
this.containingVisualElement = containingVisualElement;
}
/**
@ -67,11 +70,11 @@ public class ModelEntry {
for (PinDescription inputName : inputNames) {
Pin pin = ins.get(inputName.getName());
if (pin == null)
throw new PinException(Lang.get("err_pin_N0_atElement_N1_notFound", inputName, visualElement), visualElement);
throw new PinException(Lang.get("err_pin_N0_atElement_N1_notFound", inputName, visualElement), containingVisualElement);
ObservableValue value = pin.getValue();
if (value == null)
throw new PinException(Lang.get("err_noValueSetFor_N0_atElement_N1", inputName, visualElement), visualElement);
throw new PinException(Lang.get("err_noValueSetFor_N0_atElement_N1", inputName, visualElement), containingVisualElement);
inputs.add(ic.invert(inputName.getName(), value));
}
@ -83,7 +86,7 @@ public class ModelEntry {
bidirect = new ArrayList<>();
final ObservableValue readerValue = p.getReaderValue();
if (readerValue == null)
throw new PinException(Lang.get("err_noValueSetFor_N0_atElement_N1", p.getName(), visualElement), visualElement);
throw new PinException(Lang.get("err_noValueSetFor_N0_atElement_N1", p.getName(), visualElement), containingVisualElement);
bidirect.add(readerValue);
}
}
@ -141,4 +144,11 @@ public class ModelEntry {
public IOState getIoState() {
return ioState;
}
/**
* @return the containing visual element
*/
public VisualElement getContainingVisualElement() {
return containingVisualElement;
}
}

View File

@ -6,6 +6,7 @@ import de.neemann.digital.core.element.PinDescription;
import de.neemann.digital.core.wiring.bus.DataBus;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.elements.Wire;
import de.neemann.digital.draw.graphics.Vector;
import de.neemann.digital.lang.Lang;
@ -29,14 +30,17 @@ public class Net {
private final ArrayList<Wire> wires;
private final HashSet<String> labelSet;
private File origin;
private VisualElement visualElement; // only used to create better error messages
/**
* Creates a copy of the given net
*
* @param toCopy the net to copy
* @param toCopy the net to copy
* @param visualElement the containing visual element, only used to create better error messages
*/
public Net(Net toCopy) {
public Net(Net toCopy, VisualElement visualElement) {
points = toCopy.points; // no deep copy of points necessary
this.visualElement = visualElement;
wires = null; // wires not needed
pins = new ArrayList<>(toCopy.pins); // Pins are changed so create a deep copy
labelSet = new HashSet<>(toCopy.labelSet); //ToDo copy necessary?
@ -255,4 +259,11 @@ public class Net {
public File getOrigin() {
return origin;
}
/**
* @return the containing visual element
*/
public VisualElement getVisualElement() {
return visualElement;
}
}

View File

@ -65,12 +65,13 @@ public class NetList implements Iterable<Net> {
/**
* Creates a copy of the given net list
*
* @param toCopy the net list to copy
* @param toCopy the net list to copy
* @param visualElement the containing visual element, only used to create better error messages
*/
public NetList(NetList toCopy) {
public NetList(NetList toCopy, VisualElement visualElement) {
netList = new ArrayList<>();
for (Net net : toCopy)
netList.add(new Net(net));
netList.add(new Net(net, visualElement));
}
/**

View File

@ -1081,6 +1081,7 @@ public final class Main extends JFrame implements ClosingWindowListener.ConfirmS
if (cause instanceof NodeException) {
NodeException e = (NodeException) cause;
circuitComponent.addHighLightedWires(e.getValues());
circuitComponent.addHighLighted(e.getVisualElement());
if (modelCreator != null)
modelCreator.addNodeElementsTo(e.getNodes(), circuitComponent.getHighLighted());
} else if (cause instanceof PinException) {

View File

@ -0,0 +1,63 @@
package de.neemann.digital.integration;
import de.neemann.digital.core.ExceptionWithOrigin;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.library.ElementNotFoundException;
import junit.framework.TestCase;
import java.io.IOException;
public class TestErrorOrigin extends TestCase {
public void testErrorMessage() throws PinException, NodeException, ElementNotFoundException, IOException {
try {
new ToBreakRunner("/dig/errorOrigin/main.dig");
fail();
} catch (PinException e) {
assertNotNull(e.getVisualElement());
assertEquals("mid.dig", e.getVisualElement().getElementName());
checkOrigin(e, "src/test/resources/dig/errorOrigin/inner.dig");
}
}
private void checkOrigin(ExceptionWithOrigin e, String origin) {
assertEquals(1, e.getOrigin().size());
String file = e.getOrigin().iterator().next().getPath().replace('\\', '/');
assertTrue(file, file.endsWith(origin));
}
public void testErrorMessage2() throws PinException, NodeException, ElementNotFoundException, IOException {
try {
new ToBreakRunner("/dig/errorOrigin/main2.dig");
fail();
} catch (PinException e) {
assertNotNull(e.getVisualElement());
assertEquals("mid2.dig", e.getVisualElement().getElementName());
checkOrigin(e, "src/test/resources/dig/errorOrigin/mid2.dig");
}
}
public void testErrorMessage3() throws PinException, NodeException, ElementNotFoundException, IOException {
try {
new ToBreakRunner("/dig/errorOrigin/main3.dig");
fail();
} catch (PinException e) {
assertNotNull(e.getVisualElement());
assertEquals("midOk.dig", e.getVisualElement().getElementName());
checkOrigin(e, "src/test/resources/dig/errorOrigin/midOk.dig");
}
}
public void testErrorMessage4() throws PinException, NodeException, ElementNotFoundException, IOException {
try {
new ToBreakRunner("/dig/errorOrigin/main4.dig");
fail();
} catch (PinException e) {
assertNotNull(e.getVisualElement());
assertEquals("And", e.getVisualElement().getElementName());
checkOrigin(e, "src/test/resources/dig/errorOrigin/main4.dig");
}
}
}

View File

@ -1,6 +1,7 @@
package de.neemann.digital.integration;
import de.neemann.digital.core.Model;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.draw.model.ModelCreator;
import de.neemann.digital.testing.TestCaseElement;
@ -61,6 +62,10 @@ public class TestExamples extends TestCase {
throw e;
}
boolean isLib = dig.getPath().replace('\\', '/').contains("/lib/");
assertTrue("wrong locked mode", isLib == br.getCircuit().getAttributes().get(Keys.LOCKED_MODE));
try {
for (VisualElement el : br.getCircuit().getElements())
if (el.equalsDescription(TestCaseElement.TESTCASEDESCRIPTION)) {

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="240" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="200" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="200" y="180"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="400" y="160"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="340" y="160"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="380" y="160"/>
<p2 x="400" y="160"/>
</wire>
<wire>
<p1 x="200" y="180"/>
<p2 x="240" y="180"/>
</wire>
<wire>
<p1 x="200" y="140"/>
<p2 x="240" y="140"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="240" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="200" y="140"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="200" y="180"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="340" y="160"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="320" y="160"/>
<p2 x="340" y="160"/>
</wire>
<wire>
<p1 x="200" y="180"/>
<p2 x="240" y="180"/>
</wire>
<wire>
<p1 x="200" y="140"/>
<p2 x="240" y="140"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="280" y="260"/>
</visualElement>
<visualElement>
<elementName>mid.dig</elementName>
<elementAttributes/>
<pos x="180" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="180" y="240"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="280" y="260"/>
</wire>
<wire>
<p1 x="140" y="280"/>
<p2 x="180" y="280"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="280" y="260"/>
</visualElement>
<visualElement>
<elementName>mid2.dig</elementName>
<elementAttributes/>
<pos x="180" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="180" y="240"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="280" y="260"/>
</wire>
<wire>
<p1 x="140" y="280"/>
<p2 x="180" y="280"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="280" y="260"/>
</visualElement>
<visualElement>
<elementName>midOk.dig</elementName>
<elementAttributes/>
<pos x="180" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="180" y="240"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="280" y="260"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="140" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes/>
<pos x="280" y="260"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="180" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="180" y="240"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="280" y="260"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>inner.dig</elementName>
<elementAttributes/>
<pos x="360" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="280" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="280" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="500" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="300" y="240"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="300" y="280"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="440" y="260"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="280" y="240"/>
<p2 x="300" y="240"/>
</wire>
<wire>
<p1 x="340" y="240"/>
<p2 x="360" y="240"/>
</wire>
<wire>
<p1 x="420" y="260"/>
<p2 x="440" y="260"/>
</wire>
<wire>
<p1 x="480" y="260"/>
<p2 x="500" y="260"/>
</wire>
<wire>
<p1 x="280" y="280"/>
<p2 x="300" y="280"/>
</wire>
<wire>
<p1 x="340" y="280"/>
<p2 x="360" y="280"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="280" y="240"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="280" y="280"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="500" y="260"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="300" y="240"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="300" y="280"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="440" y="260"/>
</visualElement>
<visualElement>
<elementName>inner2.dig</elementName>
<elementAttributes/>
<pos x="360" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="280" y="240"/>
<p2 x="300" y="240"/>
</wire>
<wire>
<p1 x="340" y="240"/>
<p2 x="360" y="240"/>
</wire>
<wire>
<p1 x="420" y="260"/>
<p2 x="440" y="260"/>
</wire>
<wire>
<p1 x="480" y="260"/>
<p2 x="500" y="260"/>
</wire>
<wire>
<p1 x="280" y="280"/>
<p2 x="300" y="280"/>
</wire>
<wire>
<p1 x="340" y="280"/>
<p2 x="360" y="280"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>A</string>
</entry>
</elementAttributes>
<pos x="140" y="240"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="280" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>B</string>
</entry>
</elementAttributes>
<pos x="140" y="280"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes/>
<pos x="180" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="180" y="240"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="280" y="260"/>
</wire>
<wire>
<p1 x="140" y="280"/>
<p2 x="180" y="280"/>
</wire>
</wires>
</circuit>