simplified the generics resolving code

This commit is contained in:
hneemann 2019-07-11 12:53:05 +02:00
parent 45a7627dd3
commit 55b1e77db6
4 changed files with 115 additions and 163 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<HDLCircuit> {
private HashMap<Circuit, HDLCircuit> circuitMap;
private HDLCircuit main;
private Renaming renaming;
private StatementCache statementCache = new StatementCache();
private ResolveGenerics resolveGenerics = new ResolveGenerics();
private HashMap<String, GenNum> genericInstanceNumbers;
/**
@ -78,7 +70,7 @@ public class HDLModel implements Iterable<HDLCircuit> {
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<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) {
return s.replace("-", "_");
}