macro processor: introduce colon operator with three args
This introduces a shift/reduce compilation warning in the macro processor because at expr COLON expr . COLON expr the parser doesn’t know whether to shift or reduceissue#70
parent
ae0a91256a
commit
866e4d6d39
|
@ -531,38 +531,29 @@ Array::eval()
|
||||||
{
|
{
|
||||||
if (arr.empty() && range1 && range2)
|
if (arr.empty() && range1 && range2)
|
||||||
{
|
{
|
||||||
DoublePtr range1int = dynamic_pointer_cast<Double>(range1->eval());
|
DoublePtr range1dbl = dynamic_pointer_cast<Double>(range1->eval());
|
||||||
DoublePtr range2int = dynamic_pointer_cast<Double>(range2->eval());
|
DoublePtr range2dbl = dynamic_pointer_cast<Double>(range2->eval());
|
||||||
if (!range1int || !range2int)
|
if (!range1dbl || !range2dbl)
|
||||||
throw StackTrace("To create an array from a range using the colon operator, "
|
throw StackTrace("To create an array from a range using the colon operator, "
|
||||||
"both arguments must be doubles");
|
"the arguments must evaluate to doubles");
|
||||||
|
|
||||||
|
DoublePtr incdbl = make_shared<Double>(1, env);
|
||||||
if (increment)
|
if (increment)
|
||||||
{
|
{
|
||||||
auto incrementp = dynamic_pointer_cast<Double>(increment->eval());
|
incdbl = dynamic_pointer_cast<Double>(increment->eval());
|
||||||
if (*incrementp == 0)
|
if (!incdbl)
|
||||||
throw StackTrace("the increment cannot be equal to zero");
|
throw StackTrace("To create an array from a range using the colon operator, "
|
||||||
|
"the increment must evaluate to a double");
|
||||||
if (*range1int <= *range2int)
|
|
||||||
if (*incrementp < 0)
|
|
||||||
throw StackTrace("In this case the increment cannot be negative");
|
|
||||||
else
|
|
||||||
for (int i = *range1int; i <= *range2int; i += *incrementp)
|
|
||||||
arr.emplace_back(make_shared<Double>(i, env));
|
|
||||||
else
|
|
||||||
if (*incrementp > 0)
|
|
||||||
throw StackTrace("In this case the increment cannot be positive");
|
|
||||||
else
|
|
||||||
for (int i = *range1int; i >= *range2int; i += *incrementp)
|
|
||||||
arr.emplace_back(make_shared<Double>(i, env));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
for (int i = *range1int; i <= *range2int; i++)
|
if (*incdbl > 0 && *range1dbl < *range2dbl)
|
||||||
|
for (double i = *range1dbl; i <= *range2dbl; i += *incdbl)
|
||||||
|
arr.emplace_back(make_shared<Double>(i, env));
|
||||||
|
else if (*range1dbl > *range2dbl && *incdbl < 0)
|
||||||
|
for (double i = *range1dbl; i >= *range2dbl; i += *incdbl)
|
||||||
arr.emplace_back(make_shared<Double>(i, env));
|
arr.emplace_back(make_shared<Double>(i, env));
|
||||||
|
|
||||||
range1 = nullptr;
|
range1 = increment = range2 = nullptr;
|
||||||
increment = nullptr;
|
|
||||||
range2 = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<ExpressionPtr> retval;
|
vector<ExpressionPtr> retval;
|
||||||
|
|
|
@ -70,7 +70,7 @@ using namespace macro;
|
||||||
%left EQUAL_EQUAL NOT_EQUAL
|
%left EQUAL_EQUAL NOT_EQUAL
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
||||||
%nonassoc IN
|
%nonassoc IN
|
||||||
%nonassoc COLON
|
%left COLON
|
||||||
%left UNION
|
%left UNION
|
||||||
%left INTERSECTION
|
%left INTERSECTION
|
||||||
%left PLUS MINUS
|
%left PLUS MINUS
|
||||||
|
@ -88,7 +88,7 @@ using namespace macro;
|
||||||
%type <VariablePtr> symbol
|
%type <VariablePtr> symbol
|
||||||
|
|
||||||
%type <vector<VariablePtr>> comma_name
|
%type <vector<VariablePtr>> comma_name
|
||||||
%type <vector<ExpressionPtr>> comma_expr function_args tuple_comma_expr
|
%type <vector<ExpressionPtr>> comma_expr function_args tuple_comma_expr colon_expr
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
@ -278,6 +278,12 @@ tuple_comma_expr : %empty
|
||||||
{ $1.emplace_back($3); $$ = $1; }
|
{ $1.emplace_back($3); $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
colon_expr : expr COLON expr
|
||||||
|
{ $$ = vector<ExpressionPtr>{$1, $3}; }
|
||||||
|
| colon_expr COLON expr
|
||||||
|
{ $1.emplace_back($3); $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
expr : LPAREN expr RPAREN
|
expr : LPAREN expr RPAREN
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| symbol
|
| symbol
|
||||||
|
@ -292,8 +298,15 @@ expr : LPAREN expr RPAREN
|
||||||
{ $$ = make_shared<Double>($1, driver.env, @$); }
|
{ $$ = make_shared<Double>($1, driver.env, @$); }
|
||||||
| QUOTED_STRING
|
| QUOTED_STRING
|
||||||
{ $$ = make_shared<String>($1, driver.env, @$); }
|
{ $$ = make_shared<String>($1, driver.env, @$); }
|
||||||
| expr COLON expr
|
| colon_expr
|
||||||
{ $$ = make_shared<Array>($1, $3, driver.env, @$); }
|
{
|
||||||
|
if ($1.size() == 2)
|
||||||
|
$$ = make_shared<Array>($1[0], $1[1], driver.env, @$);
|
||||||
|
else if ($1.size() == 3)
|
||||||
|
$$ = make_shared<Array>($1[0], $1[1], $1[2], driver.env, @$);
|
||||||
|
else
|
||||||
|
error(@$, "The colon operator only works with 2 or 3 arguments");
|
||||||
|
}
|
||||||
| LBRACKET comma_expr RBRACKET
|
| LBRACKET comma_expr RBRACKET
|
||||||
{ $$ = make_shared<Array>($2, driver.env, @$); }
|
{ $$ = make_shared<Array>($2, driver.env, @$); }
|
||||||
| symbol LBRACKET comma_expr RBRACKET
|
| symbol LBRACKET comma_expr RBRACKET
|
||||||
|
|
Loading…
Reference in New Issue