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)
|
||||
{
|
||||
DoublePtr range1int = dynamic_pointer_cast<Double>(range1->eval());
|
||||
DoublePtr range2int = dynamic_pointer_cast<Double>(range2->eval());
|
||||
if (!range1int || !range2int)
|
||||
DoublePtr range1dbl = dynamic_pointer_cast<Double>(range1->eval());
|
||||
DoublePtr range2dbl = dynamic_pointer_cast<Double>(range2->eval());
|
||||
if (!range1dbl || !range2dbl)
|
||||
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)
|
||||
{
|
||||
auto incrementp = dynamic_pointer_cast<Double>(increment->eval());
|
||||
if (*incrementp == 0)
|
||||
throw StackTrace("the increment cannot be equal to zero");
|
||||
|
||||
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));
|
||||
incdbl = dynamic_pointer_cast<Double>(increment->eval());
|
||||
if (!incdbl)
|
||||
throw StackTrace("To create an array from a range using the colon operator, "
|
||||
"the increment must evaluate to a double");
|
||||
}
|
||||
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));
|
||||
|
||||
range1 = nullptr;
|
||||
increment = nullptr;
|
||||
range2 = nullptr;
|
||||
range1 = increment = range2 = nullptr;
|
||||
}
|
||||
|
||||
vector<ExpressionPtr> retval;
|
||||
|
|
|
@ -70,7 +70,7 @@ using namespace macro;
|
|||
%left EQUAL_EQUAL NOT_EQUAL
|
||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
||||
%nonassoc IN
|
||||
%nonassoc COLON
|
||||
%left COLON
|
||||
%left UNION
|
||||
%left INTERSECTION
|
||||
%left PLUS MINUS
|
||||
|
@ -88,7 +88,7 @@ using namespace macro;
|
|||
%type <VariablePtr> symbol
|
||||
|
||||
%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; }
|
||||
;
|
||||
|
||||
colon_expr : expr COLON expr
|
||||
{ $$ = vector<ExpressionPtr>{$1, $3}; }
|
||||
| colon_expr COLON expr
|
||||
{ $1.emplace_back($3); $$ = $1; }
|
||||
;
|
||||
|
||||
expr : LPAREN expr RPAREN
|
||||
{ $$ = $2; }
|
||||
| symbol
|
||||
|
@ -292,8 +298,15 @@ expr : LPAREN expr RPAREN
|
|||
{ $$ = make_shared<Double>($1, driver.env, @$); }
|
||||
| QUOTED_STRING
|
||||
{ $$ = make_shared<String>($1, driver.env, @$); }
|
||||
| expr COLON expr
|
||||
{ $$ = make_shared<Array>($1, $3, driver.env, @$); }
|
||||
| colon_expr
|
||||
{
|
||||
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
|
||||
{ $$ = make_shared<Array>($2, driver.env, @$); }
|
||||
| symbol LBRACKET comma_expr RBRACKET
|
||||
|
|
Loading…
Reference in New Issue