/[svn]/linuxsampler/trunk/src/scriptvm/parser.y
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/parser.y

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3580 by schoenebeck, Tue Aug 27 21:36:53 2019 UTC revision 3581 by schoenebeck, Fri Aug 30 11:40:25 2019 UTC
# Line 190  statement: Line 190  statement:
190          } else if (name[0] == '@') {          } else if (name[0] == '@') {
191              context->vartable[name] = new StringVariable(context);              context->vartable[name] = new StringVariable(context);
192          } else if (name[0] == '~') {          } else if (name[0] == '~') {
193              context->vartable[name] = new RealVariable(context);              context->vartable[name] = new RealVariable({
194                    .ctx = context
195                });
196          } else if (name[0] == '$') {          } else if (name[0] == '$') {
197              context->vartable[name] = new IntVariable(context);              context->vartable[name] = new IntVariable({
198                    .ctx = context
199                });
200          } else if (name[0] == '?') {          } else if (name[0] == '?') {
201              PARSE_ERR(@2, (String("Real number array variable '") + name + "' declaration requires array size.").c_str());              PARSE_ERR(@2, (String("Real number array variable '") + name + "' declaration requires array size.").c_str());
202          } else if (name[0] == '%') {          } else if (name[0] == '%') {
# Line 210  statement: Line 214  statement:
214          } else if (name[0] != '$' && name[0] != '~') {          } else if (name[0] != '$' && name[0] != '~') {
215              PARSE_ERR(@3, "Polyphonic variables must only be declared either as integer or real number type.");              PARSE_ERR(@3, "Polyphonic variables must only be declared either as integer or real number type.");
216          } else if (name[0] == '~') {          } else if (name[0] == '~') {
217              context->vartable[name] = new PolyphonicRealVariable(context);              context->vartable[name] = new PolyphonicRealVariable({
218          } else {                  .ctx = context
219              context->vartable[name] = new PolyphonicIntVariable(context);              });
220            } else {
221                context->vartable[name] = new PolyphonicIntVariable({
222                    .ctx = context
223                });
224          }          }
225          $$ = new NoOperation;          $$ = new NoOperation;
226      }      }
# Line 241  statement: Line 249  statement:
249              if (name[0] != '~')              if (name[0] != '~')
250                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());
251              RealExprRef expr = $4;              RealExprRef expr = $4;
252              RealVariableRef var = new RealVariable(context);              RealVariableRef var = new RealVariable({
253                    .ctx = context,
254                    .unitType = expr->unitType(),
255                    .isFinal = expr->isFinal()
256                });
257              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
258                  const vmfloat f = expr->evalReal();                  $$ = new Assignment(var, new RealLiteral({
259                  $$ = new Assignment(var, new RealLiteral(f));                      .value = expr->evalReal(),
260                        .unitFactor = expr->unitFactor(),
261                        .unitType = expr->unitType(),
262                        .isFinal = expr->isFinal()
263                    }));
264              } else {              } else {
265                  $$ = new Assignment(var, expr);                  $$ = new Assignment(var, expr);
266              }              }
             var->copyUnitFrom(expr);  
             var->setFinal(expr->isFinal());  
267              context->vartable[name] = var;              context->vartable[name] = var;
268          } else if ($4->exprType() == INT_EXPR) {          } else if ($4->exprType() == INT_EXPR) {
269              if (name[0] != '$')              if (name[0] != '$')
270                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());
271              IntExprRef expr = $4;              IntExprRef expr = $4;
272              IntVariableRef var = new IntVariable(context);              IntVariableRef var = new IntVariable({
273                    .ctx = context,
274                    .unitType = expr->unitType(),
275                    .isFinal = expr->isFinal()
276                });
277              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
278                  const vmint i = expr->evalInt();                  $$ = new Assignment(var, new IntLiteral({
279                  $$ = new Assignment(var, new IntLiteral(i));                      .value = expr->evalInt(),
280                        .unitFactor = expr->unitFactor(),
281                        .unitType = expr->unitType(),
282                        .isFinal = expr->isFinal()
283                    }));
284              } else {              } else {
285                  $$ = new Assignment(var, expr);                  $$ = new Assignment(var, expr);
286              }              }
             var->copyUnitFrom(expr);  
             var->setFinal(expr->isFinal());  
