/[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 3052 by schoenebeck, Wed Dec 14 17:34:54 2016 UTC revision 3561 by schoenebeck, Fri Aug 23 11:44:00 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson   * Copyright (c) 2014-2017 Christian Schoenebeck and Andreas Persson
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 23  Line 23 
23      #define scanner context->scanner      #define scanner context->scanner
24      #define PARSE_ERR(loc,txt)  yyerror(&loc, context, txt)      #define PARSE_ERR(loc,txt)  yyerror(&loc, context, txt)
25      #define PARSE_WRN(loc,txt)  InstrScript_warning(&loc, context, txt)      #define PARSE_WRN(loc,txt)  InstrScript_warning(&loc, context, txt)
26        #define PARSE_DROP(loc)     context->addPreprocessorComment(loc.first_line, loc.last_line, loc.first_column+1, loc.last_column+1);
27      #define yytnamerr(res,str)  InstrScript_tnamerr(res, str)      #define yytnamerr(res,str)  InstrScript_tnamerr(res, str)
28  %}  %}
29    
# Line 38  Line 39 
39  %error-verbose  %error-verbose
40    
41  %token <iValue> INTEGER "integer literal"  %token <iValue> INTEGER "integer literal"
42    %token <iUnitValue> INTEGER_UNIT "integer literal with unit"
43  %token <sValue> STRING "string literal"  %token <sValue> STRING "string literal"
44  %token <sValue> IDENTIFIER "function name"  %token <sValue> IDENTIFIER "function name"
45  %token <sValue> VARIABLE "variable name"  %token <sValue> VARIABLE "variable name"
# Line 52  Line 54 
54  %token CONST_ "keyword 'const'"  %token CONST_ "keyword 'const'"
55  %token POLYPHONIC "keyword 'polyphonic'"  %token POLYPHONIC "keyword 'polyphonic'"
56  %token WHILE "keyword 'while'"  %token WHILE "keyword 'while'"
57    %token SYNCHRONIZED "keyword 'synchronized'"
58  %token IF "keyword 'if'"  %token IF "keyword 'if'"
59  %token ELSE "keyword 'else'"  %token ELSE "keyword 'else'"
60  %token SELECT "keyword 'select'"  %token SELECT "keyword 'select'"
# Line 69  Line 72 
72  %token LE "operator '<='"  %token LE "operator '<='"
73  %token GE "operator '>='"  %token GE "operator '>='"
74  %token END_OF_FILE 0 "end of file"  %token END_OF_FILE 0 "end of file"
75    %token UNKNOWN_CHAR "unknown character"
76    
77  %type <nEventHandlers> script sections  %type <nEventHandlers> script sections
78  %type <nEventHandler> section eventhandler  %type <nEventHandler> section eventhandler
# Line 225  statement: Line 229  statement:
229              if (name[0] == '@')              if (name[0] == '@')
230                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as string, integer expression assigned though.").c_str());                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as string, integer expression assigned though.").c_str());
231              IntExprRef expr = $4;              IntExprRef expr = $4;
232                IntVariableRef var = new IntVariable(context);
233              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
234                  const int i = expr->evalInt();                  const vmint i = expr->evalInt();
                 IntVariableRef var = new IntVariable(context);  
                 context->vartable[name] = var;  
