macro processor: introduce integer casts
parent
4a3423f74f
commit
5fc83fad29
|
@ -297,6 +297,19 @@ String::is_equal(const BaseTypePtr &btp) const
|
|||
return make_shared<Bool>(value == btp2->value, env);
|
||||
}
|
||||
|
||||
DoublePtr
|
||||
String::cast_int() const
|
||||
{
|
||||
try
|
||||
{
|
||||
return make_shared<Double>(stoi(value), env);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw StackTrace(value + " cannot be converted to an int");
|
||||
}
|
||||
}
|
||||
|
||||
BaseTypePtr
|
||||
Array::plus(const BaseTypePtr &btp) const
|
||||
{
|
||||
|
@ -492,6 +505,14 @@ Array::sum() const
|
|||
return make_shared<Double>(retval, env);
|
||||
}
|
||||
|
||||
DoublePtr
|
||||
Array::cast_int() const
|
||||
{
|
||||
if (arr.size() != 1)
|
||||
throw StackTrace("Array must be of size 1 to be cast to an int");
|
||||
return arr.at(0)->eval()->cast_int();
|
||||
}
|
||||
|
||||
BoolPtr
|
||||
Tuple::is_equal(const BaseTypePtr &btp) const
|
||||
{
|
||||
|
@ -526,6 +547,14 @@ Tuple::contains(const BaseTypePtr &btp) const
|
|||
return make_shared<Bool>(false, env);
|
||||
}
|
||||
|
||||
DoublePtr
|
||||
Tuple::cast_int() const
|
||||
{
|
||||
if (tup.size() != 1)
|
||||
throw StackTrace("Tuple must be of size 1 to be cast to an int");
|
||||
return tup.at(0)->eval()->cast_int();
|
||||
}
|
||||
|
||||
BaseTypePtr
|
||||
Array::eval()
|
||||
{
|
||||
|
@ -709,6 +738,8 @@ UnaryOp::eval()
|
|||
auto argbt = arg->eval();
|
||||
switch (op_code)
|
||||
{
|
||||
case codes::UnaryOp::cast_int:
|
||||
return argbt->cast_int();
|
||||
case codes::UnaryOp::logical_not:
|
||||
return argbt->logical_not();
|
||||
case codes::UnaryOp::unary_minus:
|
||||
|
@ -1029,6 +1060,8 @@ UnaryOp::to_string() const noexcept
|
|||
string retval = arg->to_string();
|
||||
switch (op_code)
|
||||
{
|
||||
case codes::UnaryOp::cast_int:
|
||||
return "(int)" + retval;
|
||||
case codes::UnaryOp::logical_not:
|
||||
return "!" + retval;
|
||||
case codes::UnaryOp::unary_minus:
|
||||
|
@ -1229,6 +1262,9 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
|
|||
{
|
||||
switch (op_code)
|
||||
{
|
||||
case codes::UnaryOp::cast_int:
|
||||
output << "(int)";
|
||||
break;
|
||||
case codes::UnaryOp::logical_not:
|
||||
output << "!";
|
||||
break;
|
||||
|
@ -1314,7 +1350,8 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
|
|||
|
||||
arg->print(output, matlab_output);
|
||||
|
||||
if (op_code != codes::UnaryOp::logical_not
|
||||
if (op_code != codes::UnaryOp::cast_int
|
||||
&& op_code != codes::UnaryOp::logical_not
|
||||
&& op_code != codes::UnaryOp::unary_plus
|
||||
&& op_code != codes::UnaryOp::unary_minus)
|
||||
output << ")";
|
||||
|
|
|
@ -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 DoublePtr cast_int() const { throw StackTrace("This type cannot be cast to an integer"); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -202,6 +203,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 DoublePtr cast_int() const override { return value ? make_shared<Double>(1, env) : make_shared<Double>(0, env); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -286,6 +288,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 DoublePtr cast_int() const override { return make_shared<Double>(static_cast<int>(value), env); }
|
||||
};
|
||||
|
||||
class String final : public BaseType
|
||||
|
@ -310,6 +313,7 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -335,6 +339,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); }
|
||||
DoublePtr cast_int() const override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -376,6 +381,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;
|
||||
DoublePtr cast_int() const override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace macro
|
|||
|
||||
enum class UnaryOp
|
||||
{
|
||||
cast_int,
|
||||
logical_not,
|
||||
unary_minus,
|
||||
unary_plus,
|
||||
|
|
|
@ -65,6 +65,8 @@ 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
|
||||
|
||||
%left OR
|
||||
%left AND
|
||||
%left EQUAL_EQUAL NOT_EQUAL
|
||||
|
@ -76,6 +78,7 @@ using namespace macro;
|
|||
%left PLUS MINUS
|
||||
%left TIMES DIVIDE
|
||||
%precedence UMINUS UPLUS NOT
|
||||
%precedence CAST_INT
|
||||
%nonassoc POWER
|
||||
|
||||
%token <string> NAME TEXT QUOTED_STRING NUMBER EOL
|
||||
|
@ -319,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 INT RPAREN expr %prec CAST_INT
|
||||
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::cast_int, $4, driver.env, @$); }
|
||||
| NOT expr
|
||||
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::logical_not, $2, driver.env, @$); }
|
||||
| MINUS expr %prec UMINUS
|
||||
|
|
|
@ -142,6 +142,8 @@ CONT \\\\{SPC}*
|
|||
<expr,eval>normpdf { return token::NORMPDF; }
|
||||
<expr,eval>normcdf { return token::NORMCDF; }
|
||||
|
||||
<expr,eval>int { return token::INT; }
|
||||
|
||||
<expr,eval>((([0-9]*\.[0-9]+)|([0-9]+\.))([ed][-+]?[0-9]+)?)|([0-9]+([ed][-+]?[0-9]+)?)|nan|inf {
|
||||
yylval->build<string>(yytext);
|
||||
return token::NUMBER;
|
||||
|
|
Loading…
Reference in New Issue