287              context->vartable[name] = var;              context->vartable[name] = var;
288          } else if ($4->exprType() == EMPTY_EXPR) {          } else if ($4->exprType() == EMPTY_EXPR) {
289              PARSE_ERR(@4, "Expression does not result in a value.");              PARSE_ERR(@4, "Expression does not result in a value.");
# Line 283  statement: Line 303  statement:
303          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
304              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
305          } else {          } else {
306              IntExprRef expr = $4;              IntExprRef sizeExpr = $4;
307              if (expr->unitType() || expr->unitPrefix(0)) {              if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) {
308                  PARSE_ERR(@4, "Units are not allowed as array size.");                  PARSE_ERR(@4, "Units are not allowed as array size.");
309              } else {              } else {
310                  if (expr->isFinal())                  if (sizeExpr->isFinal())
311                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");
312                  vmint size = expr->evalInt();                  vmint size = sizeExpr->evalInt();
313                  if (size <= 0) {                  if (size <= 0) {
314                      PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());                      PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());
315                  } else {                  } else {
# Line 324  statement: Line 344  statement:
344                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
345                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
346                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
347              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {              } else if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) {
348                  PARSE_ERR(@4, "Units are not allowed as array size.");                  PARSE_ERR(@4, "Units are not allowed as array size.");
349              } else {              } else {
350                  if (sizeExpr->isFinal())                  if (sizeExpr->isFinal())
# Line 355  statement: Line 375  statement:
375                              );                              );
376                              argsOK = false;                              argsOK = false;
377                              break;                              break;
378                          } else if (args->arg(i)->asInt()->unitType() ||                          } else if (args->arg(i)->asScalarNumberExpr()->unitType()) {
379                                     args->arg(i)->asInt()->unitPrefix(0))                              PARSE_ERR(
380                          {                                  @8,
381                                    (String("Array variable '") + name +
382                                    "' declared with invalid assignment values. Assigned element " +
383                                    ToString(i+1) + " contains a unit type, only metric prefixes are allowed for arrays.").c_str()
384                                );
385                                argsOK = false;
386                                break;
387                            } else if (args->arg(i)->asScalarNumberExpr()->isFinal()) {
388                              PARSE_ERR(                              PARSE_ERR(
389                                  @8,                                  @8,
390                                  (String("Array variable '") + name +                                  (String("Array variable '") + name +
391                                  "' declared with invalid assignment values. Assigned element " +                                  "' declared with invalid assignment values. Assigned element " +
392                                  ToString(i+1) + " contains a unit.").c_str()                                  ToString(i+1) + " declared as 'final' value.").c_str()
393                              );                              );
394                              argsOK = false;                              argsOK = false;
395                              break;                              break;
# Line 398  statement: Line 425  statement:
425                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
426                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
427                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
428              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {              } else if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) {
429                  PARSE_ERR(@5, "Units are not allowed as array size.");                  PARSE_ERR(@5, "Units are not allowed as array size.");
430              } else {              } else {
431                  if (sizeExpr->isFinal())                  if (sizeExpr->isFinal())
# Line 423  statement: Line 450  statement:
450                          if (args->arg(i)->exprType() != declType) {                          if (args->arg(i)->exprType() != declType) {
451                              PARSE_ERR(                              PARSE_ERR(
452                                  @9,                                  @9,
453                                  (String("Array variable '") + name +                                  (String("const array variable '") + name +
454                                  "' declared with invalid assignment values. Assigned element " +                                  "' declared with invalid assignment values. Assigned element " +
455                                  ToString(i+1) + " is not an " + typeStr(declType) + " expression.").c_str()                                  ToString(i+1) + " is not an " + typeStr(declType) + " expression.").c_str()
456                              );                              );
# Line 439  statement: Line 466  statement:
466                              );                              );
467                              argsOK = false;                              argsOK = false;
468                              break;                              break;
469                          } else if (args->arg(i)->asInt()->unitType() ||                          } else if (args->arg(i)->asScalarNumberExpr()->unitType()) {
470                                     args->arg(i)->asInt()->unitPrefix(0))                              PARSE_ERR(
471                          {                                  @9,
472                                    (String("const array variable '") + name +
473                                    "' declared with invalid assignment values. Assigned element " +
474                                    ToString(i+1) + " contains a unit type, only metric prefixes are allowed for arrays.").c_str()
475                                );
476                                argsOK = false;
477                                break;
478                            } else if (args->arg(i)->asScalarNumberExpr()->isFinal()) {
479                              PARSE_ERR(                              PARSE_ERR(
480                                  @9,                                  @9,
481                                  (String("const array variable '") + name +                                  (String("const array variable '") + name +
482                                  "' declared with invalid assignment values. Assigned element " +                                  "' declared with invalid assignment values. Assigned element " +
483                                  ToString(i+1) + " contains a unit.").c_str()                                  ToString(i+1) + " declared as 'final' value.").c_str()
484                              );                              );
485                              argsOK = false;                              argsOK = false;
486                              break;                              break;
# Line 481  statement: Line 515  statement:
515          } else if ($5->exprType() == REAL_EXPR) {          } else if ($5->exprType() == REAL_EXPR) {
516              if (name[0] != '~')              if (name[0] != '~')
517                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());
             vmfloat f = 0;  
