/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *  Copyright (C) 2018  Ruben Undheim <ruben.undheim@gmail.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  ---
 *
 *  This is the AST frontend library.
 *
 *  The AST frontend library is not a frontend on it's own but provides a
 *  generic abstract syntax tree (AST) abstraction for HDL code and can be
 *  used by HDL frontends. See "ast.h" for an overview of the API and the
 *  Verilog frontend for an usage example.
 *
 */

#include "kernel/yosys.h"
#include "libs/sha1/sha1.h"
#include "ast.h"

YOSYS_NAMESPACE_BEGIN

using namespace AST;
using namespace AST_INTERNAL;

// instantiate global variables (public API)
namespace AST {
	std::string current_filename;
	void (*set_line_num)(int) = NULL;
	int (*get_line_num)() = NULL;
}

// instantiate global variables (private API)
namespace AST_INTERNAL {
	bool flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog, flag_dump_rtlil, flag_nolatches, flag_nomeminit;
	bool flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_autowire;
	AstNode *current_ast, *current_ast_mod;
	std::map<std::string, AstNode*> current_scope;
	const dict<RTLIL::SigBit, RTLIL::SigBit> *genRTLIL_subst_ptr = NULL;
	RTLIL::SigSpec ignoreThisSignalsInInitial;
	AstNode *current_always, *current_top_block, *current_block, *current_block_child;
	AstModule *current_module;
	bool current_always_clocked;
}

// convert node types to string
std::string AST::type2str(AstNodeType type)
{
	switch (type)
	{
#define X(_item) case _item: return #_item;
	X(AST_NONE)
	X(AST_DESIGN)
	X(AST_MODULE)
	X(AST_TASK)
	X(AST_FUNCTION)
	X(AST_DPI_FUNCTION)
	X(AST_WIRE)
	X(AST_MEMORY)
	X(AST_AUTOWIRE)
	X(AST_PARAMETER)
	X(AST_LOCALPARAM)
	X(AST_DEFPARAM)
	X(AST_PARASET)
	X(AST_ARGUMENT)
	X(AST_RANGE)
	X(AST_MULTIRANGE)
	X(AST_CONSTANT)
	X(AST_REALVALUE)
	X(AST_CELLTYPE)
	X(AST_IDENTIFIER)
	X(AST_PREFIX)
	X(AST_ASSERT)
	X(AST_ASSUME)
	X(AST_LIVE)
	X(AST_FAIR)
	X(AST_COVER)
	X(AST_FCALL)
	X(AST_TO_BITS)
	X(AST_TO_SIGNED)
	X(AST_TO_UNSIGNED)
	X(AST_CONCAT)
	X(AST_REPLICATE)
	X(AST_BIT_NOT)
	X(AST_BIT_AND)
	X(AST_BIT_OR)
	X(AST_BIT_XOR)
	X(AST_BIT_XNOR)
	X(AST_REDUCE_AND)
	X(AST_REDUCE_OR)
	X(AST_REDUCE_XOR)
	X(AST_REDUCE_XNOR)
	X(AST_REDUCE_BOOL)
	X(AST_SHIFT_LEFT)
	X(AST_SHIFT_RIGHT)
	X(AST_SHIFT_SLEFT)
	X(AST_SHIFT_SRIGHT)
	X(AST_LT)
	X(AST_LE)
	X(AST_EQ)
	X(AST_NE)
	X(AST_EQX)
	X(AST_NEX)
	X(AST_GE)
	X(AST_GT)
	X(AST_ADD)
	X(AST_SUB)
	X(AST_MUL)
	X(AST_DIV)
	X(AST_MOD)
	X(AST_POW)
	X(AST_POS)
	X(AST_NEG)
	X(AST_LOGIC_AND)
	X(AST_LOGIC_OR)
	X(AST_LOGIC_NOT)
	X(AST_TERNARY)
	X(AST_MEMRD)
	X(AST_MEMWR)
	X(AST_MEMINIT)
	X(AST_TCALL)
	X(AST_ASSIGN)
	X(AST_CELL)
	X(AST_PRIMITIVE)
	X(AST_CELLARRAY)
	X(AST_ALWAYS)
	X(AST_INITIAL)
	X(AST_BLOCK)
	X(AST_ASSIGN_EQ)
	X(AST_ASSIGN_LE)
	X(AST_CASE)
	X(AST_COND)
	X(AST_CONDX)
	X(AST_CONDZ)
	X(AST_DEFAULT)
	X(AST_FOR)
	X(AST_WHILE)
	X(AST_REPEAT)
	X(AST_GENVAR)
	X(AST_GENFOR)
	X(AST_GENIF)
	X(AST_GENCASE)
	X(AST_GENBLOCK)
	X(AST_POSEDGE)
	X(AST_NEGEDGE)
	X(AST_EDGE)
	X(AST_PACKAGE)
#undef X
	default:
		log_abort();
	}
}

// check if attribute exists and has non-zero value
bool AstNode::get_bool_attribute(RTLIL::IdString id)
{
	if (attributes.count(id) == 0)
		return false;

	AstNode *attr = attributes.at(id);
	if (attr->type != AST_CONSTANT)
		log_file_error(attr->filename, attr->linenum, "Attribute `%s' with non-constant value!\n", id.c_str());

	return attr->integer != 0;
}

// create new node (AstNode constructor)
// (the optional child arguments make it easier to create AST trees)
AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *child3)
{
	static unsigned int hashidx_count = 123456789;
	hashidx_count = mkhash_xorshift(hashidx_count);
	hashidx_ = hashidx_count;

	this->type = type;
	filename = current_filename;
	linenum = get_line_num();
	is_input = false;
	is_output = false;
	is_reg = false;
	is_logic = false;
	is_signed = false;
	is_string = false;
	was_checked = false;
	range_valid = false;
	range_swapped = false;
	port_id = 0;
	range_left = -1;
	range_right = 0;
	integer = 0;
	realvalue = 0;
	id2ast = NULL;
	basic_prep = false;

	if (child1)
		children.push_back(child1);
	if (child2)
		children.push_back(child2);
	if (child3)
		children.push_back(child3);
}

