206 lines
5.2 KiB
C++
206 lines
5.2 KiB
C++
/* Authors: Aaron Graham (aaron.graham@unb.ca, aarongraham9@gmail.com),
|
|
* Jean-Philippe Legault (jlegault@unb.ca, jeanphilippe.legault@gmail.com) and
|
|
* Dr. Kenneth B. Kent (ken@unb.ca)
|
|
* for the Reconfigurable Computing Research Lab at the
|
|
* Univerity of New Brunswick in Fredericton, New Brunswick, Canada
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <algorithm>
|
|
|
|
#include "rtl_int.hpp"
|
|
#include "rtl_utils.hpp"
|
|
|
|
#define bad_ops(test) _bad_ops(test, __func__, __LINE__)
|
|
inline static std::string _bad_ops(std::string test, const char *FUNCT, int LINE)
|
|
{
|
|
std::cerr << "INVALID INPUT OPS: (" << test << ")@" << FUNCT << "::" << std::to_string(LINE) << std::endl;
|
|
std::abort();
|
|
}
|
|
|
|
/***
|
|
* __ __ ___ __ __ ___ __
|
|
* / ` / \ |\ | | |__) / \ | |__ | / \ | |
|
|
* \__, \__/ | \| | | \ \__/ |___ | |___ \__/ |/\|
|
|
*
|
|
* This is used for testing purposes only, unused in ODIN as the input is already preprocessed
|
|
*/
|
|
|
|
static std::string arithmetic(std::string op, std::string a_in)
|
|
{
|
|
|
|
VNumber a(a_in);
|
|
|
|
|
|
/* return Process Operator via ternary */
|
|
return (
|
|
(op == "to_unsigned")? V_UNSIGNED(a):
|
|
(op == "to_signed") ? V_SIGNED(a):
|
|
(op == "~") ? V_BITWISE_NOT(a):
|
|
(op == "-") ? V_MINUS(a):
|
|
(op == "+") ? V_ADD(a):
|
|
(op == "&") ? V_BITWISE_AND(a):
|
|
(op == "|") ? V_BITWISE_OR(a):
|
|
(op == "^") ? V_BITWISE_XOR(a):
|
|
(op == "~&") ? V_BITWISE_NAND(a):
|
|
(op == "~|") ? V_BITWISE_NOR(a):
|
|
(op == "~^"
|
|
|| op == "^~") ? V_BITWISE_XNOR(a):
|
|
(op == "!") ? V_LOGICAL_NOT(a):
|
|
bad_ops(op)
|
|
).to_full_string();
|
|
}
|
|
|
|
static std::string arithmetic(std::string a_in, std::string op, std::string b_in)
|
|
{
|
|
|
|
VNumber a(a_in);
|
|
VNumber b(b_in);
|
|
|
|
|
|
/* return Process Operator via ternary */
|
|
return (
|
|
(op == "&") ? V_BITWISE_AND(a, b):
|
|
(op == "|") ? V_BITWISE_OR(a, b):
|
|
(op == "^") ? V_BITWISE_XOR(a, b):
|
|
(op == "~&") ? V_BITWISE_NAND(a, b):
|
|
(op == "~|") ? V_BITWISE_NOR(a, b):
|
|
(op == "~^"
|
|
|| op == "^~") ? V_BITWISE_XNOR(a, b):
|
|
/* Case test */
|
|
(op == "===" ) ? V_CASE_EQUAL(a, b):
|
|
(op == "!==") ? V_CASE_NOT_EQUAL(a, b):
|
|
/* Shift Operator */
|
|
(op == "<<") ? V_SHIFT_LEFT(a, b):
|
|
(op == "<<<") ? V_SIGNED_SHIFT_LEFT(a, b):
|
|
(op == ">>") ? V_SHIFT_RIGHT(a, b):
|
|
(op == ">>>") ? V_SIGNED_SHIFT_RIGHT(a, b):
|
|
/* Logical Operators */
|
|
(op == "&&") ? V_LOGICAL_AND(a, b):
|
|
(op == "||") ? V_LOGICAL_OR(a, b):
|
|
(op == "<") ? V_LT(a, b):
|
|
(op == ">") ? V_GT(a, b):
|
|
(op == "<=") ? V_LE(a, b):
|
|
(op == ">=") ? V_GE(a, b):
|
|
(op == "==") ? V_EQUAL(a, b):
|
|
(op == "!=") ? V_NOT_EQUAL(a, b):
|
|
/* arithmetic Operators */
|
|
(op == "+") ? V_ADD(a, b):
|
|
(op == "-") ? V_MINUS(a, b):
|
|
(op == "*") ? V_MULTIPLY(a, b):
|
|
(op == "**") ? V_POWER(a, b):
|
|
/* cannot div by 0 */
|
|
(op == "/") ? V_DIV(a, b):
|
|
(op == "%") ? V_MOD(a, b):
|
|
bad_ops(op)
|
|
).to_full_string();
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
std::vector<std::string> input;
|
|
for(int i=0; i < argc; i++) input.push_back(argv[i]);
|
|
|
|
std::string result = "";
|
|
|
|
if(argc < 3)
|
|
{
|
|
ERR_MSG("Not Enough Arguments: " << std::to_string(argc - 1));
|
|
|
|
return -1;
|
|
}
|
|
else if(argc == 3 && input[1] == "is_true")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_TRUE(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_false")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_FALSE(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_unk")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_UNK(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_x")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_IS_X(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_z")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_IS_Z(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_unsigned")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_IS_UNSIGNED(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "is_signed")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = (V_IS_SIGNED(input_2) ? "pass" : "fail");
|
|
}
|
|
else if(argc == 3 && input[1] == "display")
|
|
{
|
|
VNumber input_2(input[2]);
|
|
|
|
result = V_STRING(input_2);
|
|
}
|
|
else if(argc == 3)
|
|
{
|
|
result = arithmetic(input[1], input[2]);
|
|
}
|
|
else if(argc == 4)
|
|
{
|
|
result = arithmetic(input[1], input[2], input[3]);
|
|
|
|
}
|
|
else if(argc == 6
|
|
&& (input[2] == "?" && input[4] == ":"))
|
|
{
|
|
VNumber a(input[1]);
|
|
VNumber b(input[3]);
|
|
VNumber c(input[5]);
|
|
|
|
result = V_TERNARY(a, b, c).to_full_string();
|
|
}
|
|
else if(argc == 6
|
|
&&(input[1] == "{" && input[3] == "," && input[5] == "}")) // the pipe symbol is a hack since our test handle uses csv.
|
|
{
|
|
VNumber a(input[2]);
|
|
VNumber b(input[4]);
|
|
|
|
result = V_CONCAT({a, b}).to_full_string();
|
|
}
|
|
else if(argc == 7
|
|
&&(input[1] == "{" && input[3] == "{" && input[5] == "}" && input[6] == "}"))
|
|
{
|
|
VNumber n_times(input[2]);
|
|
VNumber replicant(input[4]);
|
|
|
|
result = V_REPLICATE(replicant, n_times).to_full_string();
|
|
}
|
|
else
|
|
{
|
|
ERR_MSG("invalid Arguments: " << std::to_string(argc - 1));
|
|
return -1;
|
|
}
|
|
|
|
std::cout << result << std::endl;
|
|
|
|
return 0;
|
|
}
|