518              RealExprRef expr = $5;              RealExprRef expr = $5;
519              if (expr->isConstExpr())              if (!expr->isConstExpr()) {
                 f = expr->evalReal();  
             else  
520                  PARSE_ERR(@5, (String("Assignment to const real number variable '") + name + "' requires const expression.").c_str());                  PARSE_ERR(@5, (String("Assignment to const real number variable '") + name + "' requires const expression.").c_str());
521              ConstRealVariableRef var = new ConstRealVariable(f);              }
522              var->copyUnitFrom(expr);              ConstRealVariableRef var = new ConstRealVariable({
523              var->setFinal(expr->isFinal());                  .value = (expr->isConstExpr()) ? expr->evalReal() : vmfloat(0),
524                    .unitFactor = (expr->isConstExpr()) ? expr->unitFactor() : VM_NO_FACTOR,
525                    .unitType = expr->unitType(),
526                    .isFinal = expr->isFinal()
527                });
528              context->vartable[name] = var;              context->vartable[name] = var;
529              //$$ = new Assignment(var, new IntLiteral(i));              //$$ = new Assignment(var, new IntLiteral(i));
530          } else if ($5->exprType() == INT_EXPR) {          } else if ($5->exprType() == INT_EXPR) {
531              if (name[0] != '$')              if (name[0] != '$')
532                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());
             vmint i = 0;  