// create a (deep recursive) copy of a node
AstNode *AstNode::clone() const
{
	AstNode *that = new AstNode;
	*that = *this;
	for (auto &it : that->children)
		it = it->clone();
	for (auto &it : that->attributes)
		it.second = it.second->clone();
	return that;
}

// create a (deep recursive) copy of a node use 'other' as target root node
void AstNode::cloneInto(AstNode *other) const
{
	AstNode *tmp = clone();
	other->delete_children();
	*other = *tmp;
	tmp->children.clear();
	tmp->attributes.clear();
	delete tmp;
}

// delete all children in this node
void AstNode::delete_children()
{
	for (auto &it : children)
		delete it;
	children.clear();

	for (auto &it : attributes)
		delete it.second;
	attributes.clear();
}

// AstNode destructor
AstNode::~AstNode()
{
	delete_children();
}

// create a nice text representation of the node
// (traverse tree by recursion, use 'other' pointer for diffing two AST trees)
void AstNode::dumpAst(FILE *f, std::string indent) const
{
	if (f == NULL) {
		for (auto f : log_files)
			dumpAst(f, indent);
		return;
	}

	std::string type_name = type2str(type);
	fprintf(f, "%s%s <%s:%d>", indent.c_str(), type_name.c_str(), filename.c_str(), linenum);

	if (!flag_no_dump_ptr) {
		if (id2ast)
			fprintf(f, " [%p -> %p]", this, id2ast);
		else
			fprintf(f, " [%p]", this);
	}

	if (!str.empty())
		fprintf(f, " str='%s'", str.c_str());
	if (!bits.empty()) {
		fprintf(f, " bits='");
		for (size_t i = bits.size(); i > 0; i--)
			fprintf(f, "%c", bits[i-1] == RTLIL::S0 ? '0' :
					bits[i-1] == RTLIL::S1 ? '1' :
					bits[i-1] == RTLIL::Sx ? 'x' :
					bits[i-1] == RTLIL::Sz ? 'z' : '?');
		fprintf(f, "'(%d)", GetSize(bits));
	}
	if (is_input)
		fprintf(f, " input");
	if (is_output)
		fprintf(f, " output");
	if (is_logic)
		fprintf(f, " logic");
	if (is_reg) // this is an AST dump, not Verilog - if we see "logic reg" that's fine.
		fprintf(f, " reg");
	if (is_signed)
		fprintf(f, " signed");
	if (port_id > 0)
		fprintf(f, " port=%d", port_id);
	if (range_valid || range_left != -1 || range_right != 0)
		fprintf(f, " %srange=[%d:%d]%s", range_swapped ? "swapped_" : "", range_left, range_right, range_valid ? "" : "!");
	if (integer != 0)
		fprintf(f, " int=%u", (int)integer);
	if (realvalue != 0)
		fprintf(f, " real=%e", realvalue);
	if (!multirange_dimensions.empty()) {
		fprintf(f, " multirange=[");
		for (int v : multirange_dimensions)
			fprintf(f, " %d", v);
		fprintf(f, " ]");
	}
	fprintf(f, "\n");

	for (auto &it : attributes) {
		fprintf(f, "%s  ATTR %s:\n", indent.c_str(), it.first.c_str());
		it.second->dumpAst(f, indent + "    ");
	}

	for (size_t i = 0; i < children.size(); i++)
		children[i]->dumpAst(f, indent + "  ");

	fflush(f);
}

// helper function for AstNode::dumpVlog()
static std::string id2vl(std::string txt)
{
	if (txt.size() > 1 && txt[0] == '\\')
		txt = txt.substr(1);
	for (size_t i = 0; i < txt.size(); i++) {
		if ('A' <= txt[i] && txt[i] <= 'Z') continue;
		if ('a' <= txt[i] && txt[i] <= 'z') continue;
		if ('0' <= txt[i] && txt[i] <= '9') continue;
		if (txt[i] == '_') continue;
		txt = "\\" + txt + " ";
		break;
	}
	return txt;
}

