systemverilog-plugin: handle identifiers as list op arguments

Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index 4b5ced1..1de8a5a 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -37,7 +37,8 @@
 enum AstNodeTypeExtended {
     AST_DOT = ::Yosys::AST::AST_BIND + 1, // here we always want to point to the last element of yosys' AstNodeType
     AST_BREAK,
-    AST_CONTINUE
+    AST_CONTINUE,
+    AST_LOW_HIGH_BOUND
 };
 }
 } // namespace AST
@@ -959,6 +960,34 @@
     for (size_t i = 0; i < current_node->children.size(); i++) {
         simplify(current_node->children[i], current_node);
     }
+    if (current_node->type == static_cast<AST::AstNodeType>(AST::Extended::AST_LOW_HIGH_BOUND)) {
+        log_assert(current_node->children.size() == 2);
+        while (current_node->children[0]->simplify(true, false, false, 1, -1, false, false)) {
+        };
+        while (current_node->children[1]->simplify(true, false, false, 1, -1, false, false)) {
+        };
+        log_assert(current_node->children[0]->type == AST::AST_CONSTANT);
+        log_assert(current_node->children[1]->type == AST::AST_CONSTANT);
+        const int low = current_node->children[0]->integer;
+        const int high = current_node->children[1]->integer;
+        int range = current_node->children[0]->range_left;
+        while (!current_node->children.empty()) {
+            delete current_node->children.back();
+            current_node->children.pop_back();
+        }
+        // According to standard:
+        // If the bound to the left of the colon is greater than the
+        // bound to the right, the range is empty and contains no values.
+        for (int i = low; i >= low && i <= high; i++) {
+            // TODO(krak): what should be correct constant range if we don't have
+            // information about range?
+            if (range == -1) {
+                range = 64;
+            }
+            parent_node->children.push_back(AST::AstNode::mkconst_int(i, false, range));
+        }
+        return;
+    }
     switch (current_node->type) {
     case AST::AST_TYPEDEF:
     case AST::AST_ENUM:
@@ -1028,6 +1057,14 @@
         if (current_node->str == "$display" || current_node->str == "$write")
             simplify_format_string(current_node);
         break;
+    case AST::AST_COND:
+    case AST::AST_CONDX:
+    case AST::AST_CONDZ:
+        if (!current_node->children.empty() && current_node->children[0]->type == static_cast<AST::AstNodeType>(AST::Extended::AST_LOW_HIGH_BOUND)) {
+            delete current_node->children[0];
+            current_node->children.erase(current_node->children.begin());
+        }
+        break;
     default:
         break;
     }
@@ -3501,25 +3538,10 @@
             // a, b, c ... -> multiple vpiListOp with single item
             // [a : b] -> single vpiListOp with 2 items
             if (current_node->children.size() == 2) {
-                // TODO(krak): we should actually simplify this nodes first,
-                // but that would require to delay this to later.
-                // For now check that they are constants.
-                log_assert(current_node->children[0]->type == AST::AST_CONSTANT);
-                log_assert(current_node->children[1]->type == AST::AST_CONSTANT);
-                const int low = current_node->children[0]->integer;
-                const int high = current_node->children[1]->integer;
-                // TODO(krak): get proper width of constant
-                log_assert(current_node->children[0]->range_left == 31);
-                // According to standard:
-                // If the bound to the left of the colon is greater than the
-                // bound to the right, the range is empty and contains no values.
-                while (!current_node->children.empty()) {
-                    delete current_node->children.back();
-                    current_node->children.pop_back();
-                }
-                for (int i = low; i >= low && i <= high; i++) {
-                    current_node->children.push_back(AST::AstNode::mkconst_int(i, false, 32));
-                }
+                auto bound = new AST::AstNode(static_cast<AST::AstNodeType>(AST::Extended::AST_LOW_HIGH_BOUND));
+                bound->children = current_node->children;
+                current_node->children.erase(current_node->children.begin(), current_node->children.end());
+                current_node->children.push_back(bound);
             }
         } else {
             UhdmAst uhdm_ast(this, shared, indent + "  ");