533              IntExprRef expr = $5;              IntExprRef expr = $5;
534              if (expr->isConstExpr())              if (!expr->isConstExpr()) {
                 i = expr->evalInt();  
             else  
535                  PARSE_ERR(@5, (String("Assignment to const integer variable '") + name + "' requires const expression.").c_str());                  PARSE_ERR(@5, (String("Assignment to const integer variable '") + name + "' requires const expression.").c_str());
536              ConstIntVariableRef var = new ConstIntVariable(i);              }
537              var->copyUnitFrom(expr);              ConstIntVariableRef var = new ConstIntVariable({
538              var->setFinal(expr->isFinal());                  .value = (expr->isConstExpr()) ? expr->evalInt() : 0,
539                    .unitFactor = (expr->isConstExpr()) ? expr->unitFactor() : VM_NO_FACTOR,
540                    .unitType = expr->unitType(),
541                    .isFinal = expr->isFinal()
542                });
543              context->vartable[name] = var;              context->vartable[name] = var;
544              //$$ = new Assignment(var, new IntLiteral(i));              //$$ = new Assignment(var, new IntLiteral(i));
545          } else if ($5->exprType() == EMPTY_EXPR) {          } else if ($5->exprType() == EMPTY_EXPR) {
# Line 519  statement: Line 555  statement:
555      | WHILE '(' expr ')' opt_statements END WHILE  {      | WHILE '(' expr ')' opt_statements END WHILE  {
556          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
557              IntExprRef expr = $3;              IntExprRef expr = $3;
558              if (expr->isFinal() && expr->isConstExpr())              if (expr->asScalarNumberExpr()->unitType() ||
559                    expr->asScalarNumberExpr()->hasUnitFactorEver())
560                    PARSE_WRN(@3, "Condition for 'while' loops contains a unit.");
561                else if (expr->isFinal() && expr->isConstExpr())
562                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");
563              $$ = new While(expr, $5);              $$ = new While(expr, $5);
564          } else {          } else {
565              PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");              PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");
566              $$ = new While(new IntLiteral(0), $5);              $$ = new While(new IntLiteral({ .value = 0 }), $5);
567          }          }
568      }      }
569      | SYNCHRONIZED opt_statements END SYNCHRONIZED  {      | SYNCHRONIZED opt_statements END SYNCHRONIZED  {
# Line 533  statement: Line 572  statement:
572      | IF '(' expr ')' opt_statements ELSE opt_statements END IF  {      | IF '(' expr ')' opt_statements ELSE opt_statements END IF  {
573          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
574              IntExprRef expr = $3;              IntExprRef expr = $3;
575              if (expr->isFinal() && expr->isConstExpr())              if (expr->asScalarNumberExpr()->unitType() ||
576                    expr->asScalarNumberExpr()->hasUnitFactorEver())
577                    PARSE_WRN(@3, "Condition for 'if' contains a unit.");
578                else if (expr->isFinal() && expr->isConstExpr())
579                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");
580              $$ = new If($3, $5, $7);              $$ = new If($3, $5, $7);
581          } else {          } else {
582              PARSE_ERR(@3, "Condition for 'if' must be integer expression.");              PARSE_ERR(@3, "Condition for 'if' must be integer expression.");
583              $$ = new If(new IntLiteral(0), $5, $7);              $$ = new If(new IntLiteral({ .value = 0 }), $5, $7);
584          }          }
585      }      }
586      | IF '(' expr ')' opt_statements END IF  {      | IF '(' expr ')' opt_statements END IF  {
587          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
588              IntExprRef expr = $3;              IntExprRef expr = $3;
589              if (expr->isFinal() && expr->isConstExpr())              if (expr->asScalarNumberExpr()->unitType() ||
590                    expr->asScalarNumberExpr()->hasUnitFactorEver())
591                    PARSE_WRN(@3, "Condition for 'if' contains a unit.");
592                else if (expr->isFinal() && expr->isConstExpr())
593                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");
594              $$ = new If($3, $5);              $$ = new If($3, $5);
595          } else {          } else {
596              PARSE_ERR(@3, "Condition for 'if' must be integer expression.");              PARSE_ERR(@3, "Condition for 'if' must be integer expression.");
597              $$ = new If(new IntLiteral(0), $5);              $$ = new If(new IntLiteral({ .value = 0 }), $5);
598          }          }
599      }      }
600      | SELECT expr caseclauses END SELECT  {      | SELECT expr caseclauses END SELECT  {
601          if ($2->exprType() == INT_EXPR) {          if ($2->exprType() == INT_EXPR) {
602              IntExprRef expr = $2;              IntExprRef expr = $2;
603              if (expr->unitType() || expr->unitPrefix(0)) {              if (expr->unitType() || expr->hasUnitFactorEver()) {
604                  PARSE_ERR(@2, "Units are not allowed here.");                  PARSE_ERR(@2, "Units are not allowed here.");
605                    $$ = new SelectCase(new IntLiteral({ .value = 0 }), $3);
606              } else {              } else {
607                  if (expr->isFinal() && expr->isConstExpr())                  if (expr->isFinal() && expr->isConstExpr())
608                      PARSE_WRN(@2, "Final operator '!' is meaningless here.");                      PARSE_WRN(@2, "Final operator '!' is meaningless here.");
# Line 564  statement: Line 610  statement:
610              }              }
611          } else {          } else {
612              PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");              PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");
613              $$ = new SelectCase(new IntLiteral(0), $3);              $$ = new SelectCase(new IntLiteral({ .value = 0 }), $3);
614          }          }
615      }      }
616    
# Line 581  caseclauses: Line 627  caseclauses:
627  caseclause:  caseclause:
628      CASE INTEGER opt_statements  {      CASE INTEGER opt_statements  {
629          $$ = CaseBranch();          $$ = CaseBranch();
630          $$.from = new IntLiteral($2);          $$.from = new IntLiteral({ .value = $2 });
631          $$.statements = $3;          $$.statements = $3;
632      }      }
633      | CASE INTEGER TO INTEGER opt_statements  {      | CASE INTEGER TO INTEGER opt_statements  {
634          $$ = CaseBranch();          $$ = CaseBranch();
635          $$.from = new IntLiteral($2);          $$.from = new IntLiteral({ .value = $2 });
636          $$.to   = new IntLiteral($4);          $$.to   = new IntLiteral({ .value = $4 });
637          $$.statements = $5;          $$.statements = $5;
638      }      }
639    
# Line 645  functioncall: Line 691  functioncall:
691                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects a unit.").c_str());                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects a unit.").c_str());
692                      argsOK = false;                      argsOK = false;
693                      break;                      break;
694                  } else if (isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->unitPrefix(0) && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asScalarNumberExpr()->unitType())) {                  } else if (isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->hasUnitFactorEver() && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asScalarNumberExpr()->unitType())) {
695                      if (args->arg(i)->asScalarNumberExpr()->unitType())                      if (args->arg(i)->asScalarNumberExpr()->unitType())
696                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix for unit" + unitTypeStr(args->arg(i)->asScalarNumberExpr()->unitType()) + ".").c_str());                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix for unit" + unitTypeStr(args->arg(i)->asScalarNumberExpr()->unitType()) + ".").c_str());
697                      else                      else
# Line 658  functioncall: Line 704  functioncall:
704                      break;                      break;
705                  }                  }
706              }              }
707                if (argsOK) {
708                    // perform built-in function's own, custom arguments checks (if any)
709                    fn->checkArgs(&*args, [&](String err) {
710                        PARSE_ERR(@3, (String("Built-in function '") + name + "()': " + err).c_str());
711                        argsOK = false;
712                    }, [&](String wrn) {
713                        PARSE_WRN(@3, (String("Built-in function '") + name + "()': " + wrn).c_str());
714                    });
715                }
716              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);
717          }          }
718      }      }
# Line 735  assignment: Line 790  assignment:
790              ScalarNumberExprRef expr = $3;              ScalarNumberExprRef expr = $3;
791              if (numberVar->unitType() != expr->unitType())              if (numberVar->unitType() != expr->unitType())
792                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has unit type " + unitTypeStr(numberVar->unitType()) + ", assignment has unit type " + unitTypeStr(expr->unitType()) + " though.").c_str());                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has unit type " + unitTypeStr(numberVar->unitType()) + ", assignment has unit type " + unitTypeStr(expr->unitType()) + " though.").c_str());
             else if (numberVar->unitFactor() != expr->unitFactor())  
                 PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has a different unit prefix.").c_str());  