// dump AST node as Verilog pseudo-code
void AstNode::dumpVlog(FILE *f, std::string indent) const
{
	bool first = true;
	std::string txt;
	std::vector<AstNode*> rem_children1, rem_children2;

	if (f == NULL) {
		for (auto f : log_files)
			dumpVlog(f, indent);
		return;
	}

	for (auto &it : attributes) {
		fprintf(f, "%s" "(* %s = ", indent.c_str(), id2vl(it.first.str()).c_str());
		it.second->dumpVlog(f, "");
		fprintf(f, " *)%s", indent.empty() ? "" : "\n");
	}

	switch (type)
	{
	case AST_MODULE:
		fprintf(f, "%s" "module %s(", indent.c_str(), id2vl(str).c_str());
		for (auto child : children)
			if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
				fprintf(f, "%s%s", first ? "" : ", ", id2vl(child->str).c_str());
				first = false;
			}
		fprintf(f, ");\n");

		for (auto child : children)
			if (child->type == AST_PARAMETER || child->type == AST_LOCALPARAM || child->type == AST_DEFPARAM)
				child->dumpVlog(f, indent + "  ");
			else
				rem_children1.push_back(child);

		for (auto child : rem_children1)
			if (child->type == AST_WIRE || child->type == AST_AUTOWIRE || child->type == AST_MEMORY)
				child->dumpVlog(f, indent + "  ");
			else
				rem_children2.push_back(child);
		rem_children1.clear();

		for (auto child : rem_children2)
			if (child->type == AST_TASK || child->type == AST_FUNCTION)
				child->dumpVlog(f, indent + "  ");
			else
				rem_children1.push_back(child);
		rem_children2.clear();

		for (auto child : rem_children1)
			child->dumpVlog(f, indent + "  ");
		rem_children1.clear();

		fprintf(f, "%s" "endmodule\n", indent.c_str());
		break;

	case AST_WIRE:
		if (is_input && is_output)
			fprintf(f, "%s" "inout", indent.c_str());
		else if (is_input)
			fprintf(f, "%s" "input", indent.c_str());
		else if (is_output)
			fprintf(f, "%s" "output", indent.c_str());
		else if (!is_reg)
			fprintf(f, "%s" "wire", indent.c_str());
		if (is_reg)
			fprintf(f, "%s" "reg", (is_input || is_output) ? " " : indent.c_str());
		if (is_signed)
			fprintf(f, " signed");
		for (auto child : children) {
			fprintf(f, " ");
			child->dumpVlog(f, "");
		}
		fprintf(f, " %s", id2vl(str).c_str());
		fprintf(f, ";\n");
		break;

	case AST_MEMORY:
		fprintf(f, "%s" "memory", indent.c_str());
		if (is_signed)
			fprintf(f, " signed");
		for (auto child : children) {
			fprintf(f, " ");
			child->dumpVlog(f, "");
			if (first)
				fprintf(f, " %s", id2vl(str).c_str());
			first = false;
		}
		fprintf(f, ";\n");
		break;

	case AST_RANGE:
		if (range_valid)
			fprintf(f, "[%d:%d]", range_left, range_right);
		else {
			for (auto child : children) {
				fprintf(f, "%c", first ? '[' : ':');
				child->dumpVlog(f, "");
				first = false;
			}
			fprintf(f, "]");
		}
		break;

	case AST_ALWAYS:
		fprintf(f, "%s" "always @", indent.c_str());
		for (auto child : children) {
			if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
				continue;
			fprintf(f, first ? "(" : ", ");
			child->dumpVlog(f, "");
			first = false;
		}
		fprintf(f, first ? "*\n" : ")\n");
		for (auto child : children) {
			if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
				child->dumpVlog(f, indent + "  ");
		}
		break;

	case AST_INITIAL:
		fprintf(f, "%s" "initial\n", indent.c_str());
		for (auto child : children) {
			if (child->type != AST_POSEDGE && child->type != AST_NEGEDGE && child->type != AST_EDGE)
				child->dumpVlog(f, indent + "  ");
		}
		break;

	case AST_POSEDGE:
	case AST_NEGEDGE:
	case AST_EDGE:
		if (type == AST_POSEDGE)
			fprintf(f, "posedge ");
		if (type == AST_NEGEDGE)
			fprintf(f, "negedge ");
		for (auto child : children)
			child->dumpVlog(f, "");
		break;

	case AST_IDENTIFIER:
		fprintf(f, "%s", id2vl(str).c_str());
		for (auto child : children)
			child->dumpVlog(f, "");
		break;

	case AST_CONSTANT:
		if (!str.empty())
			fprintf(f, "\"%s\"", str.c_str());
		else if (bits.size() == 32)
			fprintf(f, "%d", RTLIL::Const(bits).as_int());
		else
			fprintf(f, "%d'b %s", GetSize(bits), RTLIL::Const(bits).as_string().c_str());
		break;

	case AST_REALVALUE:
		fprintf(f, "%e", realvalue);
		break;

	case AST_BLOCK:
		if (children.size() == 1) {
			children[0]->dumpVlog(f, indent);
		} else {
			fprintf(f, "%s" "begin\n", indent.c_str());
			for (auto child : children)
				child->dumpVlog(f, indent + "  ");
			fprintf(f, "%s" "end\n", indent.c_str());
		}
		break;

	case AST_CASE:
		if (!children.empty() && children[0]->type == AST_CONDX)
			fprintf(f, "%s" "casex (", indent.c_str());
		else if (!children.empty() && children[0]->type == AST_CONDZ)
			fprintf(f, "%s" "casez (", indent.c_str());
		else
			fprintf(f, "%s" "case (", indent.c_str());
		children[0]->dumpVlog(f, "");
		fprintf(f, ")\n");
		for (size_t i = 1; i < children.size(); i++) {
			AstNode *child = children[i];
			child->dumpVlog(f, indent + "  ");
		}
		fprintf(f, "%s" "endcase\n", indent.c_str());
		break;

	case AST_COND:
	case AST_CONDX:
	case AST_CONDZ:
		for (auto child : children) {
			if (child->type == AST_BLOCK) {
				fprintf(f, ":\n");
				child->dumpVlog(f, indent + "  ");
				first = true;
			} else {
				fprintf(f, "%s", first ? indent.c_str() : ", ");
				if (child->type == AST_DEFAULT)
					fprintf(f, "default");
				else
					child->dumpVlog(f, "");
				first = false;
			}
		}
		break;

	case AST_ASSIGN:
		fprintf(f, "%sassign ", indent.c_str());
		children[0]->dumpVlog(f, "");
		fprintf(f, " = ");
		children[1]->dumpVlog(f, "");
		fprintf(f, ";\n");
		break;

	case AST_ASSIGN_EQ:
	case AST_ASSIGN_LE:
		fprintf(f, "%s", indent.c_str());
		children[0]->dumpVlog(f, "");
		fprintf(f, " %s ", type == AST_ASSIGN_EQ ? "=" : "<=");
		children[1]->dumpVlog(f, "");
		fprintf(f, ";\n");
		break;

	case AST_CONCAT:
		fprintf(f, "{");
		for (auto child : children) {
			if (!first)
				fprintf(f, ", ");
			child->dumpVlog(f, "");
			first = false;
		}
		fprintf(f, "}");
		break;

	case AST_REPLICATE:
		fprintf(f, "{");
		children[0]->dumpVlog(f, "");
		fprintf(f, "{");
		children[1]->dumpVlog(f, "");
		fprintf(f, "}}");
		break;

	if (0) { case AST_BIT_NOT:     txt = "~";  }
	if (0) { case AST_REDUCE_AND:  txt = "&";  }
	if (0) { case AST_REDUCE_OR:   txt = "|";  }
	if (0) { case AST_REDUCE_XOR:  txt = "^";  }
	if (0) { case AST_REDUCE_XNOR: txt = "~^"; }
	if (0) { case AST_REDUCE_BOOL: txt = "|";  }
	if (0) { case AST_POS:         txt = "+";  }
	if (0) { case AST_NEG:         txt = "-";  }
	if (0) { case AST_LOGIC_NOT:   txt = "!";  }
		fprintf(f, "%s(", txt.c_str());
		children[0]->dumpVlog(f, "");
		fprintf(f, ")");
		break;

	if (0) { case AST_BIT_AND:      txt = "&";   }
	if (0) { case AST_BIT_OR:       txt = "|";   }
	if (0) { case AST_BIT_XOR:      txt = "^";   }
	if (0) { case AST_BIT_XNOR:     txt = "~^";  }
	if (0) { case AST_SHIFT_LEFT:   txt = "<<";  }
	if (0) { case AST_SHIFT_RIGHT:  txt = ">>";  }
	if (0) { case AST_SHIFT_SLEFT:  txt = "<<<"; }
	if (0) { case AST_SHIFT_SRIGHT: txt = ">>>"; }
	if (0) { case AST_LT:           txt = "<";   }
	if (0) { case AST_LE:           txt = "<=";  }
	if (0) { case AST_EQ:           txt = "==";  }
	if (0) { case AST_NE:           txt = "!=";  }
	if (0) { case AST_EQX:          txt = "===";  }
	if (0) { case AST_NEX:          txt = "!==";  }
	if (0) { case AST_GE:           txt = ">=";  }
	if (0) { case AST_GT:           txt = ">";   }
	if (0) { case AST_ADD:          txt = "+";   }
	if (0) { case AST_SUB:          txt = "-";   }
	if (0) { case AST_MUL:          txt = "*";   }
	if (0) { case AST_DIV:          txt = "/";   }
	if (0) { case AST_MOD:          txt = "%";   }
	if (0) { case AST_POW:          txt = "**";  }
	if (0) { case AST_LOGIC_AND:    txt = "&&";  }
	if (0) { case AST_LOGIC_OR:     txt = "||";  }
		fprintf(f, "(");
		children[0]->dumpVlog(f, "");
		fprintf(f, ")%s(", txt.c_str());
		children[1]->dumpVlog(f, "");
		fprintf(f, ")");
		break;

	case AST_TERNARY:
		fprintf(f, "(");
		children[0]->dumpVlog(f, "");
		fprintf(f, ") ? (");
		children[1]->dumpVlog(f, "");
		fprintf(f, ") : (");
		children[2]->dumpVlog(f, "");
		fprintf(f, ")");
		break;

	default:
		std::string type_name = type2str(type);
		fprintf(f, "%s" "/** %s **/%s", indent.c_str(), type_name.c_str(), indent.empty() ? "" : "\n");
		// dumpAst(f, indent, NULL);
	}

	fflush(f);
}

