Commits (2)
...@@ -215,6 +215,7 @@ ...@@ -215,6 +215,7 @@
\item comparison operators: \texttt{< > <= >= == !=} \item comparison operators: \texttt{< > <= >= == !=}
\item concatenation: \texttt{+} \item concatenation: \texttt{+}
\item string length: \texttt{length()} \item string length: \texttt{length()}
\item string emptiness: \texttt{isempty()}
\item extraction of substrings: if \texttt{s} is a string, then one can write \texttt{s[3]} or \texttt{s[4:6]} \item extraction of substrings: if \texttt{s} is a string, then one can write \texttt{s[3]} or \texttt{s[4:6]}
\end{itemize} \end{itemize}
\end{block} \end{block}
...@@ -227,7 +228,7 @@ ...@@ -227,7 +228,7 @@
\begin{block}{Operators on tuples} \begin{block}{Operators on tuples}
\begin{itemize} \begin{itemize}
\item comparison operators: \texttt{== !=} \item comparison operators: \texttt{== !=}
\item functions: \texttt{length, empty} \item functions: \texttt{length, isempty}
\item testing membership in tuple: \texttt{in} operator \\ (example: \item testing membership in tuple: \texttt{in} operator \\ (example:
\texttt{"b" in ("a", "b", "c")} returns \texttt{1}) \texttt{"b" in ("a", "b", "c")} returns \texttt{1})
\end{itemize} \end{itemize}
...@@ -243,7 +244,7 @@ ...@@ -243,7 +244,7 @@
\item comparison operators: \texttt{== !=} \item comparison operators: \texttt{== !=}
\item dereferencing: if \texttt{v} is an array, then \texttt{v[2]} is its $2^{\textrm{nd}}$ element \item dereferencing: if \texttt{v} is an array, then \texttt{v[2]} is its $2^{\textrm{nd}}$ element
\item concatenation: \texttt{+} \item concatenation: \texttt{+}
\item functions: \texttt{sum, length, empty} \item functions: \texttt{sum, length, isempty}
\item difference \texttt{-}: returns the first operand from which the elements of the second operand have been removed \item difference \texttt{-}: returns the first operand from which the elements of the second operand have been removed
\item Cartesian product of two arrays: \texttt{*} \item Cartesian product of two arrays: \texttt{*}
\item Cartesian product of one array \texttt{N} times: \texttt{\^{}N} \item Cartesian product of one array \texttt{N} times: \texttt{\^{}N}
......
...@@ -803,6 +803,18 @@ UnaryOp::eval() ...@@ -803,6 +803,18 @@ UnaryOp::eval()
return argbt->unary_plus(); return argbt->unary_plus();
case codes::UnaryOp::length: case codes::UnaryOp::length:
return argbt->length(); return argbt->length();
case codes::UnaryOp::isempty:
return argbt->isempty();
case codes::UnaryOp::isboolean:
return argbt->isboolean();
case codes::UnaryOp::isreal:
return argbt->isreal();
case codes::UnaryOp::isstring:
return argbt->isstring();
case codes::UnaryOp::istuple:
return argbt->istuple();
case codes::UnaryOp::isarray:
return argbt->isarray();
case codes::UnaryOp::exp: case codes::UnaryOp::exp:
return argbt->exp(); return argbt->exp();
case codes::UnaryOp::ln: case codes::UnaryOp::ln:
...@@ -1133,6 +1145,18 @@ UnaryOp::to_string() const noexcept ...@@ -1133,6 +1145,18 @@ UnaryOp::to_string() const noexcept
return "+" + retval; return "+" + retval;
case codes::UnaryOp::length: case codes::UnaryOp::length:
return "length(" + retval + ")"; return "length(" + retval + ")";
case codes::UnaryOp::isempty:
return "isempty(" + retval + ")";
case codes::UnaryOp::isboolean:
return "isboolean(" + retval + ")";
case codes::UnaryOp::isreal:
return "isreal(" + retval + ")";
case codes::UnaryOp::isstring:
return "isstring(" + retval + ")";
case codes::UnaryOp::istuple:
return "istuple(" + retval + ")";
case codes::UnaryOp::isarray:
return "isarray(" + retval + ")";
case codes::UnaryOp::exp: case codes::UnaryOp::exp:
return "exp(" + retval + ")"; return "exp(" + retval + ")";
case codes::UnaryOp::ln: case codes::UnaryOp::ln:
...@@ -1352,6 +1376,24 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept ...@@ -1352,6 +1376,24 @@ UnaryOp::print(ostream &output, bool matlab_output) const noexcept
case codes::UnaryOp::length: case codes::UnaryOp::length:
output << "length("; output << "length(";
break; break;
case codes::UnaryOp::isempty:
output << "isempty(";
break;
case codes::UnaryOp::isboolean:
output << "isboolean(";
break;
case codes::UnaryOp::isreal:
output << "isreal(";
break;
case codes::UnaryOp::isstring:
output << "isstring(";
break;
case codes::UnaryOp::istuple:
output << "istuple(";
break;
case codes::UnaryOp::isarray:
output << "isarray(";
break;
case codes::UnaryOp::exp: case codes::UnaryOp::exp:
output << "exp("; output << "exp(";
break; break;
......
...@@ -148,6 +148,12 @@ namespace macro ...@@ -148,6 +148,12 @@ namespace macro
virtual ArrayPtr set_intersection(const BaseTypePtr &btp) const { throw StackTrace("Operator & does not exist for this type"); } virtual ArrayPtr set_intersection(const BaseTypePtr &btp) const { throw StackTrace("Operator & does not exist for this type"); }
virtual BoolPtr contains(const BaseTypePtr &btp) const { throw StackTrace("Second argument of `in` operator must be an array"); } virtual BoolPtr contains(const BaseTypePtr &btp) const { throw StackTrace("Second argument of `in` operator must be an array"); }
virtual RealPtr length() const { throw StackTrace("Operator `length` does not exist for this type"); } virtual RealPtr length() const { throw StackTrace("Operator `length` does not exist for this type"); }
virtual BoolPtr isempty() const { throw StackTrace("Operator `isempty` does not exist for this type"); }
virtual BoolPtr isboolean() const { return make_shared<Bool>(false, env, location); }
virtual BoolPtr isreal() const { return make_shared<Bool>(false, env, location); }
virtual BoolPtr isstring() const { return make_shared<Bool>(false, env, location); }
virtual BoolPtr istuple() const { return make_shared<Bool>(false, env, location); }
virtual BoolPtr isarray() const { return make_shared<Bool>(false, env, location); }
virtual RealPtr max(const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); } virtual RealPtr max(const BaseTypePtr &btp) const { throw StackTrace("Operator `max` does not exist for this type"); }
virtual RealPtr min(const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); } virtual RealPtr min(const BaseTypePtr &btp) const { throw StackTrace("Operator `min` does not exist for this type"); }
virtual RealPtr mod(const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); } virtual RealPtr mod(const BaseTypePtr &btp) const { throw StackTrace("Operator `mod` does not exist for this type"); }
...@@ -207,6 +213,7 @@ namespace macro ...@@ -207,6 +213,7 @@ namespace macro
BoolPtr logical_and(const BaseTypePtr &btp) const override; BoolPtr logical_and(const BaseTypePtr &btp) const override;
BoolPtr logical_or(const BaseTypePtr &btp) const override; BoolPtr logical_or(const BaseTypePtr &btp) const override;
BoolPtr logical_not() const override; BoolPtr logical_not() const override;
inline BoolPtr isboolean() const override { return make_shared<Bool>(true, env, location); }
inline BoolPtr cast_bool() const override { return make_shared<Bool>(value, env); } inline BoolPtr cast_bool() const override { return make_shared<Bool>(value, env); }
inline RealPtr cast_real() const override { return value ? make_shared<Real>(1, env) : make_shared<Real>(0, env); } inline RealPtr cast_real() const override { return value ? make_shared<Real>(1, env) : make_shared<Real>(0, env); }
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
...@@ -259,6 +266,7 @@ namespace macro ...@@ -259,6 +266,7 @@ namespace macro
BoolPtr is_less_equal(const BaseTypePtr &btp) const override; BoolPtr is_less_equal(const BaseTypePtr &btp) const override;
BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; BoolPtr is_greater_equal(const BaseTypePtr &btp) const override;
BoolPtr is_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override;
inline BoolPtr isreal() const override { return make_shared<Bool>(true, env, location); }
BoolPtr logical_and(const BaseTypePtr &btp) const override; BoolPtr logical_and(const BaseTypePtr &btp) const override;
BoolPtr logical_or(const BaseTypePtr &btp) const override; BoolPtr logical_or(const BaseTypePtr &btp) const override;
BoolPtr logical_not() const override; BoolPtr logical_not() const override;
...@@ -336,7 +344,9 @@ namespace macro ...@@ -336,7 +344,9 @@ namespace macro
BoolPtr is_less_equal(const BaseTypePtr &btp) const override; BoolPtr is_less_equal(const BaseTypePtr &btp) const override;
BoolPtr is_greater_equal(const BaseTypePtr &btp) const override; BoolPtr is_greater_equal(const BaseTypePtr &btp) const override;
BoolPtr is_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override;
inline BoolPtr isstring() const override { return make_shared<Bool>(true, env, location); }
inline RealPtr length() const override { return make_shared<Real>(value.size(), env); } inline RealPtr length() const override { return make_shared<Real>(value.size(), env); }
inline BoolPtr isempty() const override { return make_shared<Bool>(value.empty(), env); }
BoolPtr cast_bool() const override; BoolPtr cast_bool() const override;
RealPtr cast_real() const override; RealPtr cast_real() const override;
inline StringPtr cast_string() const override { return make_shared<String>(value, env); } inline StringPtr cast_string() const override { return make_shared<String>(value, env); }
...@@ -371,8 +381,10 @@ namespace macro ...@@ -371,8 +381,10 @@ namespace macro
inline vector<ExpressionPtr> getValue() const { return tup; } inline vector<ExpressionPtr> getValue() const { return tup; }
inline ExpressionPtr at(int i) const { return tup.at(i); } inline ExpressionPtr at(int i) const { return tup.at(i); }
BoolPtr is_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override;
inline BoolPtr istuple() const override { return make_shared<Bool>(true, env, location); }
BoolPtr contains(const BaseTypePtr &btp) const override; BoolPtr contains(const BaseTypePtr &btp) const override;
inline RealPtr length() const override { return make_shared<Real>(tup.size(), env); } inline RealPtr length() const override { return make_shared<Real>(tup.size(), env); }
inline BoolPtr isempty() const override { return make_shared<Bool>(empty(), env); }
BoolPtr cast_bool() const override; BoolPtr cast_bool() const override;
RealPtr cast_real() const override; RealPtr cast_real() const override;
inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); } inline StringPtr cast_string() const override { return make_shared<String>(this->to_string(), env); }
...@@ -414,10 +426,12 @@ namespace macro ...@@ -414,10 +426,12 @@ namespace macro
BaseTypePtr times(const BaseTypePtr &bt) const override; BaseTypePtr times(const BaseTypePtr &bt) const override;
BaseTypePtr power(const BaseTypePtr &btp) const override; BaseTypePtr power(const BaseTypePtr &btp) const override;
BoolPtr is_equal(const BaseTypePtr &btp) const override; BoolPtr is_equal(const BaseTypePtr &btp) const override;
inline BoolPtr isarray() const override { return make_shared<Bool>(true, env, location); }
ArrayPtr set_union(const BaseTypePtr &btp) const override; ArrayPtr set_union(const BaseTypePtr &btp) const override;
ArrayPtr set_intersection(const BaseTypePtr &btp) const override; ArrayPtr set_intersection(const BaseTypePtr &btp) const override;
BoolPtr contains(const BaseTypePtr &btp) const override; BoolPtr contains(const BaseTypePtr &btp) const override;
inline RealPtr length() const override { return make_shared<Real>(arr.size(), env); } inline RealPtr length() const override { return make_shared<Real>(arr.size(), env); }
inline BoolPtr isempty() const override { return make_shared<Bool>(empty(), env); }
RealPtr sum() const override; RealPtr sum() const override;
BoolPtr cast_bool() const override; BoolPtr cast_bool() const override;
RealPtr cast_real() const override; RealPtr cast_real() const override;
......
...@@ -76,6 +76,12 @@ namespace macro ...@@ -76,6 +76,12 @@ namespace macro
unary_minus, unary_minus,
unary_plus, unary_plus,
length, length,
isempty,
isboolean,
isreal,
isstring,
istuple,
isarray,
exp, exp,
ln, ln,
log10, log10,
......
...@@ -65,6 +65,9 @@ using namespace macro; ...@@ -65,6 +65,9 @@ using namespace macro;
%token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD %token SQRT CBRT SIGN MAX MIN FLOOR CEIL TRUNC SUM MOD
%token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH %token ERF ERFC GAMMA LGAMMA ROUND NORMPDF NORMCDF LENGTH
%token ISEMPTY
%token ISBOOLEAN ISREAL ISSTRING ISTUPLE ISARRAY
%token BOOL REAL STRING TUPLE ARRAY %token BOOL REAL STRING TUPLE ARRAY
%left OR %left OR
...@@ -340,6 +343,18 @@ expr : LPAREN expr RPAREN ...@@ -340,6 +343,18 @@ expr : LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_plus, $2, driver.env, @$); } { $$ = make_shared<UnaryOp>(codes::UnaryOp::unary_plus, $2, driver.env, @$); }
| LENGTH LPAREN expr RPAREN | LENGTH LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::length, $3, driver.env, @$); } { $$ = make_shared<UnaryOp>(codes::UnaryOp::length, $3, driver.env, @$); }
| ISEMPTY LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::isempty, $3, driver.env, @$); }
| ISBOOLEAN LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::isboolean, $3, driver.env, @$); }
| ISREAL LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::isreal, $3, driver.env, @$); }
| ISSTRING LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::isstring, $3, driver.env, @$); }
| ISTUPLE LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::istuple, $3, driver.env, @$); }
| ISARRAY LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::isarray, $3, driver.env, @$); }
| EXP LPAREN expr RPAREN | EXP LPAREN expr RPAREN
{ $$ = make_shared<UnaryOp>(codes::UnaryOp::exp, $3, driver.env, @$); } { $$ = make_shared<UnaryOp>(codes::UnaryOp::exp, $3, driver.env, @$); }
| LOG LPAREN expr RPAREN | LOG LPAREN expr RPAREN
......
...@@ -142,6 +142,13 @@ CONT \\\\{SPC}* ...@@ -142,6 +142,13 @@ CONT \\\\{SPC}*
<expr,eval>normpdf { return token::NORMPDF; } <expr,eval>normpdf { return token::NORMPDF; }
<expr,eval>normcdf { return token::NORMCDF; } <expr,eval>normcdf { return token::NORMCDF; }
<expr,eval>isempty { return token::ISEMPTY; }
<expr,eval>isboolean { return token::ISBOOLEAN; }
<expr,eval>isreal { return token::ISREAL; }
<expr,eval>isstring { return token::ISSTRING; }
<expr,eval>istuple { return token::ISTUPLE; }
<expr,eval>isarray { return token::ISARRAY; }
<expr,eval>bool { return token::BOOL; } <expr,eval>bool { return token::BOOL; }
<expr,eval>real { return token::REAL; } <expr,eval>real { return token::REAL; }
<expr,eval>string { return token::STRING; } <expr,eval>string { return token::STRING; }
......