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 4d7199698..4fa5211cf 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementTypeDescriptionCustom.java @@ -5,7 +5,6 @@ */ 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; @@ -16,8 +15,8 @@ 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.hdl.hgs.function.Function; +import de.neemann.digital.hdl.hgs.Parser; +import de.neemann.digital.hdl.hgs.ParserException; import de.neemann.digital.hdl.hgs.refs.Reference; import de.neemann.digital.hdl.hgs.refs.ReferenceToStruct; import de.neemann.digital.hdl.hgs.refs.ReferenceToVar; @@ -35,7 +34,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription { private static final int MAX_DEPTH = 30; private final File file; private final Circuit circuit; - private final StatementCache statementCache; + private final ResolveGenerics resolveGenerics; private String description; private NetList netList; private boolean isCustom = true; @@ -52,7 +51,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription { super(file.getName(), (ElementFactory) null, circuit.getInputNames()); this.file = file; this.circuit = circuit; - statementCache=new StatementCache(); + resolveGenerics = new ResolveGenerics(); setShortName(file.getName()); addAttribute(Keys.ROTATE); addAttribute(Keys.LABEL); @@ -123,56 +122,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription { throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin())); if (isGeneric()) { - Context args; - if (containingVisualElement != null) { - args = containingVisualElement.getGenericArgs(); - if (args == null) { - String argsCode = containingVisualElement.getElementAttributes().get(Keys.GENERIC); - try { - Statement s = statementCache.getStatement(argsCode); - args = new Context(); - s.execute(args); - } catch (HGSEvalException | ParserException | IOException e) { - final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", containingVisualElement, argsCode), e); - ex.setOrigin(circuit.getOrigin()); - throw ex; - } - } - } else - args = new Context(); - - Circuit c = circuit.createDeepCopy(); - for (VisualElement ve : c.getElements()) { - String gen = ve.getElementAttributes().get(Keys.GENERIC).trim(); - try { - if (!gen.isEmpty()) { - boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom(); - Statement genS = statementCache.getStatement(gen); - if (isCustom) { - Context mod = new Context() - .declareVar("args", args) - .declareFunc("setCircuit", new Function(1) { - @Override - protected Object f(Object... args) { - ve.setElementName(args[0].toString()); - return null; - } - }); - genS.execute(mod); - ve.setGenericArgs(mod); - } else { - Context mod = new Context() - .declareVar("args", args) - .declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes())); - genS.execute(mod); - } - } - } catch (HGSEvalException | ParserException | IOException e) { - final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), e); - ex.setOrigin(circuit.getOrigin()); - throw ex; - } - } + Circuit c = resolveGenerics.resolveCircuit(containingVisualElement, circuit, library); return new ModelCreator(c, library, true, new NetList(netList, errorVisualElement), subName, depth, errorVisualElement); } else diff --git a/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java new file mode 100644 index 000000000..8154f4361 --- /dev/null +++ b/src/main/java/de/neemann/digital/draw/library/ResolveGenerics.java @@ -0,0 +1,107 @@ +/* + * 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.Keys; +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.lang.Lang; + +import java.io.IOException; +import java.util.HashMap; + +/** + * Resolves a generic circuit and makes it non generic + */ +public class ResolveGenerics { + + private final HashMap map; + + /** + * Creates a new instance + */ + public ResolveGenerics() { + map = new HashMap<>(); + } + + /** + * Resolves the generics + * + * @param visualElement the visual element + * @param circuit the circuit to resolve + * @param library the library to ude + * @return the resolved circuit + * @throws NodeException NodeException + * @throws ElementNotFoundException ElementNotFoundException + */ + public Circuit resolveCircuit(VisualElement visualElement, Circuit circuit, LibraryInterface library) throws NodeException, ElementNotFoundException { + Context args; + if (visualElement != null) { + args = visualElement.getGenericArgs(); + if (args == null) { + String argsCode = visualElement.getElementAttributes().get(Keys.GENERIC); + try { + Statement s = getStatement(argsCode); + args = new Context(); + s.execute(args); + } catch (HGSEvalException | ParserException | IOException e) { + final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", visualElement, argsCode), e); + ex.setOrigin(circuit.getOrigin()); + throw ex; + } + } + } else + args = new Context(); + + Circuit c = circuit.createDeepCopy(); + for (VisualElement ve : c.getElements()) { + String gen = ve.getElementAttributes().get(Keys.GENERIC).trim(); + try { + if (!gen.isEmpty()) { + boolean isCustom = library.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom(); + Statement genS = getStatement(gen); + if (isCustom) { + Context mod = new Context() + .declareVar("args", args) + .declareFunc("setCircuit", new Function(1) { + @Override + protected Object f(Object... args) { + ve.setElementName(args[0].toString()); + return null; + } + }); + genS.execute(mod); + ve.setGenericArgs(mod); + } else { + Context mod = new Context() + .declareVar("args", args) + .declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes())); + genS.execute(mod); + } + } + } catch (HGSEvalException | ParserException | IOException e) { + final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), e); + ex.setOrigin(circuit.getOrigin()); + throw ex; + } + } + return c; + } + + 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; + } + +} diff --git a/src/main/java/de/neemann/digital/draw/library/StatementCache.java b/src/main/java/de/neemann/digital/draw/library/StatementCache.java deleted file mode 100644 index 6a705729e..000000000 --- a/src/main/java/de/neemann/digital/draw/library/StatementCache.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.hdl.hgs.Parser; -import de.neemann.digital.hdl.hgs.ParserException; -import de.neemann.digital.hdl.hgs.Statement; - -import java.io.IOException; -import java.util.HashMap; - -/** - * Implements a cache for statements - */ -public class StatementCache { - private final HashMap map; - - /** - * Creates a new instance - */ - public StatementCache() { - map = new HashMap<>(); - } - - /** - * Gets the analysed statements. - * If the statements are not present in the cache, they are generated. - * - * @param code the code - * @return the statements - * @throws IOException IOException - * @throws ParserException ParserException - */ - public 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; - } - -} diff --git a/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java b/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java index a0b0d306d..416fc2629 100644 --- a/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java +++ b/src/main/java/de/neemann/digital/hdl/model2/HDLModel.java @@ -5,7 +5,6 @@ */ package de.neemann.digital.hdl.model2; -import de.neemann.digital.analyse.SubstituteLibrary; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.ObservableValues; import de.neemann.digital.core.basic.*; @@ -23,17 +22,10 @@ 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.StatementCache; -import de.neemann.digital.hdl.hgs.Context; -import de.neemann.digital.hdl.hgs.HGSEvalException; -import de.neemann.digital.hdl.hgs.ParserException; -import de.neemann.digital.hdl.hgs.Statement; -import de.neemann.digital.hdl.hgs.function.Function; +import de.neemann.digital.draw.library.ResolveGenerics; import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator; import de.neemann.digital.hdl.model2.expression.*; -import de.neemann.digital.lang.Lang; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -47,7 +39,7 @@ public class HDLModel implements Iterable { private HashMap circuitMap; private HDLCircuit main; private Renaming renaming; - private StatementCache statementCache = new StatementCache(); + private ResolveGenerics resolveGenerics = new ResolveGenerics(); private HashMap genericInstanceNumbers; /** @@ -78,7 +70,7 @@ public class HDLModel implements Iterable { final Circuit circuit = tdc.getCircuit(); if (circuit.getAttributes().get(Keys.IS_GENERIC)) { - Circuit circuitCopy = degenerifyCircuit(v, circuit); + Circuit circuitCopy = resolveGenerics.resolveCircuit(v, circuit, elementLibrary); String elementName = v.getElementName(); GenNum num = genericInstanceNumbers.computeIfAbsent(elementName, t -> new GenNum()); @@ -161,57 +153,6 @@ public class HDLModel implements Iterable { } } - private Circuit degenerifyCircuit(VisualElement v, Circuit circuit) throws NodeException, ElementNotFoundException { - Context args = v.getGenericArgs(); - if (args == null) { - String argsCode = v.getElementAttributes().get(Keys.GENERIC); - try { - Statement s = statementCache.getStatement(argsCode); - args = new Context(); - s.execute(args); - } catch (HGSEvalException | ParserException | IOException e) { - final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", v, argsCode), e); - ex.setOrigin(circuit.getOrigin()); - throw ex; - } - } - - Circuit circuitCopy = circuit.createDeepCopy(); - for (VisualElement ve : circuitCopy.getElements()) { - String gen = ve.getElementAttributes().get(Keys.GENERIC).trim(); - try { - if (!gen.isEmpty()) { - boolean isCustom = elementLibrary.getElementType(ve.getElementName(), ve.getElementAttributes()).isCustom(); - Statement genS = statementCache.getStatement(gen); - if (isCustom) { - Context mod = new Context() - .declareVar("args", args) - .declareFunc("setCircuit", new Function(1) { - @Override - protected Object f(Object... args) { - ve.setElementName(args[0].toString()); - return null; - } - }); - genS.execute(mod); - ve.setGenericArgs(mod); - } else { - Context mod = new Context() - .declareVar("args", args) - .declareVar("this", new SubstituteLibrary.AllowSetAttributes(ve.getElementAttributes())); - genS.execute(mod); - } - } - } catch (HGSEvalException | ParserException | IOException e) { - final NodeException ex = new NodeException(Lang.get("err_evaluatingGenericsCode_N_N", ve, gen), e); - ex.setOrigin(circuit.getOrigin()); - throw ex; - } - } - circuitCopy.getAttributes().set(Keys.IS_GENERIC, false); - return circuitCopy; - } - private String cleanName(String s) { return s.replace("-", "_"); }