// check if two AST nodes are identical
bool AstNode::operator==(const AstNode &other) const
{
	if (type != other.type)
		return false;
	if (children.size() != other.children.size())
		return false;
	if (str != other.str)
		return false;
	if (bits != other.bits)
		return false;
	if (is_input != other.is_input)
		return false;
	if (is_output != other.is_output)
		return false;
	if (is_logic != other.is_logic)
		return false;
	if (is_reg != other.is_reg)
		return false;
	if (is_signed != other.is_signed)
		return false;
	if (is_string != other.is_string)
		return false;
	if (range_valid != other.range_valid)
		return false;
	if (range_swapped != other.range_swapped)
		return false;
	if (port_id != other.port_id)
		return false;
	if (range_left != other.range_left)
		return false;
	if (range_right != other.range_right)
		return false;
	if (integer != other.integer)
		return false;
	for (size_t i = 0; i < children.size(); i++)
		if (*children[i] != *other.children[i])
			return false;
	return true;
}

// check if two AST nodes are not identical
bool AstNode::operator!=(const AstNode &other) const
{
	return !(*this == other);
}

// check if this AST contains the given node
bool AstNode::contains(const AstNode *other) const
{
	if (this == other)
		return true;
	for (auto child : children)
		if (child->contains(other))
			return true;
	return false;
}

// create an AST node for a constant (using a 32 bit int as value)
AstNode *AstNode::mkconst_int(uint32_t v, bool is_signed, int width)
{
	AstNode *node = new AstNode(AST_CONSTANT);
	node->integer = v;
	node->is_signed = is_signed;
	for (int i = 0; i < width; i++) {
		node->bits.push_back((v & 1) ? RTLIL::S1 : RTLIL::S0);
		v = v >> 1;
	}
	node->range_valid = true;
	node->range_left = width-1;
	node->range_right = 0;
	return node;
}

// create an AST node for a constant (using a bit vector as value)
AstNode *AstNode::mkconst_bits(const std::vector<RTLIL::State> &v, bool is_signed)
{
	AstNode *node = new AstNode(AST_CONSTANT);
	node->is_signed = is_signed;
	node->bits = v;
	for (size_t i = 0; i < 32; i++) {
		if (i < node->bits.size())
			node->integer |= (node->bits[i] == RTLIL::S1) << i;
		else if (is_signed && !node->bits.empty())
			node->integer |= (node->bits.back() == RTLIL::S1) << i;
	}
	node->range_valid = true;
	node->range_left = node->bits.size()-1;
	node->range_right = 0;
	return node;
}

// create an AST node for a constant (using a string in bit vector form as value)
AstNode *AstNode::mkconst_str(const std::vector<RTLIL::State> &v)
{
	AstNode *node = mkconst_str(RTLIL::Const(v).decode_string());
	while (GetSize(node->bits) < GetSize(v))
		node->bits.push_back(RTLIL::State::S0);
	log_assert(node->bits == v);
	return node;
}

// create an AST node for a constant (using a string as value)
AstNode *AstNode::mkconst_str(const std::string &str)
{
	std::vector<RTLIL::State> data;
	data.reserve(str.size() * 8);
	for (size_t i = 0; i < str.size(); i++) {
		unsigned char ch = str[str.size() - i - 1];
		for (int j = 0; j < 8; j++) {
			data.push_back((ch & 1) ? RTLIL::S1 : RTLIL::S0);
			ch = ch >> 1;
		}
	}
	AstNode *node = AstNode::mkconst_bits(data, false);
	node->is_string = true;
	node->str = str;
	return node;
}

