/[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 3564 by schoenebeck, Sat Aug 24 09:18:57 2019 UTC revision 3573 by schoenebeck, Tue Aug 27 21:36:53 2019 UTC
# Line 39  Line 39 
39  %error-verbose  %error-verbose
40    
41  %token <iValue> INTEGER "integer literal"  %token <iValue> INTEGER "integer literal"
42    %token <fValue> REAL "real number literal"
43  %token <iUnitValue> INTEGER_UNIT "integer literal with unit"  %token <iUnitValue> INTEGER_UNIT "integer literal with unit"
44    %token <fUnitValue> REAL_UNIT "real number literal with unit"
45  %token <sValue> STRING "string literal"  %token <sValue> STRING "string literal"
46  %token <sValue> IDENTIFIER "function name"  %token <sValue> IDENTIFIER "function name"
47  %token <sValue> VARIABLE "variable name"  %token <sValue> VARIABLE "variable name"
# Line 183  statement: Line 185  statement:
185      | DECLARE VARIABLE  {      | DECLARE VARIABLE  {
186          const char* name = $2;          const char* name = $2;
187          //printf("declared var '%s'\n", name);          //printf("declared var '%s'\n", name);
188          if (context->variableByName(name))          if (context->variableByName(name)) {
189              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
190          if (name[0] == '@') {          } else if (name[0] == '@') {
191              context->vartable[name] = new StringVariable(context);              context->vartable[name] = new StringVariable(context);
192              $$ = new NoOperation;          } else if (name[0] == '~') {
193          } else {              context->vartable[name] = new RealVariable(context);
194            } else if (name[0] == '$') {
195              context->vartable[name] = new IntVariable(context);              context->vartable[name] = new IntVariable(context);
196              $$ = new NoOperation;          } else if (name[0] == '?') {
197                PARSE_ERR(@2, (String("Real number array variable '") + name + "' declaration requires array size.").c_str());
198            } else if (name[0] == '%') {
199                PARSE_ERR(@2, (String("Integer array variable '") + name + "' declaration requires array size.").c_str());
200            } else {
201                PARSE_ERR(@2, (String("Variable '") + name + "' declared with unknown type.").c_str());
202          }          }
203            $$ = new NoOperation;
204      }      }
205      | DECLARE POLYPHONIC VARIABLE  {      | DECLARE POLYPHONIC VARIABLE  {
206          const char* name = $3;          const char* name = $3;
207          //printf("declared polyphonic var '%s'\n", name);          //printf("declared polyphonic var '%s'\n", name);
208          if (context->variableByName(name))          if (context->variableByName(name)) {
209              PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());
210          if (name[0] != '$') {          } else if (name[0] != '$' && name[0] != '~') {
211              PARSE_ERR(@3, "Polyphonic variables may only be declared as integers.");              PARSE_ERR(@3, "Polyphonic variables must only be declared either as integer or real number type.");
212              $$ = new FunctionCall("nothing", new Args, NULL); // whatever          } else if (name[0] == '~') {
213                context->vartable[name] = new PolyphonicRealVariable(context);
214          } else {          } else {
215              context->vartable[name] = new PolyphonicIntVariable(context);              context->vartable[name] = new PolyphonicIntVariable(context);
             $$ = new NoOperation;  
216          }          }
217            $$ = new NoOperation;
218      }      }
219      | DECLARE VARIABLE ASSIGNMENT expr  {      | DECLARE VARIABLE ASSIGNMENT expr  {
220          const char* name = $2;          const char* name = $2;
221          //printf("declared assign var '%s'\n", name);          //printf("declared assign var '%s'\n", name);
222          if (context->variableByName(name))          const ExprType_t declType = exprTypeOfVarName(name);
223            if (context->variableByName(name)) {
224              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
225          if ($4->exprType() == STRING_EXPR) {              $$ = new NoOperation;
226              if (name[0] == '$')          } else if ($4->exprType() == STRING_EXPR) {
227                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as integer, string expression assigned though.").c_str());              if (name[0] != '@')
228                    PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", string expression assigned though.").c_str());
229              StringExprRef expr = $4;              StringExprRef expr = $4;
230              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
231                  const String s = expr->evalStr();                  const String s = expr->evalStr();
# Line 225  statement: Line 237  statement:
237                  context->vartable[name] = var;                  context->vartable[name] = var;
238                  $$ = new Assignment(var, expr);                  $$ = new Assignment(var, expr);
239              }              }
240          } else {          } else if ($4->exprType() == REAL_EXPR) {
241              if (name[0] == '@')              if (name[0] != '~')
242                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as string, integer expression assigned though.").c_str());                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());
243                RealExprRef expr = $4;
244                RealVariableRef var = new RealVariable(context);
245                if (expr->isConstExpr()) {
246                    const vmfloat f = expr->evalReal();
247                    $$ = new Assignment(var, new RealLiteral(f));
248                } else {
249                    $$ = new Assignment(var, expr);
250                }
251                var->copyUnitFrom(expr);
252                var->setFinal(expr->isFinal());
253                context->vartable[name] = var;
254            } else if ($4->exprType() == INT_EXPR) {
255                if (name[0] != '$')
256                    PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());
257              IntExprRef expr = $4;              IntExprRef expr = $4;
258              IntVariableRef var = new IntVariable(context);              IntVariableRef var = new IntVariable(context);
259              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
# Line 239  statement: Line 265  statement:
265              var->copyUnitFrom(expr);              var->copyUnitFrom(expr);
266              var->setFinal(expr->isFinal());              var->setFinal(expr->isFinal());
267              context->vartable[name] = var;              context->vartable[name] = var;
268            } else if ($4->exprType() == EMPTY_EXPR) {
269                PARSE_ERR(@4, "Expression does not result in a value.");
270                $$ = new NoOperation;
271            } else if (isArray($4->exprType())) {
272                PARSE_ERR(@2, (String("Variable '") + name + "' declared as scalar type, array expression assigned though.").c_str());
273                $$ = new NoOperation;
274          }          }
275      }      }
276      | DECLARE VARIABLE '[' expr ']'  {      | DECLARE VARIABLE '[' expr ']'  {
# Line 246  statement: Line 278  statement:
278          const char* name = $2;          const char* name = $2;
279          if (!$4->isConstExpr()) {          if (!$4->isConstExpr()) {
280              PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());              PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
281          } else if ($4->exprType() != INT_EXPR) {          } else if ($4->exprType() != INT_EXPR) {
282              PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());              PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
283          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
284              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
285          } else {          } else {
286              IntExprRef expr = $4;              IntExprRef expr = $4;
287              if (expr->unitType() || expr->unitPrefix(0)) {              if (expr->unitType() || expr->unitPrefix(0)) {
288                  PARSE_ERR(@4, "Units are not allowed as array size.");                  PARSE_ERR(@4, "Units are not allowed as array size.");
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
289              } else {              } else {
290                  if (expr->isFinal())                  if (expr->isFinal())
291                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");
292                  vmint size = expr->evalInt();                  vmint size = expr->evalInt();
293                  if (size <= 0) {                  if (size <= 0) {
294                      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());
                     $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
295                  } else {                  } else {
296                      context->vartable[name] = new IntArrayVariable(context, size);                      if (name[0] == '?') {
297                      $$ = new NoOperation;                          context->vartable[name] = new RealArrayVariable(context, size);
298                        } else if (name[0] == '%') {
299                            context->vartable[name] = new IntArrayVariable(context, size);
300                        } else {
301                            PARSE_ERR(@2, (String("Variable '") + name + "' declared as unknown array type: use either '%' or '?' instead of '" + String(name).substr(0,1) + "'.").c_str());
302                        }
303                  }                  }
304              }              }
305          }          }
306            $$ = new NoOperation;
307      }      }
308      | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {      | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {
309          const char* name = $2;          const char* name = $2;
310          if (!$4->isConstExpr()) {          if (!$4->isConstExpr()) {
311              PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());              PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
312          } else if ($4->exprType() != INT_EXPR) {          } else if ($4->exprType() != INT_EXPR) {
313              PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());              PARSE_ERR(@4, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
314          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
315              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
316          } else {          } else {
317              IntExprRef sizeExpr = $4;              IntExprRef sizeExpr = $4;
318              ArgsRef args = $8;              ArgsRef args = $8;
319              vmint size = sizeExpr->evalInt();              vmint size = sizeExpr->evalInt();
320              if (size <= 0) {              if (size <= 0) {
321                  PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());                  PARSE_ERR(@4, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
322              } else if (args->argsCount() > size) {              } else if (args->argsCount() > size) {
323                  PARSE_ERR(@8, (String("Array variable '") + name +                  PARSE_ERR(@8, (String("Array variable '") + name +
324                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
325                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
326                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
327              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {
328                  PARSE_ERR(@4, "Units are not allowed as array size.");                  PARSE_ERR(@4, "Units are not allowed as array size.");
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
329              } else {              } else {
330                  if (sizeExpr->isFinal())                  if (sizeExpr->isFinal())
331                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");
332                    ExprType_t declType = EMPTY_EXPR;
333                    if (name[0] == '%') {
334                        declType = INT_EXPR;
335                    } else if (name[0] == '?') {
336                        declType = REAL_EXPR;
337                    } else if (name[0] == '$') {
338                        PARSE_ERR(@2, (String("Variable '") + name + "' declaration ambiguous: Use '%' as name prefix for integer arrays instead of '$'.").c_str());
339                    } else if (name[0] == '~') {
340                        PARSE_ERR(@2, (String("Variable '") + name + "' declaration ambiguous: Use '?' as name prefix for real number arrays instead of '~'.").c_str());
341                    } else {
342                        PARSE_ERR(@2, (String("Variable '") + name + "' declared as unknown array type: use either '%' or '?' instead of '" + String(name).substr(0,1) + "'.").c_str());
343                    }
344                  bool argsOK = true;                  bool argsOK = true;
345                  for (vmint i = 0; i < args->argsCount(); ++i) {                  if (declType == EMPTY_EXPR) {
346                      if (args->arg(i)->exprType() != INT_EXPR) {                      argsOK = false;
347                          PARSE_ERR(                  } else {
348                              @8,                      for (vmint i = 0; i < args->argsCount(); ++i) {
349                              (String("Array variable '") + name +                          if (args->arg(i)->exprType() != declType) {
350                              "' declared with invalid assignment values. Assigned element " +                              PARSE_ERR(
351                              ToString(i+1) + " is not an integer expression.").c_str()                                  @8,
352                          );                                  (String("Array variable '") + name +
353                          argsOK = false;                                  "' declared with invalid assignment values. Assigned element " +
354                          break;                                  ToString(i+1) + " is not an " + typeStr(declType) + " expression.").c_str()
355                      } else if (args->arg(i)->asInt()->unitType() ||                              );
356                                 args->arg(i)->asInt()->unitPrefix(0))                              argsOK = false;
357                      {                              break;
358                          PARSE_ERR(                          } else if (args->arg(i)->asInt()->unitType() ||
359                              @8,                                     args->arg(i)->asInt()->unitPrefix(0))
360                              (String("Array variable '") + name +                          {
361                              "' declared with invalid assignment values. Assigned element " +                              PARSE_ERR(
362                              ToString(i+1) + " contains a unit.").c_str()                                  @8,
363                          );                                  (String("Array variable '") + name +
364                          argsOK = false;                                  "' declared with invalid assignment values. Assigned element " +
365                          break;                                  ToString(i+1) + " contains a unit.").c_str()
366                                );
367                                argsOK = false;
368                                break;
369                            }
370                      }                      }
371                  }                  }
372                  if (argsOK) {                  if (argsOK) {
373                      context->vartable[name] = new IntArrayVariable(context, size, args);                      if (declType == REAL_EXPR)
374                      $$ = new NoOperation;                          context->vartable[name] = new RealArrayVariable(context, size, args);
375                  } else                      else
376                      $$ = new FunctionCall("nothing", new Args, NULL); // whatever                          context->vartable[name] = new IntArrayVariable(context, size, args);
377                    }
378              }              }
379          }          }
380            $$ = new NoOperation;
381      }      }
382      | DECLARE CONST_ VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {      | DECLARE CONST_ VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {
383          const char* name = $3;          const char* name = $3;
384          if (!$5->isConstExpr()) {          if (!$5->isConstExpr()) {
385              PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());              PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
386          } else if ($5->exprType() != INT_EXPR) {          } else if ($5->exprType() != INT_EXPR) {
387              PARSE_ERR(@5, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());              PARSE_ERR(@5, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
388          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
389              PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());
             $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
390          } else {          } else {
391              IntExprRef sizeExpr = $5;              IntExprRef sizeExpr = $5;
392              ArgsRef args = $9;              ArgsRef args = $9;
393              vmint size = sizeExpr->evalInt();              vmint size = sizeExpr->evalInt();
394              if (size <= 0) {              if (size <= 0) {
395                  PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());                  PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
396              } else if (args->argsCount() > size) {              } else if (args->argsCount() > size) {
397                  PARSE_ERR(@9, (String("Array variable '") + name +                  PARSE_ERR(@9, (String("Array variable '") + name +
398                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
399                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
400                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
401              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {              } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {
402                  PARSE_ERR(@5, "Units are not allowed as array size.");                  PARSE_ERR(@5, "Units are not allowed as array size.");
                 $$ = new FunctionCall("nothing", new Args, NULL); // whatever  
403              } else {              } else {
404                  if (sizeExpr->isFinal())                  if (sizeExpr->isFinal())
405                      PARSE_WRN(@5, "Final operator '!' is meaningless here.");                      PARSE_WRN(@5, "Final operator '!' is meaningless here.");
406                    ExprType_t declType = EMPTY_EXPR;
407                    if (name[0] == '%') {
408                        declType = INT_EXPR;
409                    } else if (name[0] == '?') {
410                        declType = REAL_EXPR;
411                    } else if (name[0] == '$') {
412                        PARSE_ERR(@3, (String("Variable '") + name + "' declaration ambiguous: Use '%' as name prefix for integer arrays instead of '$'.").c_str());
413                    } else if (name[0] == '~') {
414                        PARSE_ERR(@3, (String("Variable '") + name + "' declaration ambiguous: Use '?' as name prefix for real number arrays instead of '~'.").c_str());
415                    } else {
416                        PARSE_ERR(@3, (String("Variable '") + name + "' declared as unknown array type: use either '%' or '?' instead of '" + String(name).substr(0,1) + "'.").c_str());
417                    }
418                  bool argsOK = true;                  bool argsOK = true;
419                  for (vmint i = 0; i < args->argsCount(); ++i) {                  if (declType == EMPTY_EXPR) {
420                      if (args->arg(i)->exprType() != INT_EXPR) {                      argsOK = false;
421                          PARSE_ERR(                  } else {
422                              @9,                      for (vmint i = 0; i < args->argsCount(); ++i) {
423                              (String("Array variable '") + name +                          if (args->arg(i)->exprType() != declType) {
424                              "' declared with invalid assignment values. Assigned element " +                              PARSE_ERR(
425                              ToString(i+1) + " is not an integer expression.").c_str()                                  @9,
426                          );                                  (String("Array variable '") + name +
427                          argsOK = false;                                  "' declared with invalid assignment values. Assigned element " +
428                          break;                                  ToString(i+1) + " is not an " + typeStr(declType) + " expression.").c_str()
429                      }                              );
430                      if (!args->arg(i)->isConstExpr()) {                              argsOK = false;
431                          PARSE_ERR(                              break;
432                              @9,                          }
433                              (String("const array variable '") + name +                          if (!args->arg(i)->isConstExpr()) {
434                              "' must be defined with const values. Assigned element " +                              PARSE_ERR(
435                              ToString(i+1) + " is not a const expression though.").c_str()                                  @9,
436                          );                                  (String("const array variable '") + name +
437                          argsOK = false;                                  "' must be defined with const values. Assigned element " +
438                          break;                                  ToString(i+1) + " is not a const expression though.").c_str()
439                      } else if (args->arg(i)->asInt()->unitType() ||                              );
440                                 args->arg(i)->asInt()->unitPrefix(0))                              argsOK = false;
441                      {                              break;
442                          PARSE_ERR(                          } else if (args->arg(i)->asInt()->unitType() ||
443                              @9,                                     args->arg(i)->asInt()->unitPrefix(0))
444                              (String("const array variable '") + name +                          {
445                              "' declared with invalid assignment values. Assigned element " +                              PARSE_ERR(
446                              ToString(i+1) + " contains a unit.").c_str()                                  @9,
447                          );                                  (String("const array variable '") + name +
448                          argsOK = false;                                  "' declared with invalid assignment values. Assigned element " +
449                          break;                                  ToString(i+1) + " contains a unit.").c_str()
450                                );
451                                argsOK = false;
452                                break;
453                            }
454                      }                      }
455                  }                  }
456                  if (argsOK) {                  if (argsOK) {
457                      context->vartable[name] = new IntArrayVariable(context, size, args, true);                      if (declType == REAL_EXPR)
458                      $$ = new NoOperation;                          context->vartable[name] = new RealArrayVariable(context, size, args, true);
459                  } else                      else
460                      $$ = new FunctionCall("nothing", new Args, NULL); // whatever                          context->vartable[name] = new IntArrayVariable(context, size, args, true);
461                    }
462              }              }
463          }          }
464            $$ = new NoOperation;
465      }      }
466      | DECLARE CONST_ VARIABLE ASSIGNMENT expr  {      | DECLARE CONST_ VARIABLE ASSIGNMENT expr  {
467          const char* name = $3;          const char* name = $3;
468            const ExprType_t declType = exprTypeOfVarName(name);
469          if ($5->exprType() == STRING_EXPR) {          if ($5->exprType() == STRING_EXPR) {
470              if (name[0] == '$')              if (name[0] != '@')
471                  PARSE_WRN(@5, "Variable declared as integer, string expression assigned though.");                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", string expression assigned though.").c_str());
472              String s;              String s;
473              StringExprRef expr = $5;              StringExprRef expr = $5;
474              if (expr->isConstExpr())              if (expr->isConstExpr())
# Line 420  statement: Line 478  statement:
478              ConstStringVariableRef var = new ConstStringVariable(context, s);              ConstStringVariableRef var = new ConstStringVariable(context, s);
479              context->vartable[name] = var;              context->vartable[name] = var;
480              //$$ = new Assignment(var, new StringLiteral(s));              //$$ = new Assignment(var, new StringLiteral(s));
481              $$ = new NoOperation();          } else if ($5->exprType() == REAL_EXPR) {
482          } else {              if (name[0] != '~')
483              if (name[0] == '@')                  PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str());
484                  PARSE_WRN(@5, "Variable declared as string, integer expression assigned though.");              vmfloat f = 0;
485                RealExprRef expr = $5;
486                if (expr->isConstExpr())
487                    f = expr->evalReal();
488                else
489                    PARSE_ERR(@5, (String("Assignment to const real number variable '") + name + "' requires const expression.").c_str());
490                ConstRealVariableRef var = new ConstRealVariable(f);
491                var->copyUnitFrom(expr);
492                var->setFinal(expr->isFinal());
493                context->vartable[name] = var;
494                //$$ = new Assignment(var, new IntLiteral(i));
495            } else if ($5->exprType() == INT_EXPR) {
496                if (name[0] != '$')
497                    PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str());
498              vmint i = 0;              vmint i = 0;
499              IntExprRef expr = $5;              IntExprRef expr = $5;
500              if (expr->isConstExpr())              if (expr->isConstExpr())
# Line 435  statement: Line 506  statement:
506              var->setFinal(expr->isFinal());              var->setFinal(expr->isFinal());
507              context->vartable[name] = var;              context->vartable[name] = var;
508              //$$ = new Assignment(var, new IntLiteral(i));              //$$ = new Assignment(var, new IntLiteral(i));
509              $$ = new NoOperation();          } else if ($5->exprType() == EMPTY_EXPR) {
510                PARSE_ERR(@5, "Expression does not result in a value.");
511            } else if (isArray($5->exprType())) {
512                PARSE_ERR(@5, (String("Variable '") + name + "' declared as scalar type, array expression assigned though.").c_str());
513          }          }
514            $$ = new NoOperation();
515      }      }
516      | assignment  {      | assignment  {
517          $$ = $1;          $$ = $1;
# Line 563  functioncall: Line 638  functioncall:
638                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects an assignable variable.").c_str());                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects an assignable variable.").c_str());
639                      argsOK = false;                      argsOK = false;
640                      break;                      break;
641                  } else if (args->arg(i)->exprType() == INT_EXPR && !fn->acceptsArgUnitType(i, args->arg(i)->asInt()->unitType())) {                  } else if (isScalarNumber(args->arg(i)->exprType()) && !fn->acceptsArgUnitType(i, args->arg(i)->asScalarNumberExpr()->unitType())) {
642                      if (args->arg(i)->asInt()->unitType())                      if (args->arg(i)->asScalarNumberExpr()->unitType())
643                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect unit " + unitTypeStr(args->arg(i)->asInt()->unitType()) +  ".").c_str());                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect unit " + unitTypeStr(args->arg(i)->asScalarNumberExpr()->unitType()) +  ".").c_str());
644                      else                      else
645                          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());
646                      argsOK = false;                      argsOK = false;
647                      break;                      break;
648                  } else if (args->arg(i)->exprType() == INT_EXPR && args->arg(i)->asInt()->unitPrefix(0) && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asInt()->unitType())) {                  } else if (isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->unitPrefix(0) && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asScalarNumberExpr()->unitType())) {
649                      if (args->arg(i)->asInt()->unitType())                      if (args->arg(i)->asScalarNumberExpr()->unitType())
650                          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)->asInt()->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());
651                      else                      else
652                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix.").c_str());                          PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix.").c_str());
653                      argsOK = false;                      argsOK = false;
654                      break;                      break;
655                  } else if (!fn->acceptsArgFinal(i) && args->arg(i)->exprType() == INT_EXPR && args->arg(i)->asInt()->isFinal()) {                  } else if (!fn->acceptsArgFinal(i) && isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->isFinal()) {
656                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a \"final\" value.").c_str());                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a \"final\" value.").c_str());
657                      argsOK = false;                      argsOK = false;
658                      break;                      break;
# Line 655  assignment: Line 730  assignment:
730              PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());              PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());
731          else if (var->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
732              PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());
733          else if (var->exprType() == INT_EXPR) {          else if (isScalarNumber(var->exprType())) {
734              IntVariableRef intVar = var;              ScalarNumberVariableRef numberVar = var;
735              IntExprRef expr = $3;              ScalarNumberExprRef expr = $3;
736              if (intVar->unitType() != expr->unitType())              if (numberVar->unitType() != expr->unitType())
737                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has unit type " + unitTypeStr(intVar->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());
738              else if (intVar->unitFactor() != expr->unitFactor())              else if (numberVar->unitFactor() != expr->unitFactor())
739                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has a different unit prefix.").c_str());                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has a different unit prefix.").c_str());
740              else if (intVar->isFinal() != expr->isFinal())              else if (numberVar->isFinal() != expr->isFinal())
741                  PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' was declared as " + String(intVar->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());
742          }          }
743          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
744      }      }
# Line 672  assignment: Line 747  assignment:
747          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
748          if (!var)          if (!var)
749              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
750          else if (var->exprType() != INT_ARR_EXPR)          else if (!isArray(var->exprType()))
751              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());
752          else if (var->isConstExpr())          else if (var->isConstExpr())
753              PARSE_ERR(@5, (String("Variable assignment: Cannot modify const array variable '") + name + "'.").c_str());              PARSE_ERR(@5, (String("Variable assignment: Cannot modify const array variable '") + name + "'.").c_str());
# Line 682  assignment: Line 757  assignment:
757              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());
758          else if ($3->asInt()->unitType())          else if ($3->asInt()->unitType())
759              PARSE_ERR(@3, "Unit types are not allowed as array index.");              PARSE_ERR(@3, "Unit types are not allowed as array index.");
760          else if ($6->exprType() != INT_EXPR)          else if ($6->exprType() != var->exprType())
761              PARSE_ERR(@5, (String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());              PARSE_ERR(@5, (String("Variable '") + name + "' was declared as " + typeStr(var->exprType()) + ", assigned expression is " + typeStr($6->exprType()) + " though.").c_str());
762          else if ($6->asInt()->unitType())          else if ($6->asScalarNumberExpr()->unitType())
763              PARSE_ERR(@6, "Unit types are not allowed for array variables.");              PARSE_ERR(@6, "Unit types are not allowed for array variables.");
764          else if ($6->asInt()->isFinal())          else if ($6->asScalarNumberExpr()->isFinal())
765              PARSE_ERR(@6, "Final operator '!' not allowed for array variables.");              PARSE_ERR(@6, "Final operator '!' not allowed for array variables.");
766          else if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize())          else if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((ArrayExprRef)var)->arraySize())
767              PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +              PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +
768                            " exceeds size of array variable '" + name +                            " exceeds size of array variable '" + name +
769                            "' which was declared with size " +                            "' which was declared with size " +
770                            ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str());                            ToString(((ArrayExprRef)var)->arraySize()) + ".").c_str());
771          else if ($3->asInt()->isFinal())          else if ($3->asInt()->isFinal())
772              PARSE_WRN(@3, "Final operator '!' is meaningless here.");              PARSE_WRN(@3, "Final operator '!' is meaningless here.");
773          IntArrayElementRef element = new IntArrayElement(var, $3);          if (var->exprType() == INT_ARR_EXPR) {
774          $$ = new Assignment(element, $6);              IntArrayElementRef element = new IntArrayElement(var, $3);
775                $$ = new Assignment(element, $6);
776            } else if (var->exprType() == REAL_ARR_EXPR) {
777                RealArrayElementRef element = new RealArrayElement(var, $3);
778                $$ = new Assignment(element, $6);
779            } else {
780                $$ = new NoOperation;
781            }
782      }      }
783    
784  unary_expr:  unary_expr:
785      INTEGER  {      INTEGER  {
786          $$ = new IntLiteral($1);          $$ = new IntLiteral($1);
787      }      }
788        | REAL  {
789            $$ = new RealLiteral($1);
790        }
791      | INTEGER_UNIT  {      | INTEGER_UNIT  {
792          IntLiteralRef literal = new IntLiteral($1.iValue);          IntLiteralRef literal = new IntLiteral($1.iValue);
793          literal->setUnit($1.prefix, $1.unit);          literal->setUnit($1.prefix, $1.unit);
794          $$ = literal;          $$ = literal;
795      }      }
796        | REAL_UNIT  {
797            RealLiteralRef literal = new RealLiteral($1.fValue);
798            literal->setUnit($1.prefix, $1.unit);
799            $$ = literal;
800        }
801      | STRING    {      | STRING    {
802          $$ = new StringLiteral($1);          $$ = new StringLiteral($1);
803      }      }
# Line 727  unary_expr: Line 817  unary_expr:
817          if (!var) {          if (!var) {
818              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
819              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
820          } else if (var->exprType() != INT_ARR_EXPR) {          } else if (!isArray(var->exprType())) {
821              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());
822              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
823          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
# Line 737  unary_expr: Line 827  unary_expr:
827              PARSE_ERR(@3, "Units are not allowed as array index.");              PARSE_ERR(@3, "Units are not allowed as array index.");
828              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
829          } else {          } else {
830              if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize())              if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((ArrayExprRef)var)->arraySize())
831                  PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +                  PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +
832                                 " exceeds size of array variable '" + name +                                 " exceeds size of array variable '" + name +
833                                 "' which was declared with size " +                                 "' which was declared with size " +
834                                 ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str());                                 ToString(((ArrayExprRef)var)->arraySize()) + ".").c_str());
835              else if ($3->asInt()->isFinal())              else if ($3->asInt()->isFinal())
836                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");                  PARSE_WRN(@3, "Final operator '!' is meaningless here.");
837              $$ = new IntArrayElement(var, $3);              if (var->exprType() == REAL_ARR_EXPR) {
838                    $$ = new RealArrayElement(var, $3);
839                } else {
840                    $$ = new IntArrayElement(var, $3);
841                }
842          }          }
843      }      }
844      | '(' expr ')'  {      | '(' expr ')'  {
# Line 779  unary_expr: Line 873  unary_expr:
873          }          }
874      }      }
875      | '!' unary_expr  {      | '!' unary_expr  {
876          if ($2->exprType() != INT_EXPR) {          if (!isScalarNumber($2->exprType())) {
877              PARSE_ERR(@2, (String("Right operand of \"final\" operator '!' must be an integer 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());
878              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
879          } else {          } else {
880              $$ = new Final($2);              $$ = new Final($2);
# Line 901  rel_expr: Line 995  rel_expr:
995      | rel_expr '<' add_expr  {      | rel_expr '<' add_expr  {
996          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
997          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
998          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
999              PARSE_ERR(@1, (String("Left operand of operator '<' must be an integer 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());
1000              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1001          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1002              PARSE_ERR(@3, (String("Right operand of operator '<' must be an integer 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());
1003              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1004          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1005                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1006          {          {
1007              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1008              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 919  rel_expr: Line 1013  rel_expr:
1013      | rel_expr '>' add_expr  {      | rel_expr '>' add_expr  {
1014          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1015          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1016          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1017              PARSE_ERR(@1, (String("Left operand of operator '>' must be an integer 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());
1018              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1019          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1020              PARSE_ERR(@3, (String("Right operand of operator '>' must be an integer 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());
1021              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1022          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1023                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1024          {          {
1025              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1026              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 937  rel_expr: Line 1031  rel_expr:
1031      | rel_expr LE add_expr  {      | rel_expr LE add_expr  {
1032          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1033          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1034          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1035              PARSE_ERR(@1, (String("Left operand of operator '<=' must be an integer 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());
1036              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1037          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1038              PARSE_ERR(@3, (String("Right operand of operator '<=' must be an integer 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());
1039              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1040          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1041                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1042          {          {
1043              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1044              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 955  rel_expr: Line 1049  rel_expr:
1049      | rel_expr GE add_expr  {      | rel_expr GE add_expr  {
1050          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1051          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1052          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1053              PARSE_ERR(@1, (String("Left operand of operator '>=' must be an integer 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());
1054              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1055          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1056              PARSE_ERR(@3, (String("Right operand of operator '>=' must be an integer 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());
1057              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1058          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1059                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1060          {          {
1061              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1062              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 973  rel_expr: Line 1067  rel_expr:
1067      | rel_expr '=' add_expr  {      | rel_expr '=' add_expr  {
1068          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1069          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1070          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1071              PARSE_ERR(@1, (String("Left operand of operator '=' must be an integer 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());
1072              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1073          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1074              PARSE_ERR(@3, (String("Right operand of operator '=' must be an integer 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());
1075              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1076          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1077                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1078          {          {
1079              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1080              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 991  rel_expr: Line 1085  rel_expr:
1085      | rel_expr '#' add_expr  {      | rel_expr '#' add_expr  {
1086          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1087          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1088          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1089              PARSE_ERR(@1, (String("Left operand of operator '#' must be an integer 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());
1090              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1091          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1092              PARSE_ERR(@3, (String("Right operand of operator '#' must be an integer 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());
1093              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1094          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1095                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1096          {          {
1097              PARSE_ERR(@2, "Operands of relative operations must have same unit.");              PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1098              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 1012  add_expr: Line 1106  add_expr:
1106      | add_expr '+' mul_expr  {      | add_expr '+' mul_expr  {
1107          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1108          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1109          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1110              PARSE_ERR(@1, (String("Left operand of operator '+' must be an integer 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());
1111              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1112          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1113              PARSE_ERR(@3, (String("Right operand of operator '+' must be an integer 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());
1114                $$ = new IntLiteral(0);
1115            } else if (lhs->exprType() != rhs->exprType()) {
1116                PARSE_ERR(@2, (String("Operands of operator '+' must have same type; left operand is ") +
1117                          typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1118              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1119          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1120                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1121          {          {
1122              PARSE_ERR(@2, "Operands of '+' operations must have same unit.");              PARSE_ERR(@2, "Operands of '+' operations must have same unit.");
1123              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 1030  add_expr: Line 1128  add_expr:
1128      | add_expr '-' mul_expr  {      | add_expr '-' mul_expr  {
1129          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1130          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1131          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1132              PARSE_ERR(@1, (String("Left operand of operator '-' must be an integer 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());
1133              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1134          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1135              PARSE_ERR(@3, (String("Right operand of operator '-' must be an integer 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());
1136                $$ = new IntLiteral(0);
1137            } else if (lhs->exprType() != rhs->exprType()) {
1138                PARSE_ERR(@2, (String("Operands of operator '-' must have same type; left operand is ") +
1139                          typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1140              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1141          } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||          } else if (lhs->asScalarNumberExpr()->unitType()   != rhs->asScalarNumberExpr()->unitType() ||
1142                     lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())                     lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor())
1143          {          {
1144              PARSE_ERR(@2, "Operands of '-' operations must have same unit.");              PARSE_ERR(@2, "Operands of '-' operations must have same unit.");
1145              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
# Line 1051  mul_expr: Line 1153  mul_expr:
1153      | mul_expr '*' unary_expr  {      | mul_expr '*' unary_expr  {
1154          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1155          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1156          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1157              PARSE_ERR(@1, (String("Left operand of operator '*' must be an integer 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());
1158              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1159          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1160              PARSE_ERR(@3, (String("Right operand of operator '*' must be an integer 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());
1161              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1162          } else if (lhs->asInt()->unitType() && rhs->asInt()->unitType()) {          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {
1163              PARSE_ERR(@2, "Only one operand of operator '*' may have a unit type");              PARSE_ERR(@2, "Only one operand of operator '*' may have a unit type");
1164              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1165          } else if (lhs->asInt()->unitPrefix(0) && rhs->asInt()->unitPrefix(0)) {          } else if (lhs->exprType() != rhs->exprType()) {
1166                PARSE_ERR(@2, (String("Operands of operator '*' must have same type; left operand is ") +
1167                          typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1168                $$ = new IntLiteral(0);
1169            } else if (lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0)) {
1170              PARSE_ERR(@2, "Only one operand of operator '*' may have a unit prefix");              PARSE_ERR(@2, "Only one operand of operator '*' may have a unit prefix");
1171              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1172          } else {          } else {
# Line 1070  mul_expr: Line 1176  mul_expr:
1176      | mul_expr '/' unary_expr  {      | mul_expr '/' unary_expr  {
1177          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
1178          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
1179          if (lhs->exprType() != INT_EXPR) {          if (!isScalarNumber(lhs->exprType())) {
1180              PARSE_ERR(@1, (String("Left operand of operator '/' must be an integer 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());
1181              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1182          } else if (rhs->exprType() != INT_EXPR) {          } else if (!isScalarNumber(rhs->exprType())) {
1183              PARSE_ERR(@3, (String("Right operand of operator '/' must be an integer 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());
1184              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1185          } else if (lhs->asInt()->unitType() && rhs->asInt()->unitType() &&          } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType() &&
1186                     lhs->asInt()->unitType() != rhs->asInt()->unitType())                     lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType())
1187          {          {
1188              PARSE_ERR(@2, "Operands of operator '/' with two different unit types.");              PARSE_ERR(@2, "Operands of operator '/' with two different unit types.");
1189              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1190          } else if (!lhs->asInt()->unitType() && rhs->asInt()->unitType()) {          } else if (!lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) {
1191              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 " + typeStr(rhs->exprType()) + " is not possible.").c_str());
1192              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1193          } else if (lhs->asInt()->unitFactor()  != rhs->asInt()->unitFactor() &&          } else if (lhs->asScalarNumberExpr()->unitFactor()  != rhs->asScalarNumberExpr()->unitFactor() &&
1194                     lhs->asInt()->unitPrefix(0) && rhs->asInt()->unitPrefix(0))                     lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0))
1195          {          {
1196              PARSE_ERR(@2, "Dividing two operands with two different unit prefixes is not possible.");              PARSE_ERR(@2, "Dividing two operands with two different unit prefixes is not possible.");
1197              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1198          } else if (lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor() &&          } else if (lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor() &&
1199                     rhs->asInt()->unitPrefix(0))                     rhs->asScalarNumberExpr()->unitPrefix(0))
1200          {          {
1201              PARSE_ERR(@3, "Dividing left operand without any unit prefix by right operand with unit prefix is not possible.");              PARSE_ERR(@3, "Dividing left operand without any unit prefix by right operand with unit prefix is not possible.");
1202              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1203            } else if (lhs->exprType() != rhs->exprType()) {
1204                PARSE_ERR(@2, (String("Operands of operator '/' must have same type; left operand is ") +
1205                          typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str());
1206                $$ = new IntLiteral(0);
1207          } else {          } else {
1208              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
1209          }          }

Legend:
Removed from v.3564  
changed lines
  Added in v.3573

  ViewVC Help
Powered by ViewVC