summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2018-05-25 07:40:11 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2018-05-25 07:40:11 +0200
commitf7d1dab52196f0d4fb0932b321645cf91e95877e (patch)
tree8ea0a0b19ac8d1da4011824538d305af28895d7f
downloadghdl2hastabel-f7d1dab52196f0d4fb0932b321645cf91e95877e.zip
ghdl2hastabel-f7d1dab52196f0d4fb0932b321645cf91e95877e.tar.bz2
Isolates Tabellion's "ast-to-instr" module.
-rw-r--r--Makefile70
-rw-r--r--src/ghdl2hastabel/Depths.java77
-rw-r--r--src/ghdl2hastabel/Expressions.java430
-rw-r--r--src/ghdl2hastabel/Functions.java33
-rw-r--r--src/ghdl2hastabel/IDs.java134
-rw-r--r--src/ghdl2hastabel/Main.java184
-rw-r--r--src/ghdl2hastabel/OutputFile.java137
-rw-r--r--src/ghdl2hastabel/Parameters.java59
-rw-r--r--src/ghdl2hastabel/ParsableXML.java32
-rw-r--r--src/ghdl2hastabel/Predicates.java33
-rw-r--r--src/ghdl2hastabel/Strings.java56
-rw-r--r--src/ghdl2hastabel/Waveforms.java32
-rw-r--r--src/ghdl2hastabel/XMLManager.java128
-rw-r--r--src/ghdl2hastabel/vhdl/.Node.java.swpbin0 -> 12288 bytes
-rw-r--r--src/ghdl2hastabel/vhdl/Architecture.java351
-rw-r--r--src/ghdl2hastabel/vhdl/CSNode.java309
-rw-r--r--src/ghdl2hastabel/vhdl/Component.java449
-rw-r--r--src/ghdl2hastabel/vhdl/Entity.java290
-rw-r--r--src/ghdl2hastabel/vhdl/File.java145
-rw-r--r--src/ghdl2hastabel/vhdl/Generic.java257
-rw-r--r--src/ghdl2hastabel/vhdl/ISNode.java273
-rw-r--r--src/ghdl2hastabel/vhdl/Node.java137
-rw-r--r--src/ghdl2hastabel/vhdl/Port.java365
-rw-r--r--src/ghdl2hastabel/vhdl/Process.java451
-rw-r--r--src/ghdl2hastabel/vhdl/SSASNode.java292
-rw-r--r--src/ghdl2hastabel/vhdl/SSCNode.java234
-rw-r--r--src/ghdl2hastabel/vhdl/Signal.java317
-rw-r--r--src/ghdl2hastabel/vhdl/WNode.java211
28 files changed, 5486 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..49f6b10
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,70 @@
+## Parameters ##################################################################
+SRC_DIR ?= ${CURDIR}/src/
+BIN_DIR ?= ${CURDIR}/bin/
+LIB_DIR ?= ${CURDIR}/lib/
+
+TARGET ?= ghdl2hastabel.jar
+INSTALL_DIR ?= $(LIB_DIR)
+
+#### Where to get the missing Jar files.
+JAR_SOURCE ?= "https://noot-noot.org/tabellion/jar/"
+
+#### Binaries
+###### JAR binary
+JAR ?= jar
+
+###### JRE binary
+JAVA ?= java
+
+###### JDK binary
+JAVAC ?= javac
+
+##### Downloader
+DOWNLOADER ?= wget
+
+## Parameters Sanity Check #####################################################
+ifeq ($(strip $(JAVA)),)
+$(error No Java executable defined as parameter.)
+endif
+
+ifeq ($(strip $(JAVAC)),)
+$(error No Java compiler defined as parameter.)
+endif
+
+## Java Config #################################################################
+CLASSPATH = "$(SRC_DIR):$(BIN_DIR)"
+
+## Makefile Magic ##############################################################
+JAVA_SOURCES = \
+ $(wildcard $(SRC_DIR)/ghdl2hastabel/*.java) \
+ $(wildcard $(SRC_DIR)/ghdl2hastabel/*/*.java)
+CLASSES = $(patsubst $(SRC_DIR)/%,$(BIN_DIR)/%, $(JAVA_SOURCES:.java=.class))
+
+## Makefile Rules ##############################################################
+$(TARGET): $(JAVA_SOURCES) $(CLASSES)
+ $(MAKE) $(LIB_DIR)
+ rm -f $(TARGET) $(INSTALL_DIR)/$@
+ $(JAR) cf $@ -C $(BIN_DIR) .
+ cp $@ $(INSTALL_DIR)/$@
+
+clean:
+ rm -rf $(BIN_DIR)/*
+ rm -f $(TARGET)
+
+$(CLASSES): $(BIN_DIR)/%.class: $(SRC_DIR)/%.java $(BIN_DIR)
+ $(JAVAC) -cp $(CLASSPATH) -d $(BIN_DIR) $<
+
+%.jar:
+ $(MAKE) $(LIB_DIR)
+ echo "Attempting to download missing jar '$@'..."
+ cd $(LIB_DIR); $(DOWNLOADER) "$(JAR_SOURCE)/$(notdir $@)"
+
+$(LIB_DIR):
+ mkdir -p $@
+
+$(BIN_DIR):
+ mkdir -p $@
+
+##### For my private use...
+publish: $(TARGET)
+ scp $< dreamhost:~/noot-noot/tabellion/jar/
diff --git a/src/ghdl2hastabel/Depths.java b/src/ghdl2hastabel/Depths.java
new file mode 100644
index 0000000..3e01423
--- /dev/null
+++ b/src/ghdl2hastabel/Depths.java
@@ -0,0 +1,77 @@
+package ghdl2hastabel;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class Depths
+{
+ private static final Map<Integer, IDs> TO_ID;
+ private static final OutputFile DEPTHS_OUTPUT;
+ private static int highest_depth;
+
+ static
+ {
+ highest_depth = -1;
+
+ TO_ID = new HashMap<Integer, IDs>();
+
+ /* TODO: filename as a param? */
+ DEPTHS_OUTPUT = OutputFile.new_output_file("depths.mod");
+ }
+
+ private Depths () {} /* Utility class. */
+
+ public static IDs get_id_from_depth
+ (
+ final String depth
+ )
+ {
+ return get_id_from_depth(Integer.valueOf(depth));
+ }
+
+ public static IDs get_id_from_depth
+ (
+ final Integer depth
+ )
+ {
+ IDs result;
+
+ result = TO_ID.get(depth);
+
+ if (result == null)
+ {
+ result = IDs.generate_new_id(DEPTHS_OUTPUT, "depth");
+
+ TO_ID.put(depth, result);
+ }
+
+ if (depth.intValue() > highest_depth)
+ {
+ highest_depth = depth.intValue();
+ }
+
+ return result;
+ }
+
+ public static void generate_predicates ()
+ {
+ for
+ (
+ int current_depth = highest_depth;
+ current_depth > 0;
+ --current_depth
+ )
+ {
+ for (int i = 0; i < current_depth; ++i)
+ {
+ Predicates.add_entry
+ (
+ DEPTHS_OUTPUT,
+ "is_lower_than",
+ get_id_from_depth(new Integer(i)),
+ get_id_from_depth(new Integer(current_depth))
+ );
+ }
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/Expressions.java b/src/ghdl2hastabel/Expressions.java
new file mode 100644
index 0000000..3c8f547
--- /dev/null
+++ b/src/ghdl2hastabel/Expressions.java
@@ -0,0 +1,430 @@
+package ghdl2hastabel;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+public class Expressions
+{
+ private static final XPathExpression XPE_GET_LEFT_SIDE;
+ private static final XPathExpression XPE_GET_RIGHT_SIDE;
+ private static final XPathExpression XPE_GET_OPERAND;
+ private static final XPathExpression XPE_GET_FUN_PARAMETERS;
+ private static final XPathExpression XPE_GET_INDEX_LIST;
+ private static final XPathExpression XPE_GET_NAMED_ENTITY;
+ private static final XPathExpression XPE_GET_PREFIX_NAMED_ENTITY;
+ private static final XPathExpression XPE_GET_PREFIX;
+
+ static
+ {
+ XPE_GET_LEFT_SIDE = XMLManager.compile_or_die("./left");
+ XPE_GET_RIGHT_SIDE = XMLManager.compile_or_die("./right");
+ XPE_GET_OPERAND = XMLManager.compile_or_die("./operand");
+
+ XPE_GET_FUN_PARAMETERS =
+ XMLManager.compile_or_die
+ (
+ "./parameter_association_chain/el/actual"
+ );
+
+ XPE_GET_INDEX_LIST = XMLManager.compile_or_die("./index_list/el");
+
+ XPE_GET_NAMED_ENTITY = XMLManager.compile_or_die("./named_entity");
+ XPE_GET_PREFIX_NAMED_ENTITY =
+ XMLManager.compile_or_die
+ (
+ "./prefix/named_entity"
+ );
+
+ XPE_GET_PREFIX = XMLManager.compile_or_die("./prefix");
+ }
+
+ private static enum Operator
+ {
+ /* From GHDL's ./src/vhdl/nodes_meta.adb */
+ IDENTITY("identity_operator", "+", false), /* assuming it means "+ number" */
+ NEGATION("negation_operator", "-", false), /* assuming it means "- number" */
+ ABSOLUTE("absolute_operator", "abs", false),
+
+ NOT("not_operator", "not", false),
+
+ CONDITION("condition_operator", "???", true), /* FIXME: what's this? */
+
+ /* Flattens vectors using an operator. */
+ REDUCTION_AND("reduction_and_operator", "and", false),
+ REDUCTION_OR("reduction_or_operator", "or", false),
+ REDUCTION_NAND("reduction_nand_operator", "nand", false),
+ REDUCTION_NOR("reduction_nor_operator", "nor", false),
+ REDUCTION_XOR("reduction_xor_operator", "xor", false),
+ REDUCTION_XNOR("reduction_xnor_operator", "xnor", false),
+
+ AND("and_operator", "and", true),
+ OR("or_operator", "or", true),
+ NAND("nand_operator", "nand", true),
+ NOR("nor_operator", "nor", true),
+ XOR("xor_operator", "xor", true),
+ XNOR("xnor_operator", "xnor", true),
+
+ EQUALITY("equality_operator", "=", true),
+ INEQUALITY("inequality_operator", "/=", true),
+ LESS_THAN("less_than_operator", "<", true),
+ LESS_THAN_OR_EQUAL("less_than_or_equal_operator", "<=", true),
+ GREATER_THAN("greater_than_operator", ">", true),
+ GREATER_THAN_OR_EQUAL("greater_than_or_equal_operator", ">=", true),
+
+ /* FIXME: What are those? */
+ MATCH_EQUALITY("match_equality_operator", "???", true),
+ MATCH_INEQUALITY("match_inequality_operator", "???", true),
+ MATCH_LESS_THAN("match_less_than_operator", "???", true),
+ MATCH_LESS_THAN_OR_EQUAL
+ (
+ "match_less_than_or_equal_operator",
+ "???",
+ true
+ ),
+ MATCH_GREATER_THAN("match_greater_than_operator", "???", true),
+ MATCH_GREATER_THAN_OR_EQUAL
+ (
+ "match_greater_than_or_equal_operator",
+ "???",
+ true
+ ),
+
+ /* Called using "logical array OP integer", apparently. */
+ SLL("sll_operator", "sll", true),
+ SLA("sla_operator", "sla", true),
+ SRL("srl_operator", "srl", true),
+ SRA("sra_operator", "sra", true),
+ ROL("rol_operator", "rol", true),
+ ROR("ror_operator", "ror", true),
+
+ ADDITION("addition_operator", "+", true),
+ SUBSTRACTION("substraction_operator", "-", true),
+ CONCATENATION("concatenation_operator", "&", true),
+ MULTIPLICATION("multiplication_operator", "*", true),
+ DIVISION("division_operator", "/", true),
+ MODULUS("modulus_operator", "mod", true),
+ REMAINDER("remainder_operator", "rem", true),
+ EXPONENTIATION("exponentiation_operator", "**", true);
+
+ /** Static **************************************************************/
+ private static final Map<String, Operator> FROM_TAG;
+
+ static
+ {
+ final Operator operators[];
+
+ FROM_TAG = new HashMap<String, Operator>();
+
+ operators = Operator.class.getEnumConstants(); /* We Java now... */
+
+ for (final Operator op: operators)
+ {
+ FROM_TAG.put(op.tag, op);
+ }
+ }
+
+ /** Non-Static **********************************************************/
+ private final String tag;
+ private final String symbol;
+ private final boolean is_binary;
+
+ private Operator
+ (
+ final String tag,
+ final String symbol,
+ final boolean is_binary
+ )
+ {
+ this.tag = tag;
+ this.symbol = symbol;
+ this.is_binary = is_binary;
+ }
+ }
+
+ public static void process
+ (
+ final List<IDs> elements,
+ final StringBuilder structure,
+ final Node current_node
+ )
+ throws XPathExpressionException
+ {
+ final String kind;
+ final Operator op;
+
+ kind = XMLManager.get_attribute(current_node, "kind");
+
+ op = Operator.FROM_TAG.get(kind);
+
+ if (op == null)
+ {
+ process_non_operator(elements, structure, current_node, kind);
+ }
+ else if (op.is_binary)
+ {
+ structure.append("(?");
+ elements.add
+ (
+ Strings.get_id_from_string
+ (
+ op.symbol
+ )
+ );
+
+ process
+ (
+ elements,
+ structure,
+ (Node) XPE_GET_LEFT_SIDE.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ )
+ );
+
+ process
+ (
+ elements,
+ structure,
+ (Node) XPE_GET_RIGHT_SIDE.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ )
+ );
+
+ structure.append(")");
+ }
+ else
+ {
+ structure.append("(?");
+ elements.add
+ (
+ Strings.get_id_from_string
+ (
+ op.symbol
+ )
+ );
+
+ process
+ (
+ elements,
+ structure,
+ (Node) XPE_GET_OPERAND.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ )
+ );
+
+ structure.append(")");
+ }
+ }
+
+ public static void process_non_operator
+ (
+ final List<IDs> elements,
+ final StringBuilder structure,
+ final Node current_node,
+ final String kind
+ )
+ throws XPathExpressionException
+ {
+ if (kind.equals("simple_name"))
+ {
+ final Node named_entity;
+
+ named_entity =
+ (Node) XPE_GET_NAMED_ENTITY.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ );
+
+ structure.append("?");
+
+ elements.add
+ (
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(named_entity, "ref"),
+ null
+ )
+ )
+ );
+ }
+ else if (kind.equals("function_call"))
+ {
+ final Node named_entity;
+ final NodeList params;
+ final int params_length;
+
+ named_entity =
+ (Node) XPE_GET_PREFIX/*_NAMED_ENTITY*/.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ );
+
+ structure.append("(?");
+
+ /*
+ * TODO: Handle functions better, like:
+ elements.add
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(named_entity, "ref"),
+ null
+ )
+ );
+ * But for now, we'll just use the function's name as string:
+ */
+ elements.add
+ (
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(named_entity, "identifier")
+ )
+ );
+
+
+ params =
+ (NodeList) XPE_GET_FUN_PARAMETERS.evaluate
+ (
+ current_node,
+ XPathConstants.NODESET
+ );
+
+ params_length = params.getLength();
+
+ for (int i = 0; i < params_length; ++i)
+ {
+ process
+ (
+ elements,
+ structure,
+ params.item(i)
+ );
+ }
+
+ structure.append(")");
+ }
+ else if (kind.equals("indexed_name")) /* vector */
+ {
+ final Node named_entity;
+ final NodeList params;
+ final int params_length;
+
+ named_entity =
+ (Node) XPE_GET_PREFIX_NAMED_ENTITY.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ );
+
+ structure.append("(?");
+
+ elements.add
+ (
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(named_entity, "ref"),
+ null
+ )
+ )
+ );
+
+ params =
+ (NodeList) XPE_GET_INDEX_LIST.evaluate
+ (
+ current_node,
+ XPathConstants.NODESET
+ );
+
+ params_length = params.getLength();
+
+ for (int i = 0; i < params_length; ++i)
+ {
+ process
+ (
+ elements,
+ structure,
+ params.item(i)
+ );
+ }
+
+ structure.append(")");
+ }
+ else if (kind.contains("literal"))
+ {
+ /*
+ grep "Kind.*Literal" ./src/vhdl/nodes_meta.adb | sort | uniq -u
+ points to:
+ "character_literal";
+ "enumeration_literal";
+ "floating_point_literal";
+ "integer_literal";
+ "null_literal";
+ "overflow_literal";
+ "physical_fp_literal";
+ "physical_int_literal";
+ "physical_literal"; (unsure if it can happen)
+ "string_literal8";
+
+ They don't all use the same structure, so we're going to handle them
+ later.
+ TODO
+ */
+
+ structure.append("?");
+ elements.add
+ (
+ Strings.get_id_from_string
+ (
+ "l"
+ )
+ );
+
+ }
+ else if (kind.contains("attribute"))
+ {
+ structure.append("(?");
+
+ elements.add
+ (
+ Strings.get_id_from_string
+ (
+ /* FIXME: Kind of a hacky */
+ kind.replace("_attribute", "")
+ )
+ );
+
+ process
+ (
+ elements,
+ structure,
+ (Node) XPE_GET_PREFIX.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ )
+ );
+
+ structure.append(")");
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/Functions.java b/src/ghdl2hastabel/Functions.java
new file mode 100644
index 0000000..b854c0d
--- /dev/null
+++ b/src/ghdl2hastabel/Functions.java
@@ -0,0 +1,33 @@
+package ghdl2hastabel;
+
+public class Functions
+{
+ public static void add_entry
+ (
+ final String function_name,
+ final IDs... params
+ )
+ {
+ add_entry(Main.get_main_output(), function_name, params);
+ }
+
+ public static void add_entry
+ (
+ final OutputFile output,
+ final String function_name,
+ final IDs... params
+ )
+ {
+ output.write("(set_function ");
+
+ output.write(function_name);
+
+ for (final IDs param: params)
+ {
+ output.write(" " + param.get_value());
+ }
+
+ output.write(")");
+ output.insert_newline();
+ }
+}
diff --git a/src/ghdl2hastabel/IDs.java b/src/ghdl2hastabel/IDs.java
new file mode 100644
index 0000000..23bdafb
--- /dev/null
+++ b/src/ghdl2hastabel/IDs.java
@@ -0,0 +1,134 @@
+package ghdl2hastabel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.HashMap;
+
+public class IDs
+{
+ /** Static *****************************************************************/
+ private static final Map<String, IDs> FROM_XML;
+ private static final OutputFile XML_MAP_OUTPUT;
+ private static int next_id;
+
+ static
+ {
+ next_id = 0;
+
+ FROM_XML = new HashMap<String, IDs>();
+
+ /* TODO: filename as a param? */
+ XML_MAP_OUTPUT = OutputFile.new_output_file("xml_to_instr.map");
+ }
+
+ public static IDs get_id_from_xml_id
+ (
+ final String xml_id,
+ final String type
+ )
+ {
+ return
+ get_id_from_xml_id
+ (
+ Main.get_main_output(),
+ xml_id,
+ type
+ );
+ }
+
+ public static IDs get_id_from_xml_id
+ (
+ final OutputFile output,
+ final String xml_id,
+ final String type
+ )
+ {
+ IDs result;
+
+ result = FROM_XML.get(xml_id);
+
+ if (result == null)
+ {
+ result = generate_new_id(output, type);
+
+ FROM_XML.put(xml_id, result);
+
+ XML_MAP_OUTPUT.write("(xml->instr ");
+ XML_MAP_OUTPUT.write(xml_id);
+ XML_MAP_OUTPUT.write(" ");
+ XML_MAP_OUTPUT.write(Integer.toString(result.get_value()));
+ XML_MAP_OUTPUT.write(")");
+ XML_MAP_OUTPUT.insert_newline();
+
+ }
+ else if ((result.type == null) && (type != null))
+ {
+ /* This allows us to get an ID from a simple reference. */
+ result.type = type;
+
+ result.add_to_output(output);
+ }
+
+ return result;
+ }
+
+ public static IDs generate_new_id
+ (
+ final String type
+ )
+ {
+ return generate_new_id(Main.get_main_output(), type);
+ }
+
+ public static IDs generate_new_id
+ (
+ final OutputFile output,
+ final String type
+ )
+ {
+ final IDs result;
+
+ result = new IDs(type);
+
+ if (type != null)
+ {
+ result.add_to_output(output);
+ }
+
+ return result;
+ }
+
+ /** Non-Static *************************************************************/
+ private final int value;
+ private String type;
+
+ private IDs (final String type)
+ {
+ this.type = type;
+
+ value = IDs.next_id;
+
+ IDs.next_id += 1;
+ }
+
+ public String get_type ()
+ {
+ return type;
+ }
+
+ public int get_value ()
+ {
+ return value;
+ }
+
+ private void add_to_output (final OutputFile output)
+ {
+ output.write("(add_element ");
+ output.write(type);
+ output.write(" ");
+ output.write(Integer.toString(value));
+ output.write(")");
+ output.insert_newline();
+ }
+}
diff --git a/src/ghdl2hastabel/Main.java b/src/ghdl2hastabel/Main.java
new file mode 100644
index 0000000..0850e06
--- /dev/null
+++ b/src/ghdl2hastabel/Main.java
@@ -0,0 +1,184 @@
+package ghdl2hastabel;
+
+import ghdl2hastabel.vhdl.File;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Collection;
+import java.util.Stack;
+
+public class Main
+{
+ private static final XPathExpression XPE_FIND_ALL_VHDL_FILES;
+ private static Parameters PARAMETERS;
+ private static Document XML_ROOT;
+ private static OutputFile MAIN_OUTPUT;
+
+ static
+ {
+ XPE_FIND_ALL_VHDL_FILES =
+ XMLManager.compile_or_die
+ (
+ //"./*/*/el[@kind=\"design_file\"][@file]"
+ "//el[@kind=\"design_file\"][@file]"
+ );
+ }
+
+ public static void main (final String... args)
+ {
+ final Collection<Node> vhdl_files;
+
+ PARAMETERS = new Parameters(args);
+
+ if (!PARAMETERS.are_valid())
+ {
+ return;
+ }
+
+ try
+ {
+ XML_ROOT = XMLManager.get_document(PARAMETERS.get_xml_file());
+ }
+ catch (final Exception e)
+ {
+ System.err.println
+ (
+ "[E] Could not load XML file \""
+ + PARAMETERS.get_xml_file()
+ + "\":"
+ );
+
+ e.printStackTrace();
+
+ return;
+ }
+
+ MAIN_OUTPUT = OutputFile.new_output_file("structural.mod");
+
+ try
+ {
+ vhdl_files =
+ XMLManager.node_list_to_node_collection
+ (
+ (NodeList) XPE_FIND_ALL_VHDL_FILES.evaluate
+ (
+ XML_ROOT,
+ XPathConstants.NODESET
+ )
+ );
+ }
+ catch (final XPathExpressionException xpee)
+ {
+ System.err.println
+ (
+ "[E] Something went wrong when looking for the VHDL files:"
+ );
+
+ xpee.printStackTrace();
+
+ return;
+ }
+
+ parse_content(vhdl_files);
+
+ Depths.generate_predicates();
+
+ OutputFile.close_all();
+ }
+
+ private static void parse_content (final Collection<Node> vhdl_files)
+ {
+ /* Stack highly recommended over FIFO (you don't want to grow large). */
+ final Stack<ParsableXML> waiting_list;
+
+ waiting_list = new Stack<ParsableXML>();
+
+ for (final Node f: vhdl_files)
+ {
+ waiting_list.push(new File(null, f));
+ }
+
+ while (!waiting_list.isEmpty())
+ {
+ final Collection<ParsableXML> children;
+
+ try
+ {
+ waiting_list.pop().parse(waiting_list);
+ }
+ catch (final XPathExpressionException xpee)
+ {
+ System.err.println
+ (
+ "[E] Something went wrong while parsing the XML file:"
+ );
+
+ xpee.printStackTrace();
+
+ return;
+ }
+ }
+ }
+
+ public static boolean node_is_function_or_literal (final String xml_id)
+ throws XPathExpressionException
+ {
+ final XPathExpression xpe_find_el_from_id;
+ final Node n;
+ final String kind;
+
+ xpe_find_el_from_id =
+ XMLManager.compile_or_die
+ (
+ ".//el[@id=\""
+ + xml_id
+ + "\"]"
+ );
+
+ n =
+ (Node) xpe_find_el_from_id.evaluate
+ (
+ XML_ROOT,
+ XPathConstants.NODE
+ );
+
+ if (n == (Node) null)
+ {
+ return true;
+ }
+
+ kind = XMLManager.get_attribute(n, "kind");
+
+ if (kind.equals("function_declaration"))
+ {
+ return true;
+ }
+ else if (kind.equals("enumeration_literal"))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ public static Document get_xml_root ()
+ {
+ return XML_ROOT;
+ }
+
+ public static OutputFile get_main_output ()
+ {
+ return MAIN_OUTPUT;
+ }
+
+ public static Parameters get_parameters ()
+ {
+ return PARAMETERS;
+ }
+}
diff --git a/src/ghdl2hastabel/OutputFile.java b/src/ghdl2hastabel/OutputFile.java
new file mode 100644
index 0000000..45ef252
--- /dev/null
+++ b/src/ghdl2hastabel/OutputFile.java
@@ -0,0 +1,137 @@
+package ghdl2hastabel;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.BufferedWriter;
+
+public class OutputFile
+{
+ private static Collection<OutputFile> ALL_OUTPUT_FILES;
+
+ static
+ {
+ ALL_OUTPUT_FILES = new ArrayList<OutputFile>();
+ }
+
+ public static void close_all ()
+ {
+ for (final OutputFile f: ALL_OUTPUT_FILES)
+ {
+ f.close();
+ }
+ }
+
+ public static OutputFile new_output_file (final String filename)
+ {
+ final OutputFile result;
+
+ result =
+ new OutputFile
+ (
+ Main.get_parameters().get_output_directory()
+ + "/"
+ + filename
+ );
+
+ ALL_OUTPUT_FILES.add(result);
+
+ return result;
+ }
+
+ /** Non-Static *************************************************************/
+ private final String filename;
+ private final BufferedWriter buffered_writer;
+
+ private OutputFile (final String filename)
+ {
+ BufferedWriter bf;
+
+ this.filename = filename;
+
+ try
+ {
+ bf = new BufferedWriter(new FileWriter(new File(filename)));
+ }
+ catch (final Exception e)
+ {
+ bf = null;
+
+ System.err.println
+ (
+ "[F] Could not create new output file \""
+ + filename
+ + "\":"
+ );
+
+ e.printStackTrace();
+
+ System.exit(-1);
+ }
+
+ buffered_writer = bf;
+ }
+
+ public void write (final String data)
+ {
+ try
+ {
+ buffered_writer.write(data);
+ }
+ catch (final Exception e)
+ {
+ System.err.println
+ (
+ "[F] Could not write to output file \""
+ + filename
+ + "\":"
+ );
+
+ e.printStackTrace();
+
+ System.exit(-1);
+ }
+ }
+
+ public void insert_newline ()
+ {
+ try
+ {
+ buffered_writer.newLine();
+ }
+ catch (final Exception e)
+ {
+ System.err.println
+ (
+ "[F] Could not write to output file \""
+ + filename
+ + "\":"
+ );
+
+ e.printStackTrace();
+
+ System.exit(-1);
+ }
+ }
+
+ private void close ()
+ {
+ try
+ {
+ buffered_writer.close();
+ }
+ catch (final Exception e)
+ {
+ System.err.println
+ (
+ "[E] Could not properly close output file \""
+ + filename
+ + "\":"
+ );
+
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/Parameters.java b/src/ghdl2hastabel/Parameters.java
new file mode 100644
index 0000000..522ffb4
--- /dev/null
+++ b/src/ghdl2hastabel/Parameters.java
@@ -0,0 +1,59 @@
+package ghdl2hastabel;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class Parameters
+{
+ private final String xml_file;
+ private final String output_dir;
+
+ private final boolean are_valid;
+
+ public static void print_usage ()
+ {
+ System.out.println
+ (
+ "AST-to-Instr\n"
+ + "USAGE:\n"
+ + "\tjava Main <XML_FILE> <OUTPUT_DIR>\n"
+ + "PARAMETERS:\n"
+ + "\t- <XML_FILE>\tThe AST (XML format).\n"
+ + "\t- <OUTPUT_DIR>\tThe output directory (must already exist)."
+ );
+ }
+
+ public Parameters (String... args)
+ {
+ if (args.length != 2)
+ {
+ print_usage();
+
+ xml_file = new String();
+ output_dir = new String();
+ are_valid = false;
+
+ return;
+ }
+
+ xml_file = args[0];
+ output_dir = args[1];
+
+ are_valid = true;
+ }
+
+ public String get_xml_file ()
+ {
+ return xml_file;
+ }
+
+ public String get_output_directory ()
+ {
+ return output_dir;
+ }
+
+ public boolean are_valid ()
+ {
+ return are_valid;
+ }
+}
diff --git a/src/ghdl2hastabel/ParsableXML.java b/src/ghdl2hastabel/ParsableXML.java
new file mode 100644
index 0000000..f5cf29b
--- /dev/null
+++ b/src/ghdl2hastabel/ParsableXML.java
@@ -0,0 +1,32 @@
+package ghdl2hastabel;
+
+import org.w3c.dom.Node;
+
+import java.util.Stack;
+
+import javax.xml.xpath.XPathExpressionException;
+
+public abstract class ParsableXML
+{
+ protected final IDs parent_id;
+ protected final Node xml_node;
+
+ public ParsableXML
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ this.parent_id = parent_id;
+ this.xml_node = xml_node;
+ }
+
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+
+ }
+}
diff --git a/src/ghdl2hastabel/Predicates.java b/src/ghdl2hastabel/Predicates.java
new file mode 100644
index 0000000..3b14e7c
--- /dev/null
+++ b/src/ghdl2hastabel/Predicates.java
@@ -0,0 +1,33 @@
+package ghdl2hastabel;
+
+public class Predicates
+{
+ public static void add_entry
+ (
+ final String predicate_name,
+ final IDs... params
+ )
+ {
+ add_entry(Main.get_main_output(), predicate_name, params);
+ }
+
+ public static void add_entry
+ (
+ final OutputFile output,
+ final String predicate_name,
+ final IDs... params
+ )
+ {
+ output.write("(");
+
+ output.write(predicate_name);
+
+ for (final IDs param: params)
+ {
+ output.write(" " + param.get_value());
+ }
+
+ output.write(")");
+ output.insert_newline();
+ }
+}
diff --git a/src/ghdl2hastabel/Strings.java b/src/ghdl2hastabel/Strings.java
new file mode 100644
index 0000000..68e17e9
--- /dev/null
+++ b/src/ghdl2hastabel/Strings.java
@@ -0,0 +1,56 @@
+package ghdl2hastabel;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class Strings
+{
+ private static final Map<String, IDs> TO_ID;
+ private static final OutputFile STRING_MAP_OUTPUT;
+
+ static
+ {
+ TO_ID = new HashMap<String, IDs>();
+
+ /* TODO: filename as a param? */
+ STRING_MAP_OUTPUT = OutputFile.new_output_file("string_to_instr.map");
+ }
+
+ private Strings () {} /* Utility class. */
+
+ public static IDs get_id_from_string
+ (
+ final String string
+ )
+ {
+ return get_id_from_string(Main.get_main_output(), string);
+ }
+
+ public static IDs get_id_from_string
+ (
+ final OutputFile output,
+ String string
+ )
+ {
+ IDs result;
+
+ string = string.toLowerCase();
+ result = TO_ID.get(string);
+
+ if (result == null)
+ {
+ result = IDs.generate_new_id(output, "string");
+
+ TO_ID.put(string, result);
+
+ STRING_MAP_OUTPUT.write("(string->instr \"");
+ STRING_MAP_OUTPUT.write(string);
+ STRING_MAP_OUTPUT.write("\" ");
+ STRING_MAP_OUTPUT.write(Integer.toString(result.get_value()));
+ STRING_MAP_OUTPUT.write(")");
+ STRING_MAP_OUTPUT.insert_newline();
+ }
+
+ return result;
+ }
+}
diff --git a/src/ghdl2hastabel/Waveforms.java b/src/ghdl2hastabel/Waveforms.java
new file mode 100644
index 0000000..682541c
--- /dev/null
+++ b/src/ghdl2hastabel/Waveforms.java
@@ -0,0 +1,32 @@
+package ghdl2hastabel;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public class Waveforms
+{
+ private static final Map<IDs, IDs> TO_WAVEFORM;
+
+ static
+ {
+ TO_WAVEFORM = new HashMap<IDs, IDs>();
+ }
+
+ private Waveforms () {} /* Utility class. */
+
+ public static IDs get_associated_waveform_id (final IDs source)
+ {
+ IDs result;
+
+ result = TO_WAVEFORM.get(source);
+
+ if (result == null)
+ {
+ result = IDs.generate_new_id("waveform");
+
+ TO_WAVEFORM.put(source, result);
+ }
+
+ return result;
+ }
+}
diff --git a/src/ghdl2hastabel/XMLManager.java b/src/ghdl2hastabel/XMLManager.java
new file mode 100644
index 0000000..f12c990
--- /dev/null
+++ b/src/ghdl2hastabel/XMLManager.java
@@ -0,0 +1,128 @@
+package ghdl2hastabel;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class XMLManager
+{
+ /* ... */
+ /* private static final DocumentBuilderFactoryCreatorMakerInstanciator; */
+ /* private static final DocumentBuilderFactoryCreatorMaker; */
+ /* private static final DocumentBuilderFactoryCreator; */
+ private static final DocumentBuilderFactory DOC_BUILDER_FACTORY;
+ private static final DocumentBuilder DOC_BUILDER;
+
+ private static final XPathFactory XPATH_FACTORY;
+ private static final XPath XPATH;
+
+ static
+ {
+ DocumentBuilder i_dont_even;
+
+ DOC_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
+
+ try
+ {
+ i_dont_even = DOC_BUILDER_FACTORY.newDocumentBuilder();
+ }
+ catch (final Exception e)
+ {
+ i_dont_even = null;
+
+ System.err.println
+ (
+ "[E] Err... You somehow managed to trigger an exception from purely"
+ + " static members:"
+ );
+
+ e.printStackTrace();
+
+ System.exit(-1);
+ }
+
+ DOC_BUILDER = i_dont_even;
+
+ XPATH_FACTORY = XPathFactory.newInstance();
+ XPATH = XPATH_FACTORY.newXPath();
+ }
+
+ private XMLManager () {} /* Utility Class. */
+
+ public static Document get_document (final String filename)
+ throws
+ SAXException,
+ IOException
+ {
+ final File file;
+
+ file = new File(filename);
+
+ return DOC_BUILDER.parse(file);
+ }
+
+ public static XPathExpression compile (final String expression)
+ throws XPathExpressionException
+ {
+ return XPATH.compile(expression);
+ }
+
+ public static XPathExpression compile_or_die (final String expression)
+ {
+ try
+ {
+ return XPATH.compile(expression);
+ }
+ catch (final XPathExpressionException xpee)
+ {
+ System.err.println("[P] Invalid XPathExpression (report as bug):");
+ xpee.printStackTrace();
+
+ System.exit(-1);
+ }
+
+ return null; /* Because Java. */
+ }
+
+ public static Collection<Node> node_list_to_node_collection
+ (
+ final NodeList nl
+ )
+ {
+ final Collection<Node> result;
+ final int nl_length;
+
+ result = new ArrayList<Node>();
+
+ nl_length = nl.getLength();
+
+ for (int i = 0; i < nl_length; ++i)
+ {
+ result.add(nl.item(i));
+ }
+
+ return result;
+ }
+
+ public static String get_attribute (final Node n, final String attr)
+ {
+ return n.getAttributes().getNamedItem(attr).getNodeValue();
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/.Node.java.swp b/src/ghdl2hastabel/vhdl/.Node.java.swp
new file mode 100644
index 0000000..942ae52
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/.Node.java.swp
Binary files differ
diff --git a/src/ghdl2hastabel/vhdl/Architecture.java b/src/ghdl2hastabel/vhdl/Architecture.java
new file mode 100644
index 0000000..36a6819
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Architecture.java
@@ -0,0 +1,351 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Architecture extends ParsableXML
+{
+ private static final XPathExpression XPE_FIND_ENTITY_NAME;
+ private static final XPathExpression XPE_FIND_SIGNALS;
+ private static final XPathExpression XPE_FIND_PROCESSES;
+ private static final XPathExpression XPE_FIND_COMPONENTS;
+
+ static
+ {
+ XPE_FIND_ENTITY_NAME =
+ XMLManager.compile_or_die
+ (
+ "./entity_name/named_entity"
+ );
+
+ XPE_FIND_SIGNALS =
+ XMLManager.compile_or_die
+ (
+ "./*/el[@kind=\"signal_declaration\"]"
+ );
+
+ XPE_FIND_PROCESSES =
+ XMLManager.compile_or_die
+ (
+ "./*/el[@kind=\"sensitized_process_statement\"]"
+ );
+
+ XPE_FIND_COMPONENTS =
+ XMLManager.compile_or_die
+ (
+ "./*/el[@kind=\"component_instantiation_statement\"]"
+ );
+ }
+
+ public Architecture
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "architecture");
+
+ /** Parent **************************************************************/
+ handle_link_to_file(local_id);
+ handle_link_to_entity(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_identifier(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_foreign_flag(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_is_withing_flag(local_id);
+ handle_predicate_end_has_reserved_id(local_id);
+ handle_predicate_end_has_identifier(local_id);
+
+ /** Children ************************************************************/
+ handle_child_signals(local_id, waiting_list);
+ handle_child_processes(local_id, waiting_list);
+ handle_child_components(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_file
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("is_in_file", local_id, parent_id);
+ }
+
+ private void handle_link_to_entity
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final Node entity_name;
+
+ entity_name =
+ (Node) XPE_FIND_ENTITY_NAME.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ if (entity_name == (Node) null)
+ {
+ System.err.println
+ (
+ "[W] Could not find entity the associated with architecture "
+ + local_id
+ + " (XML ID: "
+ + XMLManager.get_attribute(xml_node, "id")
+ + ")."
+ );
+
+ return;
+ }
+
+ Predicates.add_entry
+ (
+ "is_architecture_of",
+ local_id,
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(entity_name, "ref"),
+ "entity"
+ )
+ );
+ }
+
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_identifier
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "identifier",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "identifier")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_foreign_flag
+ (
+ final IDs local_id
+ )
+ {
+ if (XMLManager.get_attribute(xml_node, "foreign_flag").equals("true"))
+ {
+ Predicates.add_entry("has_foreign_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if (XMLManager.get_attribute(xml_node, "visible_flag").equals("true"))
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_is_withing_flag
+ (
+ final IDs local_id
+ )
+ {
+ if (XMLManager.get_attribute(xml_node, "is_within_flag").equals("true"))
+ {
+ Predicates.add_entry("is_within_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_reserved_id
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_reserved_id"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_reserved_id", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_identifier
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_identifier"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_identifier", local_id);
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_signals
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList signals;
+ final int children_count;
+
+ signals =
+ (NodeList) XPE_FIND_SIGNALS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = signals.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Signal(local_id, signals.item(i)));
+ }
+ }
+
+ private void handle_child_processes
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList processes;
+ final int children_count;
+
+ processes =
+ (NodeList) XPE_FIND_PROCESSES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = processes.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Process(local_id, processes.item(i)));
+ }
+ }
+
+ private void handle_child_components
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList components;
+ final int children_count;
+
+ components =
+ (NodeList) XPE_FIND_COMPONENTS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = components.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Component(local_id, components.item(i)));
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/CSNode.java b/src/ghdl2hastabel/vhdl/CSNode.java
new file mode 100644
index 0000000..bb36824
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/CSNode.java
@@ -0,0 +1,309 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Depths;
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+/* Case Statement Node */
+public class CSNode extends ghdl2hastabel.vhdl.Node
+{
+ private static final XPathExpression XPE_FIND_SOURCES;
+ private static final XPathExpression XPE_FIND_OTHERS_BRANCH;
+ private static final XPathExpression XPE_FIND_WHEN_BRANCHES;
+
+ static
+ {
+ XPE_FIND_SOURCES =
+ XMLManager.compile_or_die
+ (
+ "./expression"/*//named_entity"*/
+ );
+
+ XPE_FIND_OTHERS_BRANCH =
+ XMLManager.compile_or_die
+ (
+ "./case_statement_alternative_chain/el[@kind=\"choice_by_others\"]"
+ );
+
+ XPE_FIND_WHEN_BRANCHES =
+ XMLManager.compile_or_die
+ (
+ "./case_statement_alternative_chain/el"
+ + "[@kind=\"choice_by_expression\"]"
+ );
+ }
+
+ public CSNode
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final Node xml_node,
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super
+ (
+ output,
+ parent_id,
+ xml_node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(output, xml_id, "node");
+
+ /** Functions ***********************************************************/
+ handle_function_label(local_id);
+ handle_function_kind(local_id);
+ handle_function_depth(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_option(local_id);
+ handle_predicate_expr_reads(local_id);
+
+ /** Children ************************************************************/
+ handle_when_branches(local_id, waiting_list);
+ handle_others_branch(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "label",
+ local_id,
+ Strings.get_id_from_string
+ (
+ output,
+ XMLManager.get_attribute(xml_node, "label")
+ )
+ );
+ }
+
+ private void handle_function_kind
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "kind",
+ local_id,
+ Strings.get_id_from_string("case")
+ );
+ }
+
+ private void handle_function_depth
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "depth",
+ local_id,
+ Depths.get_id_from_depth(new Integer(depth))
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_option
+ (
+ final IDs local_id
+ )
+ {
+ for (final String s: attributes)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "has_option",
+ local_id,
+ Strings.get_id_from_string(s)
+ );
+ }
+ }
+
+ private void handle_predicate_expr_reads
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final Node sources;
+
+ sources =
+ (Node) XPE_FIND_SOURCES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ handle_read_expr_predicates(local_id, sources);
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_when_branches
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList when_branches;
+ final int when_branches_length;
+
+ when_branches =
+ (NodeList) XPE_FIND_WHEN_BRANCHES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ when_branches_length = when_branches.getLength();
+
+ for (int i = 0; i < when_branches_length; ++i)
+ {
+ final Node child;
+ final String child_xml_id;
+ final IDs child_local_id;
+
+ child = when_branches.item(i);
+ child_xml_id = XMLManager.get_attribute(child, "id");
+ child_local_id = IDs.get_id_from_xml_id(output, child_xml_id, "node");
+
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ local_id,
+ child_local_id
+ );
+
+ waiting_list.add
+ (
+ new WNode
+ (
+ output,
+ parent_id,
+ when_branches.item(i),
+ next_node,
+ (depth + 1),
+ new String[0]
+ )
+ );
+ }
+ }
+
+ private void handle_others_branch
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final Node others_branch;
+
+ others_branch =
+ (Node) XPE_FIND_OTHERS_BRANCH.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ if (others_branch == (Node) null)
+ {
+ if (next_node == (IDs) null)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "is_terminal",
+ local_id
+ );
+ }
+ else
+ {
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ local_id,
+ next_node
+ );
+ }
+ }
+ else
+ {
+ final String child_xml_id;
+ final IDs child_local_id;
+
+ child_xml_id = XMLManager.get_attribute(others_branch, "id");
+ child_local_id = IDs.get_id_from_xml_id(output, child_xml_id, "node");
+
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ local_id,
+ child_local_id
+ );
+
+ waiting_list.push
+ (
+ new WNode
+ (
+ output,
+ parent_id,
+ others_branch,
+ next_node,
+ (depth + 1),
+ new String[] {"WHEN_OTHERS"}
+ )
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Component.java b/src/ghdl2hastabel/vhdl/Component.java
new file mode 100644
index 0000000..8c2d4fe
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Component.java
@@ -0,0 +1,449 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Main;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Component extends ParsableXML
+{
+ private static final XPathExpression XPE_FIND_INST_UNIT;
+ private static final XPathExpression XPE_FIND_BASE_NAME;
+ private static final XPathExpression XPE_FIND_ENTITY_NAME;
+ private static final XPathExpression XPE_FIND_LIBRARY_NAME;
+
+ private static final XPathExpression XPE_FIND_PORT_MAPS;
+ private static final XPathExpression XPE_FIND_REAL_PORTS;
+ private static final XPathExpression XPE_FIND_ACTUAL_NE;
+ private static final XPathExpression XPE_FIND_FORMAL;
+
+ private static final XPathExpression XPE_FIND_GENERIC_MAPS;
+
+ static
+ {
+ XPE_FIND_INST_UNIT = XMLManager.compile_or_die("./instantiated_unit");
+ XPE_FIND_BASE_NAME = XMLManager.compile_or_die("./base_name");
+
+ XPE_FIND_ENTITY_NAME = XMLManager.compile_or_die
+ (
+ "./entity_name[@kind=\"selected_name\"]"
+ );
+
+ XPE_FIND_LIBRARY_NAME = XMLManager.compile_or_die
+ (
+ "./prefix[@kind=\"simple_name\"]"
+ );
+
+ XPE_FIND_PORT_MAPS =
+ XMLManager.compile_or_die
+ (
+ "./port_map_aspect_chain/el"
+ + "[@kind=\"association_element_by_expression\"]"
+ );
+
+ XPE_FIND_REAL_PORTS =
+ XMLManager.compile_or_die
+ (
+ "./port_chain/el[@kind=\"interface_signal_declaration\"]"
+ );
+
+ XPE_FIND_ACTUAL_NE = XMLManager.compile_or_die("./actual/named_entity");
+ XPE_FIND_FORMAL = XMLManager.compile_or_die("./formal");
+
+ XPE_FIND_GENERIC_MAPS = null; /* TODO */
+ }
+
+ public Component
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+ final Node linked_entity;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "component");
+
+ /** Parent **************************************************************/
+ handle_link_to_architecture(local_id);
+ linked_entity = handle_link_to_entity(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_label(local_id);
+
+ /** Predicates **********************************************************/
+
+ if (linked_entity != (Node) null)
+ {
+ handle_predicate_port_maps(local_id, linked_entity);
+ handle_predicate_generic_maps(local_id, linked_entity);
+ }
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_architecture
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("belongs_to_architecture", local_id, parent_id);
+ }
+
+ private Node find_entity_from_internal_ref (Node current_node)
+ throws XPathExpressionException
+ {
+ XPathExpression current_query;
+
+ /*
+ * Get the item containing the reference to the internal description
+ * of this component.
+ */
+ current_node =
+ (Node) XPE_FIND_BASE_NAME.evaluate
+ (
+ current_node,
+ XPathConstants.NODE
+ );
+
+ /* Get the referenced component declaration. */
+ current_query =
+ XMLManager.compile_or_die
+ (
+ "./../../declaration_chain/el[@kind=\"component_declaration\"]"
+ + "[@id=\""
+ + XMLManager.get_attribute(current_node, "ref")
+ + "\"]"
+ );
+ current_node =
+ (Node) current_query.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ /* Actually get the entity. */
+ current_query =
+ XMLManager.compile_or_die
+ (
+ ".//library_unit[@kind=\"entity_declaration\"][@identifier=\""
+ + XMLManager.get_attribute(current_node, "identifier")
+ + "\"]"
+ );
+
+ return
+ (Node) current_query.evaluate
+ (
+ Main.get_xml_root(),
+ XPathConstants.NODE
+ );
+ }
+
+ private Node find_entity_from_direct_ref (final Node source_node)
+ throws XPathExpressionException
+ {
+ final XPathExpression xpe_get_matching_entity;
+ final Node entity_ref, library_ref;
+
+ entity_ref =
+ (Node) XPE_FIND_ENTITY_NAME.evaluate
+ (
+ source_node,
+ XPathConstants.NODE
+ );
+
+ library_ref =
+ (Node) XPE_FIND_ENTITY_NAME.evaluate
+ (
+ entity_ref,
+ XPathConstants.NODE
+ );
+
+ xpe_get_matching_entity =
+ XMLManager.compile_or_die
+ (
+ "./el[@kind=\"library_declaration\"][@identifier=\""
+ + XMLManager.get_attribute(library_ref, "identifier")
+ + "\"]//library_unit[@kind=\"entity_declaration\"][@identifier=\""
+ + XMLManager.get_attribute(entity_ref, "identifier")
+ + "\"]"
+ );
+
+ return
+ (Node) xpe_get_matching_entity.evaluate
+ (
+ Main.get_xml_root(),
+ XPathConstants.NODE
+ );
+ }
+
+ private Node handle_link_to_entity
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final String kind;
+ Node current_node;
+
+ current_node =
+ (Node) XPE_FIND_INST_UNIT.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ kind = XMLManager.get_attribute(current_node, "kind");
+
+ if (kind.equals("simple_name"))
+ {
+ current_node = find_entity_from_internal_ref(current_node);
+ }
+ else if (kind.equals("entity_aspect_entity"))
+ {
+ current_node = find_entity_from_direct_ref(current_node);
+ }
+ else
+ {
+ System.err.println
+ (
+ "[E] Unsupported component instantiation type for element "
+ + local_id.get_value()
+ + " (XML_ID: "
+ + XMLManager.get_attribute(xml_node, "id")
+ + ")."
+ );
+
+ return null;
+ }
+
+ if (current_node == (Node) null)
+ {
+ System.err.println
+ (
+ "[E] Could not find any entity for the component instantiation "
+ + local_id.get_value()
+ + " (XML_ID: "
+ + XMLManager.get_attribute(xml_node, "id")
+ + ")."
+ );
+
+ return null;
+ }
+
+ Predicates.add_entry
+ (
+ "is_component_of",
+ local_id,
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(current_node, "id"),
+ "entity"
+ )
+ );
+
+ return current_node;
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "label",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "label")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_port_maps
+ (
+ final IDs local_id,
+ final Node linked_entity
+ )
+ throws XPathExpressionException
+ {
+ final NodeList port_maps, real_ports;
+ final int port_maps_length;
+
+ port_maps =
+ (NodeList) XPE_FIND_PORT_MAPS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ real_ports =
+ (NodeList) XPE_FIND_REAL_PORTS.evaluate
+ (
+ linked_entity,
+ XPathConstants.NODESET
+ );
+
+ port_maps_length = port_maps.getLength();
+
+ for (int i = 0; i < port_maps_length; ++i)
+ {
+ final Node mapping, formal_name, actual_waveform;
+
+ mapping = port_maps.item(i);
+
+ actual_waveform =
+ (Node) XPE_FIND_ACTUAL_NE.evaluate
+ (
+ mapping,
+ XPathConstants.NODE
+ );
+
+ formal_name =
+ (Node) XPE_FIND_FORMAL.evaluate
+ (
+ mapping,
+ XPathConstants.NODE
+ );
+
+ if (formal_name == null)
+ {
+ Predicates.add_entry
+ (
+ "port_maps",
+ local_id,
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(actual_waveform, "ref"),
+ null
+ )
+ ),
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(real_ports.item(i), "id"),
+ "port"
+ )
+ );
+ }
+ else
+ {
+ final XPathExpression xpe_find_true_port;
+ final Node true_port;
+
+ xpe_find_true_port =
+ XMLManager.compile_or_die
+ (
+ "./port_chain/el[@identifier=\""
+ + XMLManager.get_attribute(formal_name, "identifier")
+ + "\"]"
+ );
+
+ true_port =
+ (Node) xpe_find_true_port.evaluate
+ (
+ linked_entity,
+ XPathConstants.NODE
+ );
+
+ Predicates.add_entry
+ (
+ "port_maps",
+ local_id,
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(actual_waveform, "ref"),
+ null
+ )
+ ),
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(true_port, "id"),
+ "port"
+ )
+ );
+ }
+ }
+ }
+
+ private void handle_predicate_generic_maps
+ (
+ final IDs local_id,
+ final Node linked_entity
+ )
+ throws XPathExpressionException
+ {
+ /* TODO */
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Entity.java b/src/ghdl2hastabel/vhdl/Entity.java
new file mode 100644
index 0000000..607a0d9
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Entity.java
@@ -0,0 +1,290 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Entity extends ParsableXML
+{
+ private static final XPathExpression XPE_FIND_PORTS;
+ private static final XPathExpression XPE_FIND_GENERICS;
+
+ static
+ {
+ XPE_FIND_PORTS =
+ XMLManager.compile_or_die
+ (
+ "./port_chain/el[@kind=\"interface_signal_declaration\"]"
+ );
+
+ XPE_FIND_GENERICS =
+ XMLManager.compile_or_die
+ (
+ "./generic_chain/el[@kind=\"interface_constant_declaration\"]"
+ );
+ }
+
+ public Entity
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "entity");
+
+ /** Parent **************************************************************/
+ handle_link_to_file(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_identifier(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_begin(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_is_withing_flag(local_id);
+ handle_predicate_end_has_reserved_id(local_id);
+ handle_predicate_end_has_identifier(local_id);
+
+ /** Children ************************************************************/
+ handle_child_ports(local_id, waiting_list);
+ handle_child_generics(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_file
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("is_in_file", local_id, parent_id);
+ }
+
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_identifier
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "identifier",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_begin
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_begin"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_begin", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "visible_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_is_withing_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_within_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_within_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_reserved_id
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_reserved_id"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_reserved_id", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_identifier
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_identifier"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_identifier", local_id);
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_ports
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList ports;
+ final int children_count;
+
+ ports =
+ (NodeList) XPE_FIND_PORTS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = ports.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Port(local_id, ports.item(i)));
+ }
+ }
+
+ private void handle_child_generics
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList generics;
+ final int children_count;
+
+ generics =
+ (NodeList) XPE_FIND_GENERICS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = generics.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Generic(local_id, generics.item(i)));
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/File.java b/src/ghdl2hastabel/vhdl/File.java
new file mode 100644
index 0000000..c321eb2
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/File.java
@@ -0,0 +1,145 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class File extends ParsableXML
+{
+ private static final XPathExpression XPE_FIND_ENTITIES;
+ private static final XPathExpression XPE_FIND_ARCHITECTURES;
+
+ static
+ {
+ XPE_FIND_ENTITIES =
+ XMLManager.compile_or_die
+ (
+ "./*/*/library_unit[@kind=\"entity_declaration\"]"
+ );
+
+ XPE_FIND_ARCHITECTURES =
+ XMLManager.compile_or_die
+ (
+ "./*/*/library_unit[@kind=\"architecture_body\"]"
+ );
+ }
+
+ public File
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "file");
+
+ /** Functions ***********************************************************/
+ handle_function_filename(local_id);
+
+ /** Predicates **********************************************************/
+
+ /** Children ************************************************************/
+ handle_child_entities(local_id, waiting_list);
+ handle_child_architectures(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_filename
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "filename",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "file")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_entities
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList entities;
+ final int children_count;
+
+ entities =
+ (NodeList) XPE_FIND_ENTITIES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = entities.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push(new Entity(local_id, entities.item(i)));
+ }
+ }
+
+ private void handle_child_architectures
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList architectures;
+ final int children_count;
+
+ architectures =
+ (NodeList) XPE_FIND_ARCHITECTURES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ children_count = architectures.getLength();
+
+ for (int i = 0; i < children_count; ++i)
+ {
+ waiting_list.push
+ (
+ new Architecture(local_id, architectures.item(i))
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Generic.java b/src/ghdl2hastabel/vhdl/Generic.java
new file mode 100644
index 0000000..3b86585
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Generic.java
@@ -0,0 +1,257 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Generic extends ParsableXML
+{
+ public Generic
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "generic");
+
+ /** Parent **************************************************************/
+ handle_link_to_entity(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_identifier(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_class(local_id);
+ handle_predicate_is_ref(local_id);
+ handle_predicate_has_identifier_list(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_has_after_drivers_flag(local_id);
+ handle_predicate_has_use_flag(local_id);
+
+ /** Children ************************************************************/
+ handle_child_waveform(local_id);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_entity
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("is_port_of", local_id, parent_id);
+ }
+
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_identifier
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "identifier",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "identifier")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_class
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_class"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_class", local_id);
+ }
+ }
+
+ private void handle_predicate_is_ref
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_ref"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_ref", local_id);
+ }
+ }
+
+ private void handle_predicate_has_identifier_list
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_identifier_list"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_identifier_list", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "visible_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_after_drivers_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "after_drivers_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_after_drivers_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_use_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "use_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_use_flag", local_id);
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_waveform
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry
+ (
+ "is_waveform_of",
+ Waveforms.get_associated_waveform_id
+ (
+ local_id
+ ),
+ local_id
+ );
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/ISNode.java b/src/ghdl2hastabel/vhdl/ISNode.java
new file mode 100644
index 0000000..d09a815
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/ISNode.java
@@ -0,0 +1,273 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Depths;
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+/* If Statement Node */
+public class ISNode extends ghdl2hastabel.vhdl.Node
+{
+ private static final XPathExpression XPE_FIND_SOURCES;
+ private static final XPathExpression XPE_FIND_TRUE_BRANCH;
+ private static final XPathExpression XPE_FIND_ELSE_BRANCH;
+
+ static
+ {
+ XPE_FIND_SOURCES =
+ XMLManager.compile_or_die
+ (
+ "./condition" /* //named_entity" */
+ );
+
+ XPE_FIND_TRUE_BRANCH =
+ XMLManager.compile_or_die
+ (
+ "./sequential_statement_chain"
+ );
+
+ XPE_FIND_ELSE_BRANCH =
+ XMLManager.compile_or_die
+ (
+ "./else_clause/sequential_statement_chain"
+ );
+ }
+
+ public ISNode
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final Node xml_node,
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super
+ (
+ output,
+ parent_id,
+ xml_node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(output, xml_id, "node");
+
+ /** Functions ***********************************************************/
+ handle_function_label(local_id);
+ handle_function_kind(local_id);
+ handle_function_depth(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_option(local_id);
+ handle_predicate_expr_reads(local_id);
+
+ /** Children ************************************************************/
+ handle_true_branch(local_id, waiting_list);
+ handle_else_branch(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "label",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "label")
+ )
+ );
+ }
+
+ private void handle_function_kind
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "kind",
+ local_id,
+ Strings.get_id_from_string("if")
+ );
+ }
+
+ private void handle_function_depth
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "depth",
+ local_id,
+ Depths.get_id_from_depth(new Integer(depth))
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_option
+ (
+ final IDs local_id
+ )
+ {
+ for (final String s: attributes)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "has_option",
+ local_id,
+ Strings.get_id_from_string(s)
+ );
+ }
+ }
+
+ private void handle_predicate_expr_reads
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final Node sources;
+
+ sources =
+ (Node) XPE_FIND_SOURCES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ handle_read_expr_predicates(local_id, sources);
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_true_branch
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final Node true_branch;
+
+ true_branch =
+ (Node) XPE_FIND_TRUE_BRANCH.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ waiting_list.push
+ (
+ new SSCNode
+ (
+ output,
+ parent_id,
+ true_branch,
+ local_id,
+ next_node,
+ (depth + 1),
+ new String[] {"COND_WAS_TRUE"}
+ )
+ );
+ }
+
+ private void handle_else_branch
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final Node else_branch;
+
+ else_branch =
+ (Node) XPE_FIND_ELSE_BRANCH.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ if (else_branch == (Node) null)
+ {
+ if (next_node == (IDs) null)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "is_terminal",
+ local_id
+ );
+ }
+ else
+ {
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ local_id,
+ next_node
+ );
+ }
+ }
+ else
+ {
+ waiting_list.push
+ (
+ new SSCNode
+ (
+ output,
+ parent_id,
+ else_branch,
+ local_id,
+ next_node,
+ (depth + 1),
+ new String[] {"COND_WAS_FALSE"}
+ )
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Node.java b/src/ghdl2hastabel/vhdl/Node.java
new file mode 100644
index 0000000..3469277
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Node.java
@@ -0,0 +1,137 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Expressions;
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.IDs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.xpath.XPathExpressionException;
+
+public abstract class Node extends ParsableXML
+{
+ protected final IDs next_node;
+ protected final int depth;
+ protected final String[] attributes;
+ protected final OutputFile output;
+
+ public Node
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final org.w3c.dom.Node xml_node,
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super(parent_id, xml_node);
+
+ this.output = output;
+ this.next_node = next_node;
+ this.depth = depth;
+ this.attributes = attributes;
+ }
+
+ protected void handle_read_expr_predicates
+ (
+ final IDs local_id,
+ final org.w3c.dom.Node expr_node
+ )
+ throws XPathExpressionException
+ {
+ final List<IDs> elements;
+ final StringBuilder structure;
+ final int elements_count;
+
+ elements = new ArrayList<IDs>();
+ structure = new StringBuilder();
+
+ Expressions.process(elements, structure, expr_node);
+
+ Predicates.add_entry
+ (
+ output,
+ "is_read_structure",
+ local_id,
+ Strings.get_id_from_string
+ (
+ structure.toString()
+ )
+ );
+
+ elements_count = elements.size();
+
+ for (int i = 0; i < elements_count; ++i)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "is_read_element",
+ local_id,
+ Strings.get_id_from_string(Integer.toString(i)),
+ elements.get(i)
+ );
+
+ Predicates.add_entry
+ (
+ "is_accessed_by",
+ elements.get(i),
+ parent_id
+ );
+ }
+ }
+
+ protected void handle_written_expr_predicates
+ (
+ final IDs local_id,
+ final org.w3c.dom.Node expr_node
+ )
+ throws XPathExpressionException
+ {
+ final List<IDs> elements;
+ final StringBuilder structure;
+ final int elements_count;
+
+ elements = new ArrayList<IDs>();
+ structure = new StringBuilder();
+
+ Expressions.process(elements, structure, expr_node);
+
+ Predicates.add_entry
+ (
+ output,
+ "is_written_structure",
+ local_id,
+ Strings.get_id_from_string
+ (
+ structure.toString()
+ )
+ );
+
+ elements_count = elements.size();
+
+ for (int i = 0; i < elements_count; ++i)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "is_written_element",
+ local_id,
+ Strings.get_id_from_string(Integer.toString(i)),
+ elements.get(i)
+ );
+
+ Predicates.add_entry
+ (
+ "is_accessed_by",
+ elements.get(i),
+ parent_id
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Port.java b/src/ghdl2hastabel/vhdl/Port.java
new file mode 100644
index 0000000..f1a30e6
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Port.java
@@ -0,0 +1,365 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Port extends ParsableXML
+{
+ public Port
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "port");
+
+ /** Parent **************************************************************/
+ handle_link_to_entity(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_identifier(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_disconnect_flag(local_id);
+ handle_predicate_has_class(local_id);
+ handle_predicate_is_ref(local_id);
+ handle_predicate_has_active_flag(local_id);
+ handle_predicate_has_identifier_list(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_has_after_drivers_flag(local_id);
+ handle_predicate_has_use_flag(local_id);
+ handle_predicate_has_open_flag(local_id);
+ handle_predicate_has_guarded_signal_flag(local_id);
+
+ handle_predicate_has_mode(local_id);
+
+ /** Children ************************************************************/
+ handle_child_waveform(local_id);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_entity
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("is_port_of", local_id, parent_id);
+ }
+
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_identifier
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "identifier",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "identifier")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_disconnect_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_disconnect_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_disconnect_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_class
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_class"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_class", local_id);
+ }
+ }
+
+ private void handle_predicate_is_ref
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_ref"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_ref", local_id);
+ }
+ }
+
+ private void handle_predicate_has_active_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_active_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_active_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_identifier_list
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_identifier_list"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_identifier_list", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "visible_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_after_drivers_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "after_drivers_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_after_drivers_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_use_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "use_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_use_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_open_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "open_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_open_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_guarded_signal_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "guarded_signal_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_guarded_signal_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_mode
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_mode"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry
+ (
+ "has_mode",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "mode"
+ )
+ )
+ );
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_waveform
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry
+ (
+ "is_waveform_of",
+ Waveforms.get_associated_waveform_id
+ (
+ local_id
+ ),
+ local_id
+ );
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Process.java b/src/ghdl2hastabel/vhdl/Process.java
new file mode 100644
index 0000000..9f1a5f4
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Process.java
@@ -0,0 +1,451 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Process extends ParsableXML
+{
+ private static final XPathExpression XPE_FIND_SL_ELEMENTS;
+ private static final XPathExpression XPE_FIND_START_NODE;
+
+ static
+ {
+ XPE_FIND_SL_ELEMENTS =
+ XMLManager.compile_or_die
+ (
+ "(./sensitivity_list/el/named_entity | ./sensitivity_list/el[@ref])"
+ );
+
+ XPE_FIND_START_NODE =
+ XMLManager.compile_or_die
+ (
+ "./sequential_statement_chain"
+ );
+ }
+
+ public Process
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "process");
+
+ /** Parent **************************************************************/
+ handle_link_to_architecture(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_label(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_seen_flag(local_id);
+ handle_predicate_end_has_postponed(local_id);
+ handle_predicate_is_ref(local_id);
+ handle_predicate_has_passive_flag(local_id);
+ handle_predicate_has_postponed_flag(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_is_within_flag(local_id);
+ handle_predicate_has_label(local_id);
+ handle_predicate_has_is(local_id);
+ handle_predicate_end_has_reserved_id(local_id);
+ handle_predicate_end_has_identifier(local_id);
+
+ handle_predicate_is_explicit_process(local_id);
+ handle_predicate_is_in_sensitivity_list(local_id);
+
+ /** Children ************************************************************/
+ handle_child_node(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_architecture
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("belongs_to_architecture", local_id, parent_id);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "label",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "label")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_seen_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "seen_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_seen_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_postponed
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_postponed"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_postponed", local_id);
+ }
+ }
+
+ private void handle_predicate_is_ref
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_ref"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_ref", local_id);
+ }
+ }
+
+ private void handle_predicate_has_passive_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "passive_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_passive_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_postponed_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "postponed_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_postponed_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "visible_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_is_within_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_within_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_within_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_label
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_label"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_label", local_id);
+ }
+ }
+
+ private void handle_predicate_has_is
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_is"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_is", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_reserved_id
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_reserved_id"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_reserved_id", local_id);
+ }
+ }
+
+ private void handle_predicate_end_has_identifier
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "end_has_identifier"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("end_has_identifier", local_id);
+ }
+ }
+
+ private void handle_predicate_is_explicit_process
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_ref"
+ ).equals("false")
+ )
+ {
+ Predicates.add_entry("is_explicit_process", local_id);
+ }
+ }
+
+ private void handle_predicate_is_in_sensitivity_list
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final NodeList items;
+ final int items_count;
+
+ items =
+ (NodeList) XPE_FIND_SL_ELEMENTS.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ items_count = items.getLength();
+
+ for (int i = 0; i < items_count; ++i)
+ {
+ Predicates.add_entry
+ (
+ "is_in_sensitivity_list",
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute
+ (
+ items.item(i),
+ "ref"
+ ),
+ null
+ )
+ ),
+ local_id
+ );
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_node
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final Node start_node;
+
+ start_node =
+ (Node) XPE_FIND_START_NODE.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ waiting_list.push
+ (
+ new SSCNode
+ (
+ OutputFile.new_output_file
+ (
+ "cfg_" /* TODO: Prefix as parameter? */
+ + Integer.toString(local_id.get_value())
+ + ".mod" /* TODO: Suffix as parameter? */
+ ),
+ local_id,
+ start_node,
+ null, /* There is nothing before this sequence. */
+ null, /* There is nothing after this sequence. */
+ 0, /* Depth starts at zero. */
+ new String[0] /* No attributes. */
+ )
+ );
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/SSASNode.java b/src/ghdl2hastabel/vhdl/SSASNode.java
new file mode 100644
index 0000000..f5571a8
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/SSASNode.java
@@ -0,0 +1,292 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Depths;
+import ghdl2hastabel.Main;
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+/* Simple Signal Assignment Statement Node */
+public class SSASNode extends ghdl2hastabel.vhdl.Node
+{
+ private static final XPathExpression XPE_FIND_TARGET;
+ private static final XPathExpression XPE_FIND_SOURCES;
+ private static final XPathExpression XPE_FIND_PREFIXED_NE;
+ private static final XPathExpression XPE_FIND_NE;
+
+ static
+ {
+ XPE_FIND_TARGET = XMLManager.compile_or_die("./target");
+
+ XPE_FIND_SOURCES =
+ XMLManager.compile_or_die
+ (
+ "./waveform_chain/el/we_value"/* //named_entity" */
+ );
+
+ XPE_FIND_PREFIXED_NE = XMLManager.compile_or_die("./prefix/named_entity");
+ XPE_FIND_NE = XMLManager.compile_or_die("./named_entity");
+ }
+
+ public SSASNode
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final Node xml_node,
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super
+ (
+ output,
+ parent_id,
+ xml_node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(output, xml_id, "node");
+
+ /** Functions ***********************************************************/
+ handle_function_label(local_id);
+ handle_function_kind(local_id);
+ handle_function_depth(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_option(local_id);
+ handle_predicate_expr_reads(local_id);
+ handle_predicate_expr_writes(local_id);
+
+ /** Children ************************************************************/
+ handle_next_node(local_id);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "label",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "label")
+ )
+ );
+ }
+
+ private void handle_function_kind
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "kind",
+ local_id,
+ Strings.get_id_from_string("signal_assignement")
+ );
+ }
+
+ private void handle_function_depth
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "depth",
+ local_id,
+ Depths.get_id_from_depth(new Integer(depth))
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_option
+ (
+ final IDs local_id
+ )
+ {
+ for (final String s: attributes)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "has_option",
+ local_id,
+ Strings.get_id_from_string(s)
+ );
+ }
+ }
+
+ private void handle_predicate_expr_reads
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final Node sources;
+
+ sources =
+ (Node) XPE_FIND_SOURCES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ handle_read_expr_predicates(local_id, sources);
+ }
+
+ private void handle_predicate_expr_writes
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final IDs target_id;
+ Node target;
+
+ target =
+ (Node) XPE_FIND_TARGET.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ /* Oddly enough, we can get a target as a ref... */
+ /* Let's get the real source! */
+ while (target.getNodeName().equals("target"))
+ {
+ final XPathExpression xpe_find_source;
+
+ if (XMLManager.get_attribute(target, "kind").equals("indexed_name"))
+ {
+ target =
+ (Node) XPE_FIND_PREFIXED_NE.evaluate
+ (
+ target,
+ XPathConstants.NODE
+ );
+ }
+ else
+ {
+ target =
+ (Node) XPE_FIND_NE.evaluate
+ (
+ target,
+ XPathConstants.NODE
+ );
+ }
+
+ /* XXX "or_die" might be a bit abusive here. */
+ xpe_find_source =
+ XMLManager.compile_or_die
+ (
+ ".//*[@id=\""
+ + XMLManager.get_attribute(target, "ref")
+ + "\"]"
+ );
+
+ target =
+ (Node) xpe_find_source.evaluate
+ (
+ Main.get_xml_root(),
+ XPathConstants.NODE
+ );
+ }
+
+ target_id =
+ Waveforms.get_associated_waveform_id
+ (
+ IDs.get_id_from_xml_id
+ (
+ XMLManager.get_attribute(target, "id"),
+ (String) null
+ )
+ );
+
+ Predicates.add_entry
+ (
+ output,
+ "expr_writes",
+ local_id,
+ target_id
+ );
+
+ Predicates.add_entry
+ (
+ "is_accessed_by",
+ target_id,
+ parent_id
+ );
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_next_node
+ (
+ final IDs local_id
+ )
+ {
+ if (next_node == (IDs) null)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "is_terminal",
+ local_id
+ );
+ }
+ else
+ {
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ local_id,
+ next_node
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/SSCNode.java b/src/ghdl2hastabel/vhdl/SSCNode.java
new file mode 100644
index 0000000..77b151c
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/SSCNode.java
@@ -0,0 +1,234 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+/* Sequential Statement Chain Node */
+/* Not actually a node in the resulting model, though. */
+public class SSCNode extends ghdl2hastabel.vhdl.Node
+{
+ private static final XPathExpression XPE_FIND_SUB_NODES;
+ private final IDs prev_node;
+
+ static
+ {
+ XPE_FIND_SUB_NODES = XMLManager.compile_or_die("./el");
+ }
+
+ public SSCNode
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final Node xml_node,
+ final IDs prev_node, /* can't simply forward ref to SSC */
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super
+ (
+ output,
+ parent_id,
+ xml_node,
+ next_node,
+ depth,
+ attributes
+ );
+
+ this.prev_node = prev_node; /* null when first node of the process */
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final NodeList sub_nodes;
+ final int intermediary_nodes_count;
+ int i;
+
+ /* Find all the nodes, in order, in this instruction chain */
+ sub_nodes =
+ (NodeList) XPE_FIND_SUB_NODES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODESET
+ );
+
+ /* Don't handle the last node in the 'for' loop, see below. */
+ intermediary_nodes_count = (sub_nodes.getLength() - 1);
+
+ for (i = 0; i < intermediary_nodes_count; ++i)
+ {
+ /* Prepare the parsing of all those nodes throufh the waiting list.
+ * To do so, each node needs to be informed of the ID of the node that
+ * follows it.
+ */
+ final IDs next_seq_node;
+
+ /* Get the ID for the next node in the sequence */
+ next_seq_node =
+ IDs.get_id_from_xml_id
+ (
+ output,
+ XMLManager.get_attribute
+ (
+ sub_nodes.item(i + 1),
+ "id"
+ ),
+ "node"
+ );
+
+ /*
+ * Add to the waiting list, 'i' indicates if the attributes inherited
+ * by the instruction sequence node should be passed along (it's only
+ * the case if i == 0).
+ */
+ waiting_list.push(get_vhdl_node(sub_nodes.item(i), next_seq_node, i));
+ }
+
+ /*
+ * The last node of the sequence takes the node following the sequence
+ * as 'next_node', so it's handled separatly.
+ */
+ waiting_list.push(get_vhdl_node(sub_nodes.item(i), next_node, i));
+
+ /* Handle the connection of the first node to the previous node. */
+ handle_backward_connection(sub_nodes.item(0));
+ }
+
+ private ParsableXML get_vhdl_node
+ (
+ final Node node,
+ final IDs next_node,
+ final int i
+ )
+ {
+ final String node_kind;
+ final String[] attributes;
+
+ node_kind = XMLManager.get_attribute(node, "kind");
+
+ if (i == 0)
+ {
+ /* Attributes are only inherited by the first node */
+ attributes = this.attributes;
+ }
+ else
+ {
+ attributes = new String[0];
+ }
+
+ if (node_kind.equals("if_statement"))
+ {
+ return
+ new ISNode
+ (
+ output,
+ parent_id,
+ node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+ else if (node_kind.equals("simple_signal_assignment_statement"))
+ {
+ return
+ new SSASNode
+ (
+ output,
+ parent_id,
+ node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+ else if (node_kind.equals("case_statement"))
+ {
+ return
+ new CSNode
+ (
+ output,
+ parent_id,
+ node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+
+ System.err.println
+ (
+ "[E] Unimplemented instruction kind \""
+ + node_kind
+ + "\" found in Sequential Statement Chain."
+ );
+
+ System.exit(-1);
+
+ return null;
+ }
+
+ private void handle_backward_connection
+ (
+ final Node first_node
+ )
+ {
+ final IDs first_node_id;
+
+ first_node_id =
+ IDs.get_id_from_xml_id
+ (
+ output,
+ XMLManager.get_attribute
+ (
+ first_node,
+ "id"
+ ),
+ "node"
+ );
+
+ if (prev_node == null)
+ {
+ /* First node of the process */
+ Predicates.add_entry
+ (
+ output,
+ "is_start_node",
+ first_node_id,
+ parent_id
+ );
+ }
+ else
+ {
+ /*
+ * Not the first node, so have the previous node connect to this one
+ * (which is the first of this instruction set).
+ */
+ Predicates.add_entry
+ (
+ output,
+ "node_connect",
+ prev_node,
+ first_node_id
+ );
+ }
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/Signal.java b/src/ghdl2hastabel/vhdl/Signal.java
new file mode 100644
index 0000000..6812529
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/Signal.java
@@ -0,0 +1,317 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Waveforms;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+public class Signal extends ParsableXML
+{
+ public Signal
+ (
+ final IDs parent_id,
+ final Node xml_node
+ )
+ {
+ super(parent_id, xml_node);
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(xml_id, "signal");
+
+ /** Parent **************************************************************/
+ handle_link_to_architecture(local_id);
+
+ /** Functions ***********************************************************/
+ handle_function_line(local_id);
+ handle_function_column(local_id);
+ handle_function_identifier(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_disconnect_flag(local_id);
+ handle_predicate_is_ref(local_id);
+ handle_predicate_has_active_flag(local_id);
+ handle_predicate_has_identifier_list(local_id);
+ handle_predicate_has_visible_flag(local_id);
+ handle_predicate_has_after_drivers_flag(local_id);
+ handle_predicate_has_use_flag(local_id);
+ handle_predicate_has_guarded_signal_flag(local_id);
+
+ handle_predicate_is_of_kind(local_id);
+
+ /** Children ************************************************************/
+ handle_child_waveform(local_id);
+ }
+
+ /***************************************************************************/
+ /** Parents ****************************************************************/
+ /***************************************************************************/
+ private void handle_link_to_architecture
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry("belongs_to_architecture", local_id, parent_id);
+ }
+
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_line
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "line",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "line")
+ )
+ );
+ }
+
+ private void handle_function_column
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "column",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "col")
+ )
+ );
+ }
+
+ private void handle_function_identifier
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ "identifier",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute(xml_node, "identifier")
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_disconnect_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_disconnect_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_disconnect_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_is_ref
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "is_ref"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("is_ref", local_id);
+ }
+ }
+
+ private void handle_predicate_has_active_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_active_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_active_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_identifier_list
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "has_identifier_list"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_identifier_list", local_id);
+ }
+ }
+
+ private void handle_predicate_has_visible_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "visible_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_visible_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_after_drivers_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "after_drivers_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_after_drivers_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_use_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "use_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_use_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_has_guarded_signal_flag
+ (
+ final IDs local_id
+ )
+ {
+ if
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "guarded_signal_flag"
+ ).equals("true")
+ )
+ {
+ Predicates.add_entry("has_guarded_signal_flag", local_id);
+ }
+ }
+
+ private void handle_predicate_is_of_kind
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry
+ (
+ "is_of_kind",
+ local_id,
+ Strings.get_id_from_string
+ (
+ XMLManager.get_attribute
+ (
+ xml_node,
+ "signal_kind"
+ )
+ )
+ );
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+ private void handle_child_waveform
+ (
+ final IDs local_id
+ )
+ {
+ Predicates.add_entry
+ (
+ "is_waveform_of",
+ Waveforms.get_associated_waveform_id
+ (
+ local_id
+ ),
+ local_id
+ );
+ }
+}
diff --git a/src/ghdl2hastabel/vhdl/WNode.java b/src/ghdl2hastabel/vhdl/WNode.java
new file mode 100644
index 0000000..cc3864a
--- /dev/null
+++ b/src/ghdl2hastabel/vhdl/WNode.java
@@ -0,0 +1,211 @@
+package ghdl2hastabel.vhdl;
+
+import ghdl2hastabel.Depths;
+import ghdl2hastabel.OutputFile;
+import ghdl2hastabel.Strings;
+import ghdl2hastabel.Functions;
+import ghdl2hastabel.Predicates;
+import ghdl2hastabel.ParsableXML;
+import ghdl2hastabel.XMLManager;
+import ghdl2hastabel.IDs;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import java.util.Stack;
+
+/* When Node */
+public class WNode extends ghdl2hastabel.vhdl.Node
+{
+ private static final XPathExpression XPE_FIND_SOURCES;
+ private static final XPathExpression XPE_FIND_BODY;
+
+ static
+ {
+ XPE_FIND_SOURCES =
+ XMLManager.compile_or_die
+ (
+ "./choice_expression" /* //named_entity" */
+ );
+
+ XPE_FIND_BODY =
+ XMLManager.compile_or_die
+ (
+ "./associated_chain"
+ );
+ }
+
+ public WNode
+ (
+ final OutputFile output,
+ final IDs parent_id,
+ final Node xml_node,
+ final IDs next_node,
+ final int depth,
+ final String[] attributes
+ )
+ {
+ super
+ (
+ output,
+ parent_id,
+ xml_node,
+ next_node,
+ depth,
+ attributes
+ );
+ }
+
+ @Override
+ public void parse
+ (
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final String xml_id;
+ final IDs local_id;
+
+ xml_id = XMLManager.get_attribute(xml_node, "id");
+
+ local_id = IDs.get_id_from_xml_id(output, xml_id, "node");
+
+ /** Functions ***********************************************************/
+ handle_function_label(local_id);
+ handle_function_kind(local_id);
+ handle_function_depth(local_id);
+
+ /** Predicates **********************************************************/
+ handle_predicate_has_option(local_id);
+ handle_predicate_expr_reads(local_id);
+
+ /** Children ************************************************************/
+ handle_body(local_id, waiting_list);
+ }
+
+ /***************************************************************************/
+ /** Functions **************************************************************/
+ /***************************************************************************/
+ private void handle_function_label
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "label",
+ local_id,
+ Strings.get_id_from_string("")
+ );
+ }
+
+ private void handle_function_kind
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "kind",
+ local_id,
+ Strings.get_id_from_string("when")
+ );
+ }
+
+ private void handle_function_depth
+ (
+ final IDs local_id
+ )
+ {
+ Functions.add_entry
+ (
+ output,
+ "depth",
+ local_id,
+ Depths.get_id_from_depth(new Integer(depth))
+ );
+ }
+
+ /***************************************************************************/
+ /** Predicates *************************************************************/
+ /***************************************************************************/
+ private void handle_predicate_has_option
+ (
+ final IDs local_id
+ )
+ {
+ for (final String s: attributes)
+ {
+ Predicates.add_entry
+ (
+ output,
+ "has_option",
+ local_id,
+ Strings.get_id_from_string(s)
+ );
+ }
+ }
+
+ private void handle_predicate_expr_reads
+ (
+ final IDs local_id
+ )
+ throws XPathExpressionException
+ {
+ final Node sources;
+
+ sources =
+ (Node) XPE_FIND_SOURCES.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ if (sources != (Node) null)
+ {
+ /* Not "others" */
+ handle_read_expr_predicates(local_id, sources);
+ }
+ }
+
+ /***************************************************************************/
+ /** Children ***************************************************************/
+ /***************************************************************************/
+
+ private void handle_body
+ (
+ final IDs local_id,
+ final Stack<ParsableXML> waiting_list
+ )
+ throws XPathExpressionException
+ {
+ final Node body;
+
+ body =
+ (Node) XPE_FIND_BODY.evaluate
+ (
+ xml_node,
+ XPathConstants.NODE
+ );
+
+ waiting_list.push
+ (
+ new SSCNode
+ (
+ output,
+ parent_id,
+ body,
+ local_id,
+ next_node,
+ (depth + 1),
+ new String[] {"COND_WAS_TRUE"}
+ )
+ );
+ }
+}