bool AstNode::bits_only_01() const
{
	for (auto bit : bits)
		if (bit != RTLIL::S0 && bit != RTLIL::S1)
			return false;
	return true;
}

RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed)
{
	std::vector<RTLIL::State> bits = this->bits;
	if (width >= 0 && width < int(bits.size()))
		bits.resize(width);
	if (width >= 0 && width > int(bits.size())) {
		RTLIL::State extbit = RTLIL::State::S0;
		if (is_signed && !bits.empty())
			extbit = bits.back();
		while (width > int(bits.size()))
			bits.push_back(extbit);
	}
	return RTLIL::Const(bits);
}

RTLIL::Const AstNode::bitsAsConst(int width)
{
	return bitsAsConst(width, is_signed);
}

RTLIL::Const AstNode::asAttrConst()
{
	log_assert(type == AST_CONSTANT);

	RTLIL::Const val;
	val.bits = bits;

	if (is_string) {
		val.flags |= RTLIL::CONST_FLAG_STRING;
		log_assert(val.decode_string() == str);
	}

	return val;
}

RTLIL::Const AstNode::asParaConst()
{
	RTLIL::Const val = asAttrConst();
	if (is_signed)
		val.flags |= RTLIL::CONST_FLAG_SIGNED;
	return val;
}

bool AstNode::asBool() const
{
	log_assert(type == AST_CONSTANT);
	for (auto &bit : bits)
		if (bit == RTLIL::State::S1)
			return true;
	return false;
}

int AstNode::isConst() const
{
	if (type == AST_CONSTANT)
		return 1;
	if (type == AST_REALVALUE)
		return 2;
	return 0;
}

uint64_t AstNode::asInt(bool is_signed)
{
	if (type == AST_CONSTANT)
	{
		RTLIL::Const v = bitsAsConst(64, is_signed);
		uint64_t ret = 0;

		for (int i = 0; i < 64; i++)
			if (v.bits.at(i) == RTLIL::State::S1)
				ret |= uint64_t(1) << i;

		return ret;
	}

	if (type == AST_REALVALUE)
		return uint64_t(realvalue);

	log_abort();
}

double AstNode::asReal(bool is_signed)
{
	if (type == AST_CONSTANT)
	{
		RTLIL::Const val(bits);

		bool is_negative = is_signed && !val.bits.empty() && val.bits.back() == RTLIL::State::S1;
		if (is_negative)
			val = const_neg(val, val, false, false, val.bits.size());

		double v = 0;
		for (size_t i = 0; i < val.bits.size(); i++)
			// IEEE Std 1800-2012 Par 6.12.2: Individual bits that are x or z in
			// the net or the variable shall be treated as zero upon conversion.
			if (val.bits.at(i) == RTLIL::State::S1)
				v += exp2(i);
		if (is_negative)
			v *= -1;

		return v;
	}

	if (type == AST_REALVALUE)
		return realvalue;

	log_abort();
}

RTLIL::Const AstNode::realAsConst(int width)
{
	double v = round(realvalue);
	RTLIL::Const result;
#ifdef EMSCRIPTEN
	if (!isfinite(v)) {
#else
	if (!std::isfinite(v)) {
#endif
		result.bits = std::vector<RTLIL::State>(width, RTLIL::State::Sx);
	} else {
		bool is_negative = v < 0;
		if (is_negative)
			v *= -1;
		for (int i = 0; i < width; i++, v /= 2)
			result.bits.push_back((fmod(floor(v), 2) != 0) ? RTLIL::State::S1 : RTLIL::State::S0);
		if (is_negative)
			result = const_neg(result, result, false, false, result.bits.size());
	}
	return result;
}

// create a new AstModule from an AST_MODULE AST node
static AstModule* process_module(AstNode *ast, bool defer, AstNode *original_ast = NULL)
{
	log_assert(ast->type == AST_MODULE || ast->type == AST_INTERFACE);

	if (defer)
		log("Storing AST representation for module `%s'.\n", ast->str.c_str());
	else
		log("Generating RTLIL representation for module `%s'.\n", ast->str.c_str());

	current_module = new AstModule;
	current_module->ast = NULL;
	current_module->name = ast->str;
	current_module->attributes["\\src"] = stringf("%s:%d", ast->filename.c_str(), ast->linenum);
	current_module->set_bool_attribute("\\cells_not_processed");

	current_ast_mod = ast;
	AstNode *ast_before_simplify;
	if (original_ast != NULL)
		ast_before_simplify = original_ast;
	else
		ast_before_simplify = ast->clone();

	if (flag_dump_ast1) {
		log("Dumping Verilog AST before simplification:\n");
		ast->dumpAst(NULL, "    ");
		log("--- END OF AST DUMP ---\n");
	}

	if (!defer)
	{
		while (ast->simplify(!flag_noopt, false, false, 0, -1, false, false)) { }

		if (flag_dump_ast2) {
			log("Dumping Verilog AST after simplification:\n");
			ast->dumpAst(NULL, "    ");
			log("--- END OF AST DUMP ---\n");
		}

		if (flag_dump_vlog) {
			log("Dumping Verilog AST (as requested by dump_vlog option):\n");
			ast->dumpVlog(NULL, "    ");
			log("--- END OF AST DUMP ---\n");
		}

		if (flag_lib) {
			std::vector<AstNode*> new_children;
			for (auto child : ast->children) {
				if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
					new_children.push_back(child);
				} else if (child->type == AST_PARAMETER) {
					child->delete_children();
					child->children.push_back(AstNode::mkconst_int(0, false, 0));
					new_children.push_back(child);
				} else {
					delete child;
				}
			}
			ast->children.swap(new_children);
			ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
		}

		ignoreThisSignalsInInitial = RTLIL::SigSpec();

		for (auto &attr : ast->attributes) {
			if (attr.second->type != AST_CONSTANT)
				log_file_error(ast->filename, ast->linenum, "Attribute `%s' with non-constant value!\n", attr.first.c_str());
			current_module->attributes[attr.first] = attr.second->asAttrConst();
		}
		for (size_t i = 0; i < ast->children.size(); i++) {
			AstNode *node = ast->children[i];
			if (node->type == AST_WIRE || node->type == AST_MEMORY)
				node->genRTLIL();
		}
		for (size_t i = 0; i < ast->children.size(); i++) {
			AstNode *node = ast->children[i];
			if (node->type != AST_WIRE && node->type != AST_MEMORY && node->type != AST_INITIAL)
				node->genRTLIL();
		}

		ignoreThisSignalsInInitial.sort_and_unify();

		for (size_t i = 0; i < ast->children.size(); i++) {
			AstNode *node = ast->children[i];
			if (node->type == AST_INITIAL)
				node->genRTLIL();
		}

		ignoreThisSignalsInInitial = RTLIL::SigSpec();
	}

	if (ast->type == AST_INTERFACE)
		current_module->set_bool_attribute("\\is_interface");
	current_module->ast = ast_before_simplify;
	current_module->nolatches = flag_nolatches;
	current_module->nomeminit = flag_nomeminit;
	current_module->nomem2reg = flag_nomem2reg;
	current_module->mem2reg = flag_mem2reg;
	current_module->lib = flag_lib;
	current_module->noopt = flag_noopt;
	current_module->icells = flag_icells;
	current_module->autowire = flag_autowire;
	current_module->fixup_ports();

	if (flag_dump_rtlil) {
		log("Dumping generated RTLIL:\n");
		log_module(current_module);
		log("--- END OF RTLIL DUMP ---\n");
	}

	return current_module;
}

