macro processor: introduce bool casts

issue#70
Houtan Bastani 2019-08-05 14:04:57 -04:00
parent eaa8b8fa84
commit b3798a0baa
No known key found for this signature in database
GPG Key ID: 000094FB955BE169
5 changed files with 52 additions and 5 deletions

View File

@ -297,6 +297,19 @@ String::is_equal(const BaseTypePtr &btp) const
return make_shared<Bool>(value == btp2->value, env);
}
BoolPtr
String::cast_bool() const
{
try
{
return make_shared<Bool>(static_cast<bool>(stoi(value)), env);
}
catch (...)
{
throw StackTrace(value + " cannot be converted to a boolean");
}
}
DoublePtr
String::cast_int() const
{
@ -518,6 +531,14 @@ Array::sum() const
return make_shared<Double>(retval, env);
}
BoolPtr
Array::cast_bool() const
{
if (arr.size() != 1)
throw StackTrace("Array must be of size 1 to be cast to a boolean");
return arr.at(0)->eval()->cast_bool();
}
DoublePtr
Array::cast_int() const
{
@ -568,6 +589,14 @@ Tuple::contains(const BaseTypePtr &btp) const
return make_shared<Bool>(false, env);
}
BoolPtr
Tuple::cast_bool() const
{
if (tup.size() != 1)
throw StackTrace("Tuple must be of size 1 to be cast to a boolean");
return tup.at(0)->eval()->cast_bool();
}
DoublePtr
Tuple::cast_int() const
{
@ -767,6 +796,8 @@ UnaryOp::eval()
auto argbt = arg->eval();
switch (op_code)
{
case codes::UnaryOp::cast_bool:
return argbt->cast_bool();
case codes::UnaryOp::cast_int:
return argbt->cast_int();
case codes::UnaryOp::cast_double:
@ -1097,6 +1128,8 @@ UnaryOp::to_string() const noexcept
string retval = arg->to_string();
switch (op_code)
{
case codes::UnaryOp::cast_bool:
return "(bool)" + retval;
case codes::UnaryOp::cast_int:
return "(int)" + retval;
case codes::UnaryOp::cast_double:
@ -1307,6 +1340,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
{
switch (op_code)
{
case codes::UnaryOp::cast_bool:
output << "(bool)";
break;
case codes::UnaryOp::cast_int:
output << "(int)";
break;
@ -1407,7 +1443,8 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
arg->print(output, matlab_output);
if (op_code != codes::UnaryOp::cast_int
if (op_code != codes::UnaryOp::cast_bool
&& op_code != codes::UnaryOp::cast_int
&& op_code != codes::UnaryOp::cast_double
&& op_code != codes::UnaryOp::cast_string
&& op_code != codes::UnaryOp::cast_tuple

View File

@ -180,6 +180,7 @@ namespace macro
virtual DoublePtr normpdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normpdf` does not exist for this type"); }
virtual DoublePtr normcdf() const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
virtual DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const { throw StackTrace("Operator `normcdf` does not exist for this type"); }
virtual BoolPtr cast_bool() const { throw StackTrace("This type cannot be cast to a boolean"); }
virtual DoublePtr cast_int() const { throw StackTrace("This type cannot be cast to an integer"); }
virtual DoublePtr cast_double() const { throw StackTrace("This type cannot be cast to a double"); }
virtual StringPtr cast_string() const { throw StackTrace("This type cannot be cast to a string"); }
@ -207,6 +208,7 @@ namespace macro
BoolPtr logical_and(const BaseTypePtr &btp) const override;
BoolPtr logical_or(const BaseTypePtr &btp) const override;
BoolPtr logical_not() const override;
inline BoolPtr cast_bool() const override { return make_shared<Bool>(value, env); }
inline DoublePtr cast_int() const override { return value ? make_shared<Double>(1, env) : make_shared<Double>(0, env); }
inline DoublePtr cast_double() const override { return cast_int(); }
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
@ -302,6 +304,7 @@ namespace macro
return normcdf(make_shared<Double>(0, env), make_shared<Double>(1, env));
}
DoublePtr normcdf(const BaseTypePtr &btp1, const BaseTypePtr &btp2) const override;
inline BoolPtr cast_bool() const override { return make_shared<Bool>(static_cast<bool>(value), env); }
inline DoublePtr cast_int() const override { return make_shared<Double>(static_cast<int>(value), env); }
inline DoublePtr cast_double() const override { return make_shared<Double>(value, env); }
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
@ -337,8 +340,9 @@ namespace macro
BoolPtr is_greater_equal(const BaseTypePtr &btp) const override;
BoolPtr is_equal(const BaseTypePtr &btp) const override;
inline DoublePtr length() const override { return make_shared<Double>(value.size(), env); }
inline DoublePtr cast_int() const override;
inline DoublePtr cast_double() const override;
BoolPtr cast_bool() const override;
DoublePtr cast_int() const override;
DoublePtr cast_double() const override;
inline StringPtr cast_string() const override { return make_shared<String>(value, env); }
inline TuplePtr cast_tuple() const override
{
@ -373,6 +377,7 @@ namespace macro
BoolPtr is_equal(const BaseTypePtr &btp) const override;
BoolPtr contains(const BaseTypePtr &btp) const override;
inline DoublePtr length() const override { return make_shared<Double>(tup.size(), env); }
BoolPtr cast_bool() const override;
DoublePtr cast_int() const override;
DoublePtr cast_double() const override;
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
@ -419,6 +424,7 @@ namespace macro
BoolPtr contains(const BaseTypePtr &btp) const override;
inline DoublePtr length() const override { return make_shared<Double>(arr.size(), env); }
DoublePtr sum() const override;
BoolPtr cast_bool() const override;
DoublePtr cast_int() const override;
DoublePtr cast_double() const override;
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }

View File

@ -67,6 +67,7 @@ namespace macro
enum class UnaryOp
{
cast_bool,
cast_int,
cast_double,
cast_string,

View File

@ -65,7 +65,7 @@ using namespace macro;
%token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD
%token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH
%token INT DOUBLE STRING TUPLE ARRAY
%token BOOL INT DOUBLE STRING TUPLE ARRAY
%left OR
%left AND
@ -78,7 +78,7 @@ using namespace macro;
%left PLUS MINUS
%left TIMES DIVIDE
%precedence UMINUS UPLUS NOT
%precedence CAST_INT CAST_DOUBLE CAST_STRING CAST_TUPLE CAST_ARRAY
%precedence CAST_BOOL CAST_INT CAST_DOUBLE CAST_STRING CAST_TUPLE CAST_ARRAY
%nonassoc POWER
%token <string> NAME TEXT QUOTED_STRING NUMBER EOL
@ -322,6 +322,8 @@ expr : LPAREN expr RPAREN
{ $$ = make_shared<Comprehension>($2, $4, $6, driver.env, @$); }
| LBRACKET expr FOR expr IN expr WHEN expr RBRACKET
{ $$ = make_shared<Comprehension>($2, $4, $6, $8, driver.env, @$); }
| LPAREN BOOL RPAREN expr %prec CAST_BOOL
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_bool, $4, driver.env, @$); }
| LPAREN INT RPAREN expr %prec CAST_INT
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_int, $4, driver.env, @$); }
| LPAREN DOUBLE RPAREN expr %prec CAST_DOUBLE

View File

@ -142,6 +142,7 @@ CONT \\\\{SPC}*
<expr,eval>normpdf { return token::NORMPDF; }
<expr,eval>normcdf { return token::NORMCDF; }
<expr,eval>bool { return token::BOOL; }
<expr,eval>int { return token::INT; }
<expr,eval>double { return token::DOUBLE; }
<expr,eval>string { return token::STRING; }