235                  $$ = new Assignment(var, new IntLiteral(i));                  $$ = new Assignment(var, new IntLiteral(i));
236              } else {              } else {
                 IntVariableRef var = new IntVariable(context);  
                 context->vartable[name] = var;  
237                  $$ = new Assignment(var, expr);                  $$ = new Assignment(var, expr);
238              }              }
239                var->copyUnitFrom(expr);
240                var->setFinal(expr->isFinal());
241                context->vartable[name] = var;
242          }          }
243      }      }
244      | DECLARE VARIABLE '[' expr ']'  {      | DECLARE VARIABLE '[' expr ']'  {
# Line 251  statement: Line 255  statement:
255              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
256          } else {          } else {
257              IntExprRef expr = $4;              IntExprRef expr = $4;
258              int size = expr->evalInt();              if (expr->unitType() || expr->unitPrefix(0)) {
259              if (size <= 0) {                  PARSE_ERR(@4, "Units are not allowed as array size.");
                 PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());  
260                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever
261              } else {              } else {
262                  context->vartable[name] = new IntArrayVariable(context, size);                  if (expr->isFinal())
263                  $$ = new NoOperation;                      PARSE_WRN(@4, "Final operator '!' is meaningless here.");
264                    vmint size = expr->evalInt();
265                    if (size <= 0) {
266                        PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());
267                        $$ = new FunctionCall("nothing", new Args, NULL); // whatever
268                    } else {
269                        context->vartable[name] = new IntArrayVariable(context, size);
270                        $$ = new NoOperation;
271                    }
272              }              }
273          }          }
274      }      }
# Line 275  statement: Line 286  statement:
286          } else {          } else {
287              IntExprRef sizeExpr = $4;              IntExprRef sizeExpr = $4;
288              ArgsRef args = $8;              ArgsRef args = $8;
289              int size = sizeExpr->evalInt();              vmint size = sizeExpr->evalInt();
290              if (size <= 0) {              if (size <= 0) {
291                  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());
292                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever
293              } else if (args->argsCount() > size) {              } else if (args->argsCount() > size) {
294                  PARSE_ERR(@8, (String("Variable '") + name +                  PARSE_ERR(@8, (String("Array variable '") + name +
295                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
296                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
297                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
298                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever                            $$ = new FunctionCall("nothing", new Args, NULL); // whatever
299                } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {
300                    PARSE_ERR(@4, "Units are not allowed as array size.");
301                    $$ = new FunctionCall("nothing", new Args, NULL); // whatever
302              } else {              } else {
303                    if (sizeExpr->isFinal())
304                        PARSE_WRN(@4, "Final operator '!' is meaningless here.");
305                  bool argsOK = true;                  bool argsOK = true;
306                  for (int i = 0; i < args->argsCount(); ++i) {                  for (vmint i = 0; i < args->argsCount(); ++i) {
307                      if (args->arg(i)->exprType() != INT_EXPR) {                      if (args->arg(i)->exprType() != INT_EXPR) {
308                          PARSE_ERR(                          PARSE_ERR(
309                              @8,                              @8,
# Line 297  statement: Line 313  statement:
313                          );                          );
314                          argsOK = false;                          argsOK = false;
315                          break;                          break;
316                        } else if (args->arg(i)->asInt()->unitType() ||
317                                   args->arg(i)->asInt()->unitPrefix(0))
318                        {
319                            PARSE_ERR(
320                                @8,
321                                (String("Array variable '") + name +
322                                "' declared with invalid assignment values. Assigned element " +
323                                ToString(i+1) + " contains a unit.").c_str()
324                            );
325                            argsOK = false;
326                            break;
327                      }                      }
328                  }                  }
329                  if (argsOK) {                  if (argsOK) {
# Line 307  statement: Line 334  statement:
334              }              }
335          }          }
336      }      }
337        | DECLARE CONST_ VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {
338            const char* name = $3;
339            if (!$5->isConstExpr()) {
340                PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with constant array size.").c_str());
341                $$ = new FunctionCall("nothing", new Args, NULL); // whatever
342            } else if ($5->exprType() != INT_EXPR) {
343                PARSE_ERR(@5, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
344                $$ = new FunctionCall("nothing", new Args, NULL); // whatever
345            } else if (context->variableByName(name)) {
346                PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());
347                $$ = new FunctionCall("nothing", new Args, NULL); // whatever
348            } else {
349                IntExprRef sizeExpr = $5;
350                ArgsRef args = $9;
351                vmint size = sizeExpr->evalInt();
352                if (size <= 0) {
353                    PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with positive array size.").c_str());
354                    $$ = new FunctionCall("nothing", new Args, NULL); // whatever
355                } else if (args->argsCount() > size) {
356                    PARSE_ERR(@9, (String("Array variable '") + name +
357                              "' was declared with size " + ToString(size) +
358                              " but " + ToString(args->argsCount()) +
359                              " values were assigned." ).c_str());
360                    $$ = new FunctionCall("nothing", new Args, NULL); // whatever
361                } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) {
362                    PARSE_ERR(@5, "Units are not allowed as array size.");
363                    $$ = new FunctionCall("nothing", new Args, NULL); // whatever
364                } else {
365                    if (sizeExpr->isFinal())
366                        PARSE_WRN(@5, "Final operator '!' is meaningless here.");
367                    bool argsOK = true;
368                    for (vmint i = 0; i < args->argsCount(); ++i) {
369                        if (args->arg(i)->exprType() != INT_EXPR) {
370                            PARSE_ERR(
371                                @9,
372                                (String("Array variable '") + name +
373                                "' declared with invalid assignment values. Assigned element " +
374                                ToString(i+1) + " is not an integer expression.").c_str()
375                            );
376                            argsOK = false;
377                            break;
378                        }
379                        if (!args->arg(i)->isConstExpr()) {
380                            PARSE_ERR(
381                                @9,
382                                (String("const array variable '") + name +
383                                "' must be defined with const values. Assigned element " +
384                                ToString(i+1) + " is not a const expression though.").c_str()
385                            );
386                            argsOK = false;
387                            break;
388                        } else if (args->arg(i)->asInt()->unitType() ||
389                                   args->arg(i)->asInt()->unitPrefix(0))
390                        {
391                            PARSE_ERR(
392                                @9,
393                                (String("const array variable '") + name +
394                                "' declared with invalid assignment values. Assigned element " +
395                                ToString(i+1) + " contains a unit.").c_str()
396                            );
397                            argsOK = false;
398                            break;
399                        }
400                    }
401                    if (argsOK) {
402                        context->vartable[name] = new IntArrayVariable(context, size, args, true);
403                        $$ = new NoOperation;
404                    } else
405                        $$ = new FunctionCall("nothing", new Args, NULL); // whatever
406                }
407            }
408        }
409      | DECLARE CONST_ VARIABLE ASSIGNMENT expr  {      | DECLARE CONST_ VARIABLE ASSIGNMENT expr  {
410          const char* name = $3;          const char* name = $3;
411          if ($5->exprType() == STRING_EXPR) {          if ($5->exprType() == STRING_EXPR) {
# Line 325  statement: Line 424  statement:
424          } else {          } else {
425              if (name[0] == '@')              if (name[0] == '@')
426                  PARSE_WRN(@5, "Variable declared as string, integer expression assigned though.");                  PARSE_WRN(@5, "Variable declared as string, integer expression assigned though.");
427              int i = 0;              vmint i = 0;
428              IntExprRef expr = $5;              IntExprRef expr = $5;
429              if (expr->isConstExpr())              if (expr->isConstExpr())
430                  i = expr->evalInt();                  i = expr->evalInt();
431              else              else
432                  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());
433              ConstIntVariableRef var = new ConstIntVariable(i);              ConstIntVariableRef var = new ConstIntVariable(i);
434                var->copyUnitFrom(expr);
435                var->setFinal(expr->isFinal());
436              context->vartable[name] = var;              context->vartable[name] = var;
437              //$$ = new Assignment(var, new IntLiteral(i));              //$$ = new Assignment(var, new IntLiteral(i));
438              $$ = new NoOperation();              $$ = new NoOperation();
# Line 342  statement: Line 443  statement:
443      }      }
444      | WHILE '(' expr ')' opt_statements END WHILE  {      | WHILE '(' expr ')' opt_statements END WHILE  {
445          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
446              $$ = new While($3, $5);              IntExprRef expr = $3;
447                if (expr->isFinal() && expr->isConstExpr())
448                    PARSE_WRN(@3, "Final operator '!' is meaningless here.");
449                $$ = new While(expr, $5);
450          } else {          } else {
451              PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");              PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");
452              $$ = new While(new IntLiteral(0), $5);              $$ = new While(new IntLiteral(0), $5);
453          }          }
454      }      }
455        | SYNCHRONIZED opt_statements END SYNCHRONIZED  {
456            $$ = new SyncBlock($2);
457        }
458      | IF '(' expr ')' opt_statements ELSE opt_statements END IF  {      | IF '(' expr ')' opt_statements ELSE opt_statements END IF  {
459          $$ = new If($3, $5, $7);          if ($3->exprType() == INT_EXPR) {
460                IntExprRef expr = $3;
461                if (expr->isFinal() && expr->isConstExpr())
462                    PARSE_WRN(@3, "Final operator '!' is meaningless here.");
463                $$ = new If($3, $5, $7);
464            } else {
465                PARSE_ERR(@3, "Condition for 'if' must be integer expression.");
466                $$ = new If(new IntLiteral(0), $5, $7);
467            }
468      }      }
469      | IF '(' expr ')' opt_statements END IF  {      | IF '(' expr ')' opt_statements END IF  {
470          $$ = new If($3, $5);          if ($3->exprType() == INT_EXPR) {
471                IntExprRef expr = $3;
472                if (expr->isFinal() && expr->isConstExpr())
473                    PARSE_WRN(@3, "Final operator '!' is meaningless here.");
474                $$ = new If($3, $5);
475            } else {
476                PARSE_ERR(@3, "Condition for 'if' must be integer expression.");
477                $$ = new If(new IntLiteral(0), $5);
478            }
479      }      }
480      | SELECT expr caseclauses END SELECT  {      | SELECT expr caseclauses END SELECT  {
481          if ($2->exprType() == INT_EXPR) {          if ($2->exprType() == INT_EXPR) {
482              $$ = new SelectCase($2, $3);              IntExprRef expr = $2;
483                if (expr->unitType() || expr->unitPrefix(0)) {
484                    PARSE_ERR(@2, "Units are not allowed here.");
485                } else {
486                    if (expr->isFinal() && expr->isConstExpr())
487                        PARSE_WRN(@2, "Final operator '!' is meaningless here.");
488                    $$ = new SelectCase(expr, $3);
489                }
490          } else {          } else {
491              PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");              PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");
492              $$ = new SelectCase(new IntLiteral(0), $3);              $$ = new SelectCase(new IntLiteral(0), $3);
# Line 413  functioncall: Line 543  functioncall:
543          } else if (!fn) {          } else if (!fn) {
544              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
545              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
546            } else if (context->functionProvider->isFunctionDisabled(fn,context)) {
547                PARSE_DROP(@$);
548                $$ = new NoFunctionCall;
549          } else if (args->argsCount() < fn->minRequiredArgs()) {          } else if (args->argsCount() < fn->minRequiredArgs()) {
550              PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());              PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
551              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
# Line 421  functioncall: Line 554  functioncall:
554              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
555          } else {          } else {
556              bool argsOK = true;              bool argsOK = true;
557              for (int i = 0; i < args->argsCount(); ++i) {              for (vmint i = 0; i < args->argsCount(); ++i) {
558                  if (args->arg(i)->exprType() != fn->argType(i) && !fn->acceptsArgType(i, args->arg(i)->exprType())) {                  if (args->arg(i)->exprType() != fn->argType(i) && !fn->acceptsArgType(i, args->arg(i)->exprType())) {
559                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects " + typeStr(fn->argType(i)) + " type, but type " + typeStr(args->arg(i)->exprType()) + " was given instead.").c_str());                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects " + typeStr(fn->argType(i)) + " type, but type " + typeStr(args->arg(i)->exprType()) + " was given instead.").c_str());
560                      argsOK = false;                      argsOK = false;
# Line 430  functioncall: Line 563  functioncall:
563                      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());
564                      argsOK = false;                      argsOK = false;
565                      break;                      break;
566                    } else if (args->arg(i)->exprType() == INT_EXPR && !fn->acceptsArgUnitType(i, args->arg(i)->asInt()->unitType())) {
567                        if (args->arg(i)->asInt()->unitType())
568                            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());
569                        else
570                            PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects a unit.").c_str());
571                        argsOK = false;
572                        break;
573                    } else if (!fn->acceptsArgUnitPrefix(i) && args->arg(i)->exprType() == INT_EXPR && args->arg(i)->asInt()->unitPrefix(0)) {
574                        PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix.").c_str());
575                        argsOK = false;
576                        break;
577                    } else if (!fn->acceptsArgFinal(i) && args->arg(i)->exprType() == INT_EXPR && args->arg(i)->asInt()->isFinal()) {
578                        PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a \"final\" value.").c_str());
579                        argsOK = false;
580                        break;
581                  }                  }
582              }              }
583              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);
# Line 446  functioncall: Line 594  functioncall:
594          } else if (!fn) {          } else if (!fn) {
595              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
596              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
597            } else if (context->functionProvider->isFunctionDisabled(fn,context)) {
598                PARSE_DROP(@$);
599                $$ = new NoFunctionCall;
600          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
601              PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());              PARSE_ERR(@3, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
602              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
# Line 464  functioncall: Line 615  functioncall:
615          } else if (!fn) {          } else if (!fn) {
616              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
617              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
618            } else if (context->functionProvider->isFunctionDisabled(fn,context)) {
619                PARSE_DROP(@$);
620                $$ = new NoFunctionCall;
621          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
622              PARSE_ERR(@1, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());              PARSE_ERR(@1, (String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
623              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
# Line 498  assignment: Line 652  assignment:
652              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());
653          else if (var->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
654              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());
655            else if (var->exprType() == INT_EXPR) {
656                IntVariableRef intVar = var;
657                IntExprRef expr = $3;
658                if (intVar->unitType() != expr->unitType())
659                    PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has unit type " + unitTypeStr(intVar->unitType()) + ", assignment has unit type " + unitTypeStr(expr->unitType()) + " though.").c_str());
660                else if (intVar->unitFactor() != expr->unitFactor())
661                    PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has a different unit prefix.").c_str());
662                else if (intVar->isFinal() != expr->isFinal())
663                    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());
664            }
665          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
666      }      }
667      | VARIABLE '[' expr ']' ASSIGNMENT expr  {      | VARIABLE '[' expr ']' ASSIGNMENT expr  {
# Line 507  assignment: Line 671  assignment:
671              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
672          else if (var->exprType() != INT_ARR_EXPR)          else if (var->exprType() != INT_ARR_EXPR)
673              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());
674            else if (var->isConstExpr())
675                PARSE_ERR(@5, (String("Variable assignment: Cannot modify const array variable '") + name + "'.").c_str());
676            else if (!var->isAssignable())
677                PARSE_ERR(@5, (String("Variable assignment: Array variable '") + name + "' is not assignable.").c_str());
678          else if ($3->exprType() != INT_EXPR)          else if ($3->exprType() != INT_EXPR)
679              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());
680            else if ($3->asInt()->unitType())
681                PARSE_ERR(@3, "Unit types are not allowed as array index.");
682          else if ($6->exprType() != INT_EXPR)          else if ($6->exprType() != INT_EXPR)
683              PARSE_ERR(@5, (String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());              PARSE_ERR(@5, (String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());
684            else if ($6->asInt()->unitType())
685                PARSE_ERR(@6, "Unit types are not allowed for array variables.");
686            else if ($6->asInt()->isFinal())
687                PARSE_ERR(@6, "Final operator '!' not allowed for array variables.");
688            else if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize())
689                PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +
690                              " exceeds size of array variable '" + name +
691                              "' which was declared with size " +
692                              ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str());
693            else if ($3->asInt()->isFinal())
694                PARSE_WRN(@3, "Final operator '!' is meaningless here.");
695          IntArrayElementRef element = new IntArrayElement(var, $3);          IntArrayElementRef element = new IntArrayElement(var, $3);
696          $$ = new Assignment(element, $6);          $$ = new Assignment(element, $6);
697      }      }
# Line 519  unary_expr: Line 700  unary_expr:
700      INTEGER  {      INTEGER  {
701          $$ = new IntLiteral($1);          $$ = new IntLiteral($1);
702      }      }
703        | INTEGER_UNIT  {
704            IntLiteralRef literal = new IntLiteral($1.iValue);
705            literal->setUnit($1.prefix, $1.unit);
706            $$ = literal;
707        }
708      | STRING    {      | STRING    {
709          $$ = new StringLiteral($1);          $$ = new StringLiteral($1);
710      }      }
# Line 544  unary_expr: Line 730  unary_expr:
730          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
731              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());
732              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
733            } else if ($3->asInt()->unitType() || $3->asInt()->unitPrefix(0)) {
734                PARSE_ERR(@3, "Units are not allowed as array index.");
735                $$ = new IntLiteral(0);
736          } else {          } else {
737                if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize())
738                    PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) +
739                                   " exceeds size of array variable '" + name +
740                                   "' which was declared with size " +
741                                   ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str());
742                else if ($3->asInt()->isFinal())
743                    PARSE_WRN(@3, "Final operator '!' is meaningless here.");
744              $$ = new IntArrayElement(var, $3);              $$ = new IntArrayElement(var, $3);
745          }          }
746      }      }
# Line 561  unary_expr: Line 757  unary_expr:
757          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
758              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());
759              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
760            } else if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) {
761                PARSE_ERR(@2, "Units are not allowed for operands of bitwise operations.");
762                $$ = new IntLiteral(0);
763          } else {          } else {
764              $$ = new BitwiseNot($2);              $$ = new BitwiseNot($2);
765          }          }
# Line 569  unary_expr: Line 768  unary_expr:
768          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
769              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());
770              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
771            } else if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) {
772                PARSE_ERR(@2, "Units are not allowed for operands of logical operations.");
773                $$ = new IntLiteral(0);
774          } else {          } else {
775              $$ = new Not($2);              $$ = new Not($2);
776          }          }
777      }      }
778        | '!' unary_expr  {
779            if ($2->exprType() != INT_EXPR) {
780                PARSE_ERR(@2, (String("Right operand of \"final\" operator '!' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
781                $$ = new IntLiteral(0);
782            } else {
783                $$ = new Final($2);
784            }
785        }
786    
787  expr:  expr:
788      concat_expr      concat_expr
# Line 602  logical_or_expr: Line 812  logical_or_expr:
812          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
813              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());
814              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
815            } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {
816                PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");
817                $$ = new IntLiteral(0);
818            } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {
819                PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");
820                $$ = new IntLiteral(0);
821          } else {          } else {
822              $$ = new Or(lhs, rhs);              $$ = new Or(lhs, rhs);
823          }          }
# Line 620  logical_and_expr: Line 836  logical_and_expr:
836          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
837              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());
838              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
839            } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {
840                PARSE_ERR(@1, "Units are not allowed for operands of logical operations.");
841                $$ = new IntLiteral(0);
842            } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {
843                PARSE_ERR(@3, "Units are not allowed for operands of logical operations.");
844                $$ = new IntLiteral(0);
845          } else {          } else {
846              $$ = new And(lhs, rhs);              $$ = new And(lhs, rhs);
847          }          }
# Line 636  bitwise_or_expr: Line 858  bitwise_or_expr:
858          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
859              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());
860              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
861            } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {
862                PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");
863                $$ = new IntLiteral(0);
864            } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {
865                PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");
866                $$ = new IntLiteral(0);
867          } else {          } else {
868              $$ = new BitwiseOr(lhs, rhs);              $$ = new BitwiseOr(lhs, rhs);
869          }          }
# Line 654  bitwise_and_expr: Line 882  bitwise_and_expr:
882          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
883              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());
884              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
885            } else if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) {
886                PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations.");
887                $$ = new IntLiteral(0);
888            } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) {
889                PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations.");
890                $$ = new IntLiteral(0);
891          } else {          } else {
892              $$ = new BitwiseAnd(lhs, rhs);              $$ = new BitwiseAnd(lhs, rhs);
893          }          }
# Line 670  rel_expr: Line 904  rel_expr:
904          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
905              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
906              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
907            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
908                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
909            {
910                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
911                $$ = new IntLiteral(0);
912          } else {          } else {
913              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
914          }          }
# Line 683  rel_expr: Line 922  rel_expr:
922          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
923              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
924              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
925            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
926                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
927            {
928                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
929                $$ = new IntLiteral(0);
930          } else {          } else {
931              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
932          }          }
# Line 696  rel_expr: Line 940  rel_expr:
940          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
941              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
942              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
943            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
944                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
945            {
946                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
947                $$ = new IntLiteral(0);
948          } else {          } else {
949              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
950          }          }
# Line 709  rel_expr: Line 958  rel_expr:
958          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
959              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
960              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
961            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
962                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
963            {
964                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
965                $$ = new IntLiteral(0);
966          } else {          } else {
967              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
968          }          }
969      }      }
970      | rel_expr '=' add_expr  {      | rel_expr '=' add_expr  {
971          $$ = new Relation($1, Relation::EQUAL, $3);          ExpressionRef lhs = $1;
972            ExpressionRef rhs = $3;
973            if (lhs->exprType() != INT_EXPR) {
974                PARSE_ERR(@1, (String("Left operand of operator '=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
975                $$ = new IntLiteral(0);
976            } else if (rhs->exprType() != INT_EXPR) {
977                PARSE_ERR(@3, (String("Right operand of operator '=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
978                $$ = new IntLiteral(0);
979            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
980                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
981            {
982                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
983                $$ = new IntLiteral(0);
984            } else {
985                $$ = new Relation(lhs, Relation::EQUAL, rhs);
986            }
987      }      }
988      | rel_expr '#' add_expr  {      | rel_expr '#' add_expr  {
989          $$ = new Relation($1, Relation::NOT_EQUAL, $3);          ExpressionRef lhs = $1;
990            ExpressionRef rhs = $3;
991            if (lhs->exprType() != INT_EXPR) {
992                PARSE_ERR(@1, (String("Left operand of operator '#' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
993                $$ = new IntLiteral(0);
994            } else if (rhs->exprType() != INT_EXPR) {
995                PARSE_ERR(@3, (String("Right operand of operator '#' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
996                $$ = new IntLiteral(0);
997            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
998                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
999            {
1000                PARSE_ERR(@2, "Operands of relative operations must have same unit.");
1001                $$ = new IntLiteral(0);
1002            } else {
1003                $$ = new Relation(lhs, Relation::NOT_EQUAL, rhs);
1004            }
1005      }      }
1006    
1007  add_expr:  add_expr:
# Line 731  add_expr: Line 1015  add_expr:
1015          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1016              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1017              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1018            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
1019                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
1020            {
1021                PARSE_ERR(@2, "Operands of '+' operations must have same unit.");
1022                $$ = new IntLiteral(0);
1023          } else {          } else {
1024              $$ = new Add(lhs,rhs);              $$ = new Add(lhs,rhs);
1025          }          }
# Line 744  add_expr: Line 1033  add_expr:
1033          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1034              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1035              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1036            } else if (lhs->asInt()->unitType()   != rhs->asInt()->unitType() ||
1037                       lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor())
1038            {
1039                PARSE_ERR(@2, "Operands of '-' operations must have same unit.");
1040                $$ = new IntLiteral(0);
1041          } else {          } else {
1042              $$ = new Sub(lhs,rhs);              $$ = new Sub(lhs,rhs);
1043          }          }
# Line 760  mul_expr: Line 1054  mul_expr:
1054          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
1055              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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1056              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1057            } else if (lhs->asInt()->unitType() && rhs->asInt()->unitType()) {
1058                PARSE_ERR(@2, "Only one operand of operator '*' may have a unit type");
1059                $$ = new IntLiteral(0);
1060            } else if (lhs->asInt()->unitPrefix(0) && rhs->asInt()->unitPrefix(0)) {
1061                PARSE_ERR(@2, "Only one operand of operator '*' may have a unit prefix");
1062                $$ = new IntLiteral(0);
1063          } else {          } else {
1064              $$ = new Mul(lhs,rhs);              $$ = new Mul(lhs,rhs);
1065          }          }
# Line 773  mul_expr: Line 1073  mul_expr:
1073          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
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 an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
1075              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1076            } else if (lhs->asInt()->unitType() && rhs->asInt()->unitType() &&
1077                       lhs->asInt()->unitType() != rhs->asInt()->unitType())
1078            {
1079                PARSE_ERR(@2, "Operands of operator '/' with two different unit types.");
1080                $$ = new IntLiteral(0);
1081            } else if (!lhs->asInt()->unitType() && rhs->asInt()->unitType()) {
1082                PARSE_ERR(@3, ("Dividing left operand without any unit type by right operand with unit type " + typeStr(rhs->exprType()) + " is not possible.").c_str());
1083                $$ = new IntLiteral(0);
1084            } else if (lhs->asInt()->unitFactor()  != rhs->asInt()->unitFactor() &&
1085                       lhs->asInt()->unitPrefix(0) && rhs->asInt()->unitPrefix(0))
1086            {
1087                PARSE_ERR(@2, "Dividing two operands with two different unit prefixes is not possible.");
1088                $$ = new IntLiteral(0);
1089            } else if (lhs->asInt()->unitFactor() != rhs->asInt()->unitFactor() &&
1090                       rhs->asInt()->unitPrefix(0))
1091            {
1092                PARSE_ERR(@3, "Dividing left operand without any unit prefix by right operand with unit prefix is not possible.");
1093                $$ = new IntLiteral(0);
1094          } else {          } else {
1095              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
1096          }          }
# Line 787  mul_expr: Line 1105  mul_expr:
1105              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());
1106              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
1107          } else {          } else {
1108                if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0))
1109                    PARSE_ERR(@1, "Operands of modulo operator must not use any unit.");
1110                if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0))
1111                    PARSE_ERR(@3, "Operands of modulo operator must not use any unit.");
1112              $$ = new Mod(lhs,rhs);              $$ = new Mod(lhs,rhs);
1113          }          }
1114      }      }
# Line 838  int InstrScript_tnamerr(char* yyres, con Line 1160  int InstrScript_tnamerr(char* yyres, con
1160      }      }
1161    
1162    if (! yyres)    if (! yyres)
1163      return yystrlen (yystr);      return (int) yystrlen (yystr);
1164    
1165    return yystpcpy (yyres, yystr) - yyres;    return int( yystpcpy (yyres, yystr) - yyres );
1166  }  }

Legend:
Removed from v.3052  
changed lines
  Added in v.3561

  ViewVC Help
Powered by ViewVC