// create AstModule instances for all modules in the AST tree and add them to 'design'
void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool no_dump_ptr, bool dump_vlog, bool dump_rtlil,
		bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool nooverwrite, bool overwrite, bool defer, bool autowire)
{
	current_ast = ast;
	flag_dump_ast1 = dump_ast1;
	flag_dump_ast2 = dump_ast2;
	flag_no_dump_ptr = no_dump_ptr;
	flag_dump_vlog = dump_vlog;
	flag_dump_rtlil = dump_rtlil;
	flag_nolatches = nolatches;
	flag_nomeminit = nomeminit;
	flag_nomem2reg = nomem2reg;
	flag_mem2reg = mem2reg;
	flag_lib = lib;
	flag_noopt = noopt;
	flag_icells = icells;
	flag_autowire = autowire;

	log_assert(current_ast->type == AST_DESIGN);
	for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++)
	{
		if ((*it)->type == AST_MODULE || (*it)->type == AST_INTERFACE)
		{
			for (auto n : design->verilog_globals)
				(*it)->children.push_back(n->clone());

			for (auto n : design->verilog_packages){
				for (auto o : n->children) {
					AstNode *cloned_node = o->clone();
					cloned_node->str = n->str + std::string("::") + cloned_node->str.substr(1);
					(*it)->children.push_back(cloned_node);
				}
			}

			if (flag_icells && (*it)->str.substr(0, 2) == "\\$")
				(*it)->str = (*it)->str.substr(1);

			if (defer)
				(*it)->str = "$abstract" + (*it)->str;

			if (design->has((*it)->str)) {
				RTLIL::Module *existing_mod = design->module((*it)->str);
				if (!nooverwrite && !overwrite && !existing_mod->get_bool_attribute("\\blackbox")) {
					log_file_error((*it)->filename, (*it)->linenum, "Re-definition of module `%s'!\n", (*it)->str.c_str());
				} else if (nooverwrite) {
					log("Ignoring re-definition of module `%s' at %s:%d.\n",
							(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
					continue;
				} else {
					log("Replacing existing%s module `%s' at %s:%d.\n",
							existing_mod->get_bool_attribute("\\blackbox") ? " blackbox" : "",
							(*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
					design->remove(existing_mod);
				}
			}

			design->add(process_module(*it, defer));
		}
		else if ((*it)->type == AST_PACKAGE)
			design->verilog_packages.push_back((*it)->clone());
		else
			design->verilog_globals.push_back((*it)->clone());
	}
}

// AstModule destructor
AstModule::~AstModule()
{
	if (ast != NULL)
		delete ast;
}


// An interface port with modport is specified like this:
//    <interface_name>.<modport_name>
// This function splits the interface_name from the modport_name, and fails if it is not a valid combination
std::pair<std::string,std::string> AST::split_modport_from_type(std::string name_type)
{
	std::string interface_type = "";
	std::string interface_modport = "";
	size_t ndots = std::count(name_type.begin(), name_type.end(), '.');
	// Separate the interface instance name from any modports:
	if (ndots == 0) { // Does not have modport
		interface_type = name_type;
	}
	else {
		std::stringstream name_type_stream(name_type);
		std::string segment;
		std::vector<std::string> seglist;
		while(std::getline(name_type_stream, segment, '.')) {
			seglist.push_back(segment);
		}
		if (ndots == 1) { // Has modport
			interface_type = seglist[0];
			interface_modport = seglist[1];
		}
		else { // Erroneous port type
			log_error("More than two '.' in signal port type (%s)\n", name_type.c_str());
		}
	}
	return std::pair<std::string,std::string>(interface_type, interface_modport);

}

AstNode * AST::find_modport(AstNode *intf, std::string name)
{
	for (auto &ch : intf->children)
		if (ch->type == AST_MODPORT)
			if (ch->str == name) // Modport found
				return ch;
	return NULL;
}

// Iterate over all wires in an interface and add them as wires in the AST module:
void AST::explode_interface_port(AstNode *module_ast, RTLIL::Module * intfmodule, std::string intfname, AstNode *modport)
{
	for (auto &wire_it : intfmodule->wires_){
		AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true)));
		std::string origname = log_id(wire_it.first);
		std::string newname = intfname + "." + origname;
		wire->str = newname;
		if (modport != NULL) {
			bool found_in_modport = false;
			// Search for the current wire in the wire list for the current modport
			for (auto &ch : modport->children) {
				if (ch->type == AST_MODPORTMEMBER) {
					std::string compare_name = "\\" + origname;
					if (ch->str == compare_name) { // Found signal. The modport decides whether it is input or output
						found_in_modport = true;
						wire->is_input = ch->is_input;
						wire->is_output = ch->is_output;
						break;
					}
				}
			}
			if (found_in_modport) {
				module_ast->children.push_back(wire);
			}
			else { // If not found in modport, do not create port
				delete wire;
			}
		}
		else { // If no modport, set inout
			wire->is_input = true;
			wire->is_output = true;
			module_ast->children.push_back(wire);
		}
	}
}