793              else if (numberVar->isFinal() != expr->isFinal())              else if (numberVar->isFinal() != expr->isFinal())
794                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' was declared as " + String(numberVar->isFinal() ? "final" : "not final") + ", assignment is " + String(expr->isFinal() ? "final" : "not final") + " though.").c_str());                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' was declared as " + String(numberVar->isFinal() ? "final" : "not final") + ", assignment is " + String(expr->isFinal() ? "final" : "not final") + " though.").c_str());
795          }          }
# Line 777  assignment: Line 830  assignment:
830              RealArrayElementRef element = new RealArrayElement(var, $3);              RealArrayElementRef element = new RealArrayElement(var, $3);
831              $$ = new Assignment(element, $6);              $$ = new Assignment(element, $6);
832          } else {          } else {
833              $$ = new NoOperation;              $$ = new NoOperation; // actually not possible to ever get here
834          }          }
835      }      }
836    
837  unary_expr:  unary_expr:
838      INTEGER  {      INTEGER  {
839          $$ = new IntLiteral($1);          $$ = new IntLiteral({ .value = $1 });
840      }      }
841      | REAL  {      | REAL  {
842          $$ = new RealLiteral($1);          $$ = new RealLiteral({ .value = $1 });
843      }      }
844      | INTEGER_UNIT  {      | INTEGER_UNIT  {
845          IntLiteralRef literal = new IntLiteral($1.iValue);          IntLiteralRef literal = new IntLiteral({
846          literal->setUnit($1.prefix, $1.unit);              .value = $1.iValue,
847                .unitFactor = VMUnit::unitFactor($1.prefix),
848                .unitType = $1.unit
849            });
850          $$ = literal;          $$ = literal;
851      }      }
852      | REAL_UNIT  {      | REAL_UNIT  {
853          RealLiteralRef literal = new RealLiteral($1.fValue);          RealLiteralRef literal = new RealLiteral({
854          literal->setUnit($1.prefix, $1.unit);              .value = $1.fValue,
855                .unitFactor = VMUnit::unitFactor($1.prefix),
856                .unitType = $1.unit
857            });
858          $$ = literal;          $$ = literal;
859      }      }
860      | STRING    {      | STRING    {
# Line 808  unary_expr: Line 867  unary_expr:
867              $$ = var;              $$ = var;
868          else {          else {
869              PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
870              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
871          }          }
872      }      }
873      | VARIABLE '[' expr ']'  {      | VARIABLE '[' expr ']'  {
# Line 816  unary_expr: Line 875  unary_expr:
875          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
876          if (!var) {          if (!var) {
877              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
878              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
879          } else if (!isArray(var->exprType())) {          } else if (!isArray(var->exprType())) {
880              PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());              PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
881              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
882          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
883              PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());              PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str());
884              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
885          } else if ($3->asInt()->unitType() || $3->asInt()->unitPrefix(0)) {          } else if ($3->asInt()->unitType() || $3->asInt()->hasUnitFactorEver()) {
886              PARSE_ERR(@3, "Units are not allowed as array index.");              PARSE_ERR(@3, "Units are not allowed as array index.");
887              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
888          } else {          } else {
889              if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((ArrayExprRef)var)->arraySize())              if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((ArrayExprRef)var)->arraySize())
890                  PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +                  PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +
# Line 853  unary_expr: Line 912  unary_expr:
912      | BITWISE_NOT unary_expr  {      | BITWISE_NOT unary_expr  {
913          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
914              PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());              PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
915              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
916          } else if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) {          } else if ($2->asInt()->unitType() || $2->asInt()->hasUnitFactorEver()) {
917              PARSE_ERR(@2, "Units are not allowed for operands of bitwise operations.");              PARSE_ERR(@2, "Units are not allowed for operands of bitwise operations.");
918              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
919          } else {          } else {
920              $$ = new BitwiseNot($2);              $$ = new BitwiseNot($2);
921          }          }
# Line 864  unary_expr: Line 923  unary_expr:
923      | NOT unary_expr  {      | NOT unary_expr  {
924          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
925              PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());              PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
926              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
927          } else if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) {          } else if ($2->asInt()->unitType() || $2->asInt()->hasUnitFactorEver()) {
928              PARSE_ERR(@2, "Units are not allowed for operands of logical operations.");              PARSE_ERR(@2, "Units are not allowed for operands of logical operations.");
929              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
930          } else {          } else {
931              $$ = new Not($2);              $$ = new Not($2);
932          }          }
# Line 875  unary_expr: Line 934  unary_expr:
934      | '!' unary_expr  {      | '!' unary_expr  {
935          if (!isScalarNumber($2->exprType())) {          if (!isScalarNumber($2->exprType())) {
936              PARSE_ERR(@2, (String("Right operand of \"final\" operator '!' must be a scalar number expression, is ") + typeStr($2->exprType()) + " though.").c_str());              PARSE_ERR(@2, (String("Right operand of \"final\" operator '!' must be a scalar number expression, is ") + typeStr($2->exprType()) + " though.").c_str());
937              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
938          } else {          } else {
939              $$ = new Final($2);              $$ = new Final($2);
940          }          }
# Line 905  logical_or_expr: Line 964  logical_or_expr:
964          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
965          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
966              PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
967              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
968          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
969              PARSE_ERR(@3, (String("Right operand of operator 'or' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator 'or' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
970              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
971          } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {          } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) {
972              PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");              PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");
973              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
974          } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {          } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) {
975              PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");              PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");
976              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
977          } else {          } else {
978                if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal())
979                    PARSE_WRN(@3, "Right operand of 'or' operation is not 'final', result will be 'final' though since left operand is 'final'.");
980                else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal())
981                    PARSE_WRN(@1, "Left operand of 'or' operation is not 'final', result will be 'final' though since right operand is 'final'.");
982              $$ = new Or(lhs, rhs);              $$ = new Or(lhs, rhs);
983          }          }
984      }      }
# Line 929  logical_and_expr: Line 992  logical_and_expr:
992          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
993          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
994              PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
995              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
996          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
997              PARSE_ERR(@3, (String("Right operand of operator 'and' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator 'and' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
998              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
999          } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {          } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) {
1000              PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");              PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");
1001              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1002          } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {          } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) {
1003              PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");              PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");
1004              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1005          } else {          } else {
1006                if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal())
1007                    PARSE_WRN(@3, "Right operand of 'and' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1008                else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal())
1009                    PARSE_WRN(@1, "Left operand of 'and' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1010              $$ = new And(lhs, rhs);              $$ = new And(lhs, rhs);
1011          }          }
1012      }      }
# Line 951  bitwise_or_expr: Line 1018  bitwise_or_expr:
1018          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1019          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
1020              PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1021              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1022          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1023              PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1024              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1025          } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {          } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) {
1026              PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");              PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");
1027              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1028          } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {          } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) {
1029              PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");              PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");
1030              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1031          } else {          } else {
1032                if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal())
1033                    PARSE_WRN(@3, "Right operand of '.or.' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1034                else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal())
1035                    PARSE_WRN(@1, "Left operand of '.or.' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1036              $$ = new BitwiseOr(lhs, rhs);              $$ = new BitwiseOr(lhs, rhs);
1037          }          }
1038      }      }
# Line 975  bitwise_and_expr: Line 1046  bitwise_and_expr:
1046          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1047          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
1048              PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1049              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1050          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1051              PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1052              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1053          } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {          } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) {
1054              PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");              PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");
1055              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1056          } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {          } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) {
1057              PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");              PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");
1058              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1059          } else {          } else {
1060                if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal())
1061                    PARSE_WRN(@3, "Right operand of '.and.' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1062                else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal())
1063                    PARSE_WRN(@1, "Left operand of '.and.' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1064              $$ = new BitwiseAnd(lhs, rhs);              $$ = new BitwiseAnd(lhs, rhs);
1065          }          }
1066      }      }
# Line 997  rel_expr: Line 1072  rel_expr:
1072          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1073          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1074              PARSE_ERR(@1, (String("Left operand of operator '<' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '<' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1075              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1076          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1077              PARSE_ERR(@3, (String("Right operand of operator '<' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '<' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1078              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1079          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1080                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1081          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1082              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1083              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1084          } else {          } else {
1085                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1086                    PARSE_WRN(@3, "Right operand of '<' comparison is not 'final', left operand is 'final' though.");
1087                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1088                    PARSE_WRN(@1, "Left operand of '<' comparison is not 'final', right operand is 'final' though.");
1089              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
1090          }          }
1091      }      }
# Line 1015  rel_expr: Line 1094  rel_expr:
1094          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1095          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1096              PARSE_ERR(@1, (String("Left operand of operator '>' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '>' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1097              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1098          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1099              PARSE_ERR(@3, (String("Right operand of operator '>' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '>' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1100              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1101          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1102                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1103          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1104              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1105              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1106          } else {          } else {
1107                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1108                    PARSE_WRN(@3, "Right operand of '>' comparison is not 'final', left operand is 'final' though.");
1109                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1110                    PARSE_WRN(@1, "Left operand of '>' comparison is not 'final', right operand is 'final' though.");
1111              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
1112          }          }
1113      }      }
# Line 1033  rel_expr: Line 1116  rel_expr:
1116          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1117          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1118              PARSE_ERR(@1, (String("Left operand of operator '<=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '<=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1119              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1120          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1121              PARSE_ERR(@3, (String("Right operand of operator '<=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '<=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1122              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1123          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1124                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1125          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1126              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1127              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1128          } else {          } else {
1129                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1130                    PARSE_WRN(@3, "Right operand of '<=' comparison is not 'final', left operand is 'final' though.");
1131                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1132                    PARSE_WRN(@1, "Left operand of '<=' comparison is not 'final', right operand is 'final' though.");
1133              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
1134          }          }
1135      }      }
# Line 1051  rel_expr: Line 1138  rel_expr:
1138          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1139          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1140              PARSE_ERR(@1, (String("Left operand of operator '>=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '>=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1141              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1142          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1143              PARSE_ERR(@3, (String("Right operand of operator '>=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '>=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1144              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1145          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1146                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1147          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1148              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1149              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1150          } else {          } else {
1151                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1152                    PARSE_WRN(@3, "Right operand of '>=' comparison is not 'final', left operand is 'final' though.");
1153                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1154                    PARSE_WRN(@1, "Left operand of '>=' comparison is not 'final', right operand is 'final' though.");
1155              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
1156          }          }
1157      }      }
# Line 1069  rel_expr: Line 1160  rel_expr:
1160          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1161          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1162              PARSE_ERR(@1, (String("Left operand of operator '=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1163              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1164          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1165              PARSE_ERR(@3, (String("Right operand of operator '=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1166              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1167          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1168                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1169          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1170              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1171              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1172          } else {          } else {
1173                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1174                    PARSE_WRN(@3, "Right operand of '=' comparison is not 'final', left operand is 'final' though.");
1175                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1176                    PARSE_WRN(@1, "Left operand of '=' comparison is not 'final', right operand is 'final' though.");
1177              $$ = new Relation(lhs, Relation::EQUAL, rhs);              $$ = new Relation(lhs, Relation::EQUAL, rhs);
1178          }          }
1179      }      }
# Line 1087  rel_expr: Line 1182  rel_expr:
1182          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1183          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1184              PARSE_ERR(@1, (String("Left operand of operator '#' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '#' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1185              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1186          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1187              PARSE_ERR(@3, (String("Right operand of operator '#' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of operator '#' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1188              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1189          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1190                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") +
1191          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1192              PARSE_ERR(@2, "Operands of relative operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1193              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1194          } else {          } else {
1195                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1196                    PARSE_WRN(@3, "Right operand of '#' comparison is not 'final', left operand is 'final' though.");
1197                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1198                    PARSE_WRN(@1, "Left operand of '#' comparison is not 'final', right operand is 'final' though.");
1199              $$ = new Relation(lhs, Relation::NOT_EQUAL, rhs);              $$ = new Relation(lhs, Relation::NOT_EQUAL, rhs);
1200          }          }
1201      }      }
# Line 1108  add_expr: Line 1207  add_expr:
1207          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1208          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1209              PARSE_ERR(@1, (String("Left operand of operator '+' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '+' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1210              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1211          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1212              PARSE_ERR(@1, (String("Right operand of operator '+' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Right operand of operator '+' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1213              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1214          } else if (lhs->exprType() != rhs->exprType()) {          } else if (lhs->exprType() != rhs->exprType()) {
1215              PARSE_ERR(@2, (String("Operands of operator '+' must have same type; left operand is ") +              PARSE_ERR(@2, (String("Operands of operator '+' must have same type; left operand is ") +
1216                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1217              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1218          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1219                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of '+' operations must have same unit, left operand is ") +
1220          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1221              PARSE_ERR(@2, "Operands of '+' operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1222              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1223          } else {          } else {
1224                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1225                    PARSE_WRN(@3, "Right operand of '+' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1226                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1227                    PARSE_WRN(@1, "Left operand of '+' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1228              $$ = new Add(lhs,rhs);              $$ = new Add(lhs,rhs);
1229          }          }
1230      }      }
# Line 1130  add_expr: Line 1233  add_expr:
1233          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1234          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1235              PARSE_ERR(@1, (String("Left operand of operator '-' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '-' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1236              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1237          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1238              PARSE_ERR(@1, (String("Right operand of operator '-' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Right operand of operator '-' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1239              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1240          } else if (lhs->exprType() != rhs->exprType()) {          } else if (lhs->exprType() != rhs->exprType()) {
1241              PARSE_ERR(@2, (String("Operands of operator '-' must have same type; left operand is ") +              PARSE_ERR(@2, (String("Operands of operator '-' must have same type; left operand is ") +
1242                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1243              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1244          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) {
1245                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())              PARSE_ERR(@2, (String("Operands of '-' operations must have same unit, left operand is ") +
1246          {                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1247              PARSE_ERR(@2, "Operands of '-' operations must have same unit.");                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1248              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1249          } else {          } else {
1250                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1251                    PARSE_WRN(@3, "Right operand of '-' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1252                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1253                    PARSE_WRN(@1, "Left operand of '-' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1254              $$ = new Sub(lhs,rhs);              $$ = new Sub(lhs,rhs);
1255          }          }
1256      }      }
# Line 1155  mul_expr: Line 1262  mul_expr:
1262          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1263          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1264              PARSE_ERR(@1, (String("Left operand of operator '*' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '*' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1265              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1266          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1267              PARSE_ERR(@1, (String("Right operand of operator '*' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Right operand of operator '*' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1268              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1269          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {
1270              PARSE_ERR(@2, "Only one operand of operator '*' may have a unit type");              PARSE_ERR(@2, (String("Only one operand of operator '*' may have a unit type, left operand is ") +
1271              $$ = new IntLiteral(0);                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1272                    unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1273                $$ = new IntLiteral({ .value = 0 });
1274          } else if (lhs->exprType() != rhs->exprType()) {          } else if (lhs->exprType() != rhs->exprType()) {
1275              PARSE_ERR(@2, (String("Operands of operator '*' must have same type; left operand is ") +              PARSE_ERR(@2, (String("Operands of operator '*' must have same type; left operand is ") +
1276                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1277              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
         } else if (lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0)) {  
             PARSE_ERR(@2, "Only one operand of operator '*' may have a unit prefix");  
             $$ = new IntLiteral(0);  
1278          } else {          } else {
1279                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1280                    PARSE_WRN(@3, "Right operand of '*' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1281                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1282                    PARSE_WRN(@1, "Left operand of '*' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1283              $$ = new Mul(lhs,rhs);              $$ = new Mul(lhs,rhs);
1284          }          }
1285      }      }
# Line 1178  mul_expr: Line 1288  mul_expr:
1288          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1289          if (!isScalarNumber(lhs->exprType())) {          if (!isScalarNumber(lhs->exprType())) {
1290              PARSE_ERR(@1, (String("Left operand of operator '/' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator '/' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1291              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1292          } else if (!isScalarNumber(rhs->exprType())) {          } else if (!isScalarNumber(rhs->exprType())) {
1293              PARSE_ERR(@1, (String("Right operand of operator '/' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Right operand of operator '/' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1294              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1295          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType() &&          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType() &&
1296                     lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType())                     lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType())
1297          {          {
1298              PARSE_ERR(@2, "Operands of operator '/' with two different unit types.");              PARSE_ERR(@2, (String("Operands of operator '/' with two different unit types, left operand is ") +
1299              $$ = new IntLiteral(0);                  unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " +
1300                    unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str());
1301                $$ = new IntLiteral({ .value = 0 });
1302          } else if (!lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {          } else if (!lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {
1303              PARSE_ERR(@3, ("Dividing left operand without any unit type by right operand with unit type " + typeStr(rhs->exprType()) + " is not possible.").c_str());              PARSE_ERR(@3, ("Dividing left operand without any unit type by right operand with unit type (" +
1304              $$ = new IntLiteral(0);                  unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + ") is not possible.").c_str());
1305          } else if (lhs->asScalarNumberExpr()->unitFactor()  != rhs->asScalarNumberExpr()->unitFactor() &&              $$ = new IntLiteral({ .value = 0 });
                    lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0))  
         {  
             PARSE_ERR(@2, "Dividing two operands with two different unit prefixes is not possible.");  
             $$ = new IntLiteral(0);  
         } else if (lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor() &&  
                    rhs->asScalarNumberExpr()->unitPrefix(0))  
         {  
             PARSE_ERR(@3, "Dividing left operand without any unit prefix by right operand with unit prefix is not possible.");  
             $$ = new IntLiteral(0);  
1306          } else if (lhs->exprType() != rhs->exprType()) {          } else if (lhs->exprType() != rhs->exprType()) {
1307              PARSE_ERR(@2, (String("Operands of operator '/' must have same type; left operand is ") +              PARSE_ERR(@2, (String("Operands of operator '/' must have same type; left operand is ") +
1308                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());                        typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1309              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1310          } else {          } else {
1311                if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal())
1312                    PARSE_WRN(@3, "Right operand of '/' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1313                else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal())
1314                    PARSE_WRN(@1, "Left operand of '/' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1315              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
1316          }          }
1317      }      }
# Line 1213  mul_expr: Line 1320  mul_expr:
1320          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1321          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
1322              PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
1323              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1324          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1325              PARSE_ERR(@3, (String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1326              $$ = new IntLiteral(0);              $$ = new IntLiteral({ .value = 0 });
1327          } else {          } else {
1328              if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0))              if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver())
1329                  PARSE_ERR(@1, "Operands of modulo operator must not use any unit.");                  PARSE_ERR(@1, "Operands of modulo operator must not use any unit.");
1330              if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0))              if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver())
1331                  PARSE_ERR(@3, "Operands of modulo operator must not use any unit.");                  PARSE_ERR(@3, "Operands of modulo operator must not use any unit.");
1332                if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal())
1333                    PARSE_WRN(@3, "Right operand of 'mod' operation is not 'final', result will be 'final' though since left operand is 'final'.");
1334                else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal())
1335                    PARSE_WRN(@1, "Left operand of 'mod' operation is not 'final', result will be 'final' though since right operand is 'final'.");
1336              $$ = new Mod(lhs,rhs);              $$ = new Mod(lhs,rhs);
1337          }          }
1338      }      }

Legend:
Removed from v.3580  
changed lines
  Added in v.3581

  ViewVC Help
Powered by ViewVC