added first VHDLTemplate, not working yet

This commit is contained in:
hneemann 2018-03-12 21:21:36 +01:00
parent 4d15ea268a
commit 409bb3cac9
4 changed files with 150 additions and 2 deletions

View File

@ -14,6 +14,7 @@ public class Context {
private final Context parent;
private final StringBuilder code;
private HashMap<String, Object> map;
private int recordStart = 0;
/**
* Creates a new context
@ -37,6 +38,23 @@ public class Context {
map = new HashMap<>();
}
/**
* Returns true if this context contains a mapping for the specified key.
*
* @param name the key
* @return true if value is present
*/
public boolean contains(String name) {
if (map.containsKey(name))
return true;
else {
if (parent != null)
return parent.contains(name);
else
return false;
}
}
/**
* Get a variable
*
@ -47,6 +65,13 @@ public class Context {
public Object getVar(String name) throws EvalException {
Object v = map.get(name);
if (v == null) {
if (name.equals("output"))
return code.toString();
if (name.equals("fraction"))
return code.subSequence(recordStart, code.length()).toString();
if (parent == null)
throw new EvalException("variable not found: " + name);
else
@ -76,8 +101,9 @@ public class Context {
public Context print(String str) {
if (parent != null)
parent.print(str);
else
else {
code.append(str);
}
return this;
}
@ -88,4 +114,11 @@ public class Context {
else
return map.toString();
}
/**
* resets the record position
*/
public void resetRecorder() {
recordStart = code.length();
}
}

View File

@ -127,7 +127,7 @@ public class VHDLLibrary {
e.writeHeader(out, node);
if (e instanceof ExternalVHDL)
if (e instanceof ExternalVHDL || e instanceof VHDLTemplate)
return;
out.println();

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2017 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.hdl.vhdl.lib;
import de.neemann.digital.hdl.hgs.*;
import de.neemann.digital.hdl.model.HDLException;
import de.neemann.digital.hdl.model.HDLNode;
import de.neemann.digital.hdl.printer.CodePrinter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.HashSet;
/**
* Reads a file with the vhdl code to create the entity
*/
public class VHDLTemplate implements VHDLEntity {
private final static String ENTITY_PREFIX = "DIG_";
private final Context staticContext;
private final Statement statements;
private HashSet<String> entitiesWritten;
private String entityName;
/**
* Creates a new instance
*
* @param name the name of the entity
* @throws IOException IOException
*/
public VHDLTemplate(String name) throws IOException {
entityName = ENTITY_PREFIX + name;
InputStream inputStream = getClass().getClassLoader().getResourceAsStream(createFileName(entityName));
if (inputStream == null)
throw new IOException("file not present: " + createFileName(entityName));
try (Reader in = new InputStreamReader(inputStream, "utf-8")) {
Parser p = new Parser(in);
statements = p.parse();
staticContext = p.getStaticContext();
} catch (ParserException e) {
throw new IOException("error parsing template", e);
}
entitiesWritten = new HashSet<>();
}
private static String createFileName(String name) {
return "vhdl/" + name + ".tem";
}
@Override
public void writeHeader(CodePrinter out, HDLNode node) throws IOException {
try {
statements.execute(new Context().setVar("elem", node.getAttributes()));
entitiesWritten.add(getEntityName(node));
} catch (EvalException e) {
throw new IOException("error evaluating the template", e);
}
}
private String getEntityName(HDLNode node) throws EvalException {
String name = entityName;
if (staticContext.contains("name")) {
Object funcObj = staticContext.getVar("name");
if (funcObj instanceof FirstClassFunction)
name = ((FirstClassFunction) funcObj).evaluate(node.getAttributes()).toString();
}
return name;
}
@Override
public String getName(HDLNode node) throws HDLException {
try {
return getEntityName(node);
} catch (EvalException e) {
throw new HDLException("error requesting the entities name", e);
}
}
@Override
public boolean needsOutput(HDLNode node) throws HDLException {
try {
return !entitiesWritten.contains(getEntityName(node));
} catch (EvalException e) {
throw new HDLException("error requesting the entities name", e);
}
}
@Override
public void writeDeclaration(CodePrinter out, HDLNode node) throws IOException, HDLException {
}
@Override
public void writeArchitecture(CodePrinter out, HDLNode node) throws IOException, HDLException {
}
@Override
public void writeGenericMap(CodePrinter out, HDLNode node) throws IOException, HDLException {
}
@Override
public String getDescription(HDLNode node) {
return null;
}
}

View File

@ -255,6 +255,11 @@ public class ParserTest extends TestCase {
new Context().setVar("a", 3)).toString());
}
public void testFirstClassFunctionOutput() throws IOException, ParserException, EvalException {
assertEquals("testtext12testtext15",
exec("<? f=func(a){ ?>testtext<? print(a*3); return=output; }; print(f(4),f(5));?>").toString());
}
// public void testCode() throws IOException, ParserException {
// File dir = new File("/home/hneemann/temp/Digital/ideras/Digital/src/main/resources/verilog");