// When an interface instance is found in a module, the whole RTLIL for the module will be rederived again
// from AST. The interface members are copied into the AST module with the prefix of the interface.
void AstModule::reprocess_module(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Module*> local_interfaces)
{
	bool is_top = false;
	AstNode *new_ast = ast->clone();
	for (auto &intf : local_interfaces) {
		std::string intfname = intf.first.str();
		RTLIL::Module *intfmodule = intf.second;
		for (auto &wire_it : intfmodule->wires_){
			AstNode *wire = new AstNode(AST_WIRE, new AstNode(AST_RANGE, AstNode::mkconst_int(wire_it.second->width -1, true), AstNode::mkconst_int(0, true)));
			std::string newname = log_id(wire_it.first);
			newname = intfname + "." + newname;
			wire->str = newname;
			new_ast->children.push_back(wire);
		}
	}

	AstNode *ast_before_replacing_interface_ports = new_ast->clone();

	// Explode all interface ports. Note this will only have an effect on 'top
	// level' modules. Other sub-modules will have their interface ports
	// exploded via the derive(..) function
	for (size_t i =0; i<new_ast->children.size(); i++)
	{
		AstNode *ch2 = new_ast->children[i];
		if (ch2->type == AST_INTERFACEPORT) { // Is an interface port
			std::string name_port = ch2->str; // Name of the interface port
			if (ch2->children.size() > 0) {
				for(size_t j=0; j<ch2->children.size();j++) {
					AstNode *ch = ch2->children[j];
					if(ch->type == AST_INTERFACEPORTTYPE) { // Found the AST node containing the type of the interface
						std::pair<std::string,std::string> res = split_modport_from_type(ch->str);
						std::string interface_type = res.first;
						std::string interface_modport = res.second; // Is "", if no modport
						if (design->modules_.count(interface_type) > 0) {
							// Add a cell to the module corresponding to the interface port such that
							// it can further propagated down if needed:
							AstNode *celltype_for_intf = new AstNode(AST_CELLTYPE);
							celltype_for_intf->str = interface_type;
							AstNode *cell_for_intf = new AstNode(AST_CELL, celltype_for_intf);
							cell_for_intf->str = name_port + "_inst_from_top_dummy";
							new_ast->children.push_back(cell_for_intf);

							// Get all members of this non-overridden dummy interface instance:
							RTLIL::Module *intfmodule = design->modules_[interface_type]; // All interfaces should at this point in time (assuming
							                                                              // reprocess_module is called from the hierarchy pass) be
							                                                              // present in design->modules_
							AstModule *ast_module_of_interface = (AstModule*)intfmodule;
							std::string interface_modport_compare_str = "\\" + interface_modport;
							AstNode *modport = find_modport(ast_module_of_interface->ast, interface_modport_compare_str); // modport == NULL if no modport
							// Iterate over all wires in the interface and add them to the module:
							explode_interface_port(new_ast, intfmodule, name_port, modport);
						}
						break;
					}
				}
			}
		}
	}

	// The old module will be deleted. Rename and mark for deletion:
	std::string original_name = this->name.str();
	std::string changed_name = original_name + "_before_replacing_local_interfaces";
	design->rename(this, changed_name);
	this->set_bool_attribute("\\to_delete");

	// Check if the module was the top module. If it was, we need to remove the top attribute and put it on the
	// new module.
	if (this->get_bool_attribute("\\initial_top")) {
		this->attributes.erase("\\initial_top");
		is_top = true;
	}

	// Generate RTLIL from AST for the new module and add to the design:
	AstModule *newmod = process_module(new_ast, false, ast_before_replacing_interface_ports);
	delete(new_ast);
	design->add(newmod);
	RTLIL::Module* mod = design->module(original_name);
	if (is_top)
		mod->set_bool_attribute("\\top");

	// Set the attribute "interfaces_replaced_in_module" so that it does not happen again.
	mod->set_bool_attribute("\\interfaces_replaced_in_module");
}

