mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 15:26:52 -04:00
simplified the generics resolving code
This commit is contained in:
parent
45a7627dd3
commit
55b1e77db6
@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.draw.library;
|
package de.neemann.digital.draw.library;
|
||||||
|
|
||||||
import de.neemann.digital.analyse.SubstituteLibrary;
|
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
import de.neemann.digital.core.element.ElementAttributes;
|
import de.neemann.digital.core.element.ElementAttributes;
|
||||||
import de.neemann.digital.core.element.ElementFactory;
|
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.elements.VisualElement;
|
||||||
import de.neemann.digital.draw.model.ModelCreator;
|
import de.neemann.digital.draw.model.ModelCreator;
|
||||||
import de.neemann.digital.draw.model.NetList;
|
import de.neemann.digital.draw.model.NetList;
|
||||||
import de.neemann.digital.hdl.hgs.*;
|
import de.neemann.digital.hdl.hgs.Parser;
|
||||||
import de.neemann.digital.hdl.hgs.function.Function;
|
import de.neemann.digital.hdl.hgs.ParserException;
|
||||||
import de.neemann.digital.hdl.hgs.refs.Reference;
|
import de.neemann.digital.hdl.hgs.refs.Reference;
|
||||||
import de.neemann.digital.hdl.hgs.refs.ReferenceToStruct;
|
import de.neemann.digital.hdl.hgs.refs.ReferenceToStruct;
|
||||||
import de.neemann.digital.hdl.hgs.refs.ReferenceToVar;
|
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 static final int MAX_DEPTH = 30;
|
||||||
private final File file;
|
private final File file;
|
||||||
private final Circuit circuit;
|
private final Circuit circuit;
|
||||||
private final StatementCache statementCache;
|
private final ResolveGenerics resolveGenerics;
|
||||||
private String description;
|
private String description;
|
||||||
private NetList netList;
|
private NetList netList;
|
||||||
private boolean isCustom = true;
|
private boolean isCustom = true;
|
||||||
@ -52,7 +51,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
|
|||||||
super(file.getName(), (ElementFactory) null, circuit.getInputNames());
|
super(file.getName(), (ElementFactory) null, circuit.getInputNames());
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.circuit = circuit;
|
this.circuit = circuit;
|
||||||
statementCache=new StatementCache();
|
resolveGenerics = new ResolveGenerics();
|
||||||
setShortName(file.getName());
|
setShortName(file.getName());
|
||||||
addAttribute(Keys.ROTATE);
|
addAttribute(Keys.ROTATE);
|
||||||
addAttribute(Keys.LABEL);
|
addAttribute(Keys.LABEL);
|
||||||
@ -123,56 +122,7 @@ public final class ElementTypeDescriptionCustom extends ElementTypeDescription {
|
|||||||
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
|
throw new NodeException(Lang.get("err_recursiveNestingAt_N0", circuit.getOrigin()));
|
||||||
|
|
||||||
if (isGeneric()) {
|
if (isGeneric()) {
|
||||||
Context args;
|
Circuit c = resolveGenerics.resolveCircuit(containingVisualElement, circuit, library);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ModelCreator(c, library, true, new NetList(netList, errorVisualElement), subName, depth, errorVisualElement);
|
return new ModelCreator(c, library, true, new NetList(netList, errorVisualElement), subName, depth, errorVisualElement);
|
||||||
} else
|
} else
|
||||||
|
@ -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<String, Statement> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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<String, Statement> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -5,7 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package de.neemann.digital.hdl.model2;
|
package de.neemann.digital.hdl.model2;
|
||||||
|
|
||||||
import de.neemann.digital.analyse.SubstituteLibrary;
|
|
||||||
import de.neemann.digital.core.NodeException;
|
import de.neemann.digital.core.NodeException;
|
||||||
import de.neemann.digital.core.ObservableValues;
|
import de.neemann.digital.core.ObservableValues;
|
||||||
import de.neemann.digital.core.basic.*;
|
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.ElementLibrary;
|
||||||
import de.neemann.digital.draw.library.ElementNotFoundException;
|
import de.neemann.digital.draw.library.ElementNotFoundException;
|
||||||
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
import de.neemann.digital.draw.library.ElementTypeDescriptionCustom;
|
||||||
import de.neemann.digital.draw.library.StatementCache;
|
import de.neemann.digital.draw.library.ResolveGenerics;
|
||||||
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.hdl.model2.clock.HDLClockIntegrator;
|
import de.neemann.digital.hdl.model2.clock.HDLClockIntegrator;
|
||||||
import de.neemann.digital.hdl.model2.expression.*;
|
import de.neemann.digital.hdl.model2.expression.*;
|
||||||
import de.neemann.digital.lang.Lang;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -47,7 +39,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
private HashMap<Circuit, HDLCircuit> circuitMap;
|
private HashMap<Circuit, HDLCircuit> circuitMap;
|
||||||
private HDLCircuit main;
|
private HDLCircuit main;
|
||||||
private Renaming renaming;
|
private Renaming renaming;
|
||||||
private StatementCache statementCache = new StatementCache();
|
private ResolveGenerics resolveGenerics = new ResolveGenerics();
|
||||||
private HashMap<String, GenNum> genericInstanceNumbers;
|
private HashMap<String, GenNum> genericInstanceNumbers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +70,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
final Circuit circuit = tdc.getCircuit();
|
final Circuit circuit = tdc.getCircuit();
|
||||||
if (circuit.getAttributes().get(Keys.IS_GENERIC)) {
|
if (circuit.getAttributes().get(Keys.IS_GENERIC)) {
|
||||||
|
|
||||||
Circuit circuitCopy = degenerifyCircuit(v, circuit);
|
Circuit circuitCopy = resolveGenerics.resolveCircuit(v, circuit, elementLibrary);
|
||||||
|
|
||||||
String elementName = v.getElementName();
|
String elementName = v.getElementName();
|
||||||
GenNum num = genericInstanceNumbers.computeIfAbsent(elementName, t -> new GenNum());
|
GenNum num = genericInstanceNumbers.computeIfAbsent(elementName, t -> new GenNum());
|
||||||
@ -161,57 +153,6 @@ public class HDLModel implements Iterable<HDLCircuit> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
private String cleanName(String s) {
|
||||||
return s.replace("-", "_");
|
return s.replace("-", "_");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user