// create a new parametric module (when needed) and return the name of the generated module - WITH support for interfaces
// This method is used to explode the interface when the interface is a port of the module (not instantiated inside)
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, dict<RTLIL::IdString, RTLIL::Module*> interfaces, dict<RTLIL::IdString, RTLIL::IdString> modports, bool mayfail)
{
	AstNode *new_ast = NULL;
	std::string modname = derive_common(design, parameters, &new_ast, mayfail);

	// Since interfaces themselves may be instantiated with different parameters,
	// "modname" must also take those into account, so that unique modules
	// are derived for any variant of interface connections:
	std::string interf_info = "";

	bool has_interfaces = false;
	for(auto &intf : interfaces) {
		interf_info += log_id(intf.second->name);
		has_interfaces = true;
	}

	if (has_interfaces)
		modname += "$interfaces$" + interf_info;


	if (!design->has(modname)) {
		new_ast->str = modname;

		// Iterate over all interfaces which are ports in this module:
		for(auto &intf : interfaces) {
			RTLIL::Module * intfmodule = intf.second;
			std::string intfname = intf.first.str();
			// Check if a modport applies for the interface port:
			AstNode *modport = NULL;
			if (modports.count(intfname) > 0) {
				std::string interface_modport = modports.at(intfname).str();
				AstModule *ast_module_of_interface = (AstModule*)intfmodule;
				AstNode *ast_node_of_interface = ast_module_of_interface->ast;
				modport = find_modport(ast_node_of_interface, interface_modport);
			}
			// Iterate over all wires in the interface and add them to the module:
			explode_interface_port(new_ast, intfmodule, intfname, modport);
		}

		design->add(process_module(new_ast, false));
		design->module(modname)->check();

		RTLIL::Module* mod = design->module(modname);

		// Now that the interfaces have been exploded, we can delete the dummy port related to every interface.
		for(auto &intf : interfaces) {
			if(mod->wires_.count(intf.first)) {
				mod->wires_.erase(intf.first);
				mod->fixup_ports();
				// We copy the cell of the interface to the sub-module such that it can further be found if it is propagated
				// down to sub-sub-modules etc.
				RTLIL::Cell * new_subcell = mod->addCell(intf.first, intf.second->name);
				new_subcell->set_bool_attribute("\\is_interface");
			}
			else {
				log_error("No port with matching name found (%s) in %s. Stopping\n", log_id(intf.first), modname.c_str());
			}
		}

		// If any interfaces were replaced, set the attribute 'interfaces_replaced_in_module':
		if (interfaces.size() > 0) {
			mod->set_bool_attribute("\\interfaces_replaced_in_module");
		}

	} else {
		log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
	}

	delete new_ast;
	return modname;
}

// create a new parametric module (when needed) and return the name of the generated module - without support for interfaces
RTLIL::IdString AstModule::derive(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, bool mayfail)
{
	AstNode *new_ast = NULL;
	std::string modname = derive_common(design, parameters, &new_ast, mayfail);

	if (!design->has(modname)) {
		new_ast->str = modname;
		design->add(process_module(new_ast, false));
		design->module(modname)->check();
	} else {
		log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
	}

	delete new_ast;
	return modname;
}

// create a new parametric module (when needed) and return the name of the generated module
std::string AstModule::derive_common(RTLIL::Design *design, dict<RTLIL::IdString, RTLIL::Const> parameters, AstNode **new_ast_out, bool)
{
	std::string stripped_name = name.str();

	if (stripped_name.substr(0, 9) == "$abstract")
		stripped_name = stripped_name.substr(9);

	log_header(design, "Executing AST frontend in derive mode using pre-parsed AST for module `%s'.\n", stripped_name.c_str());

	current_ast = NULL;
	flag_dump_ast1 = false;
	flag_dump_ast2 = false;
	flag_dump_vlog = false;
	flag_nolatches = nolatches;
	flag_nomeminit = nomeminit;
	flag_nomem2reg = nomem2reg;
	flag_mem2reg = mem2reg;
	flag_lib = lib;
	flag_noopt = noopt;
	flag_icells = icells;
	flag_autowire = autowire;
	use_internal_line_num();

	std::string para_info;
	AstNode *new_ast = ast->clone();

	int para_counter = 0;
	int orig_parameters_n = parameters.size();
	for (auto it = new_ast->children.begin(); it != new_ast->children.end(); it++) {
		AstNode *child = *it;
		if (child->type != AST_PARAMETER)
			continue;
		para_counter++;
		std::string para_id = child->str;
		if (parameters.count(para_id) > 0) {
			log("Parameter %s = %s\n", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[child->str])));
	rewrite_parameter:
			para_info += stringf("%s=%s", child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
			delete child->children.at(0);
			if ((parameters[para_id].flags & RTLIL::CONST_FLAG_STRING) != 0)
				child->children[0] = AstNode::mkconst_str(parameters[para_id].decode_string());
			else
				child->children[0] = AstNode::mkconst_bits(parameters[para_id].bits, (parameters[para_id].flags & RTLIL::CONST_FLAG_SIGNED) != 0);
			parameters.erase(para_id);
			continue;
		}
		para_id = stringf("$%d", para_counter);
		if (parameters.count(para_id) > 0) {
			log("Parameter %d (%s) = %s\n", para_counter, child->str.c_str(), log_signal(RTLIL::SigSpec(parameters[para_id])));
			goto rewrite_parameter;
		}
	}

	for (auto param : parameters) {
		AstNode *defparam = new AstNode(AST_DEFPARAM, new AstNode(AST_IDENTIFIER));
		defparam->children[0]->str = param.first.str();
		if ((param.second.flags & RTLIL::CONST_FLAG_STRING) != 0)
			defparam->children.push_back(AstNode::mkconst_str(param.second.decode_string()));
		else
			defparam->children.push_back(AstNode::mkconst_bits(param.second.bits, (param.second.flags & RTLIL::CONST_FLAG_SIGNED) != 0));
		new_ast->children.push_back(defparam);
	}

	std::string modname;

	if (orig_parameters_n == 0)
		modname = stripped_name;
	else if (para_info.size() > 60)
		modname = "$paramod$" + sha1(para_info) + stripped_name;
	else
		modname = "$paramod" + stripped_name + para_info;


	(*new_ast_out) = new_ast;
	return modname;
}

RTLIL::Module *AstModule::clone() const
{
	AstModule *new_mod = new AstModule;
	new_mod->name = name;
	cloneInto(new_mod);

	new_mod->ast = ast->clone();
	new_mod->nolatches = nolatches;
	new_mod->nomeminit = nomeminit;
	new_mod->nomem2reg = nomem2reg;
	new_mod->mem2reg = mem2reg;
	new_mod->lib = lib;
	new_mod->noopt = noopt;
	new_mod->icells = icells;
	new_mod->autowire = autowire;

	return new_mod;
}

// internal dummy line number callbacks
namespace {
	int internal_line_num;
	void internal_set_line_num(int n) {
		internal_line_num = n;
	}
	int internal_get_line_num() {
		return internal_line_num;
	}
}

// use internal dummy line number callbacks
void AST::use_internal_line_num()
{
	set_line_num = &internal_set_line_num;
	get_line_num = &internal_get_line_num;
}

YOSYS_NAMESPACE_END
