/[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 2581 by schoenebeck, Fri May 30 12:48:05 2014 UTC revision 2945 by schoenebeck, Thu Jul 14 00:22:26 2016 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck and Andreas Persson   * Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
6   * This file is part of LinuxSampler and released under the same terms.   * This file is part of LinuxSampler and released under the same terms.
7   * See README file for details.   * See README file for details.
8   */   */
9    
10    /* Parser for NKSP real-time instrument script language. */
11    
12  %{  %{
13      #define YYERROR_VERBOSE 1      #define YYERROR_VERBOSE 1
# Line 18  Line 20 
20      void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt);      void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt);
21      int InstrScript_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);      int InstrScript_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
22      #define scanner context->scanner      #define scanner context->scanner
23      #define PARSE_ERR(txt)  yyerror(&yylloc, context, txt)      #define PARSE_ERR(loc,txt)  yyerror(&loc, context, txt)
24      #define PARSE_WRN(txt)  InstrScript_warning(&yylloc, context, txt)      #define PARSE_WRN(loc,txt)  InstrScript_warning(&loc, context, txt)
25  %}  %}
26    
27  // generate reentrant safe parser  // generate reentrant safe parser
# Line 37  Line 39 
39  %token <sValue> IDENTIFIER  %token <sValue> IDENTIFIER
40  %token <sValue> VARIABLE  %token <sValue> VARIABLE
41  %token ON END INIT NOTE DECLARE ASSIGNMENT WHILE IF OR RELEASE AND ELSE  %token ON END INIT NOTE DECLARE ASSIGNMENT WHILE IF OR RELEASE AND ELSE
42  %token CONTROLLER SELECT CASE TO NOT CONST POLYPHONIC MOD  %token BITWISE_OR BITWISE_AND BITWISE_NOT
43    %token CONTROLLER SELECT CASE TO NOT CONST_ POLYPHONIC MOD
44  %token LE GE  %token LE GE
45    
46  %type <nEventHandlers> script eventhandlers  %type <nEventHandlers> script eventhandlers
47  %type <nEventHandler> eventhandler  %type <nEventHandler> eventhandler
48  %type <nStatements> statements  %type <nStatements> statements body
49  %type <nStatement> statement assignment  %type <nStatement> statement assignment
50  %type <nFunctionCall> functioncall  %type <nFunctionCall> functioncall
51  %type <nArgs> args  %type <nArgs> args
52  %type <nExpression> arg expr or_expr and_expr rel_expr add_expr mul_expr unary_expr concat_expr  %type <nExpression> arg expr logical_or_expr logical_and_expr bitwise_or_expr bitwise_and_expr rel_expr add_expr mul_expr unary_expr concat_expr
53  %type <nCaseBranch> caseclause  %type <nCaseBranch> caseclause
54  %type <nCaseBranches> caseclauses  %type <nCaseBranches> caseclauses
55    
# Line 70  eventhandlers: Line 73  eventhandlers:
73      }      }
74    
75  eventhandler:  eventhandler:
76      ON NOTE statements END ON  {      ON NOTE body END ON  {
77          if (context->onNote)          if (context->onNote)
78              PARSE_ERR("Redeclaration of 'note' event handler.");              PARSE_ERR(@2, "Redeclaration of 'note' event handler.");
79          context->onNote = new OnNote($3);          context->onNote = new OnNote($3);
80          $$ = context->onNote;          $$ = context->onNote;
81      }      }
82      | ON INIT statements END ON  {      | ON INIT body END ON  {
83          if (context->onInit)          if (context->onInit)
84              PARSE_ERR("Redeclaration of 'init' event handler.");              PARSE_ERR(@2, "Redeclaration of 'init' event handler.");
85          context->onInit = new OnInit($3);          context->onInit = new OnInit($3);
86          $$ = context->onInit;          $$ = context->onInit;
87      }      }
88      | ON RELEASE statements END ON  {      | ON RELEASE body END ON  {
89          if (context->onRelease)          if (context->onRelease)
90              PARSE_ERR("Redeclaration of 'release' event handler.");              PARSE_ERR(@2, "Redeclaration of 'release' event handler.");
91          context->onRelease = new OnRelease($3);          context->onRelease = new OnRelease($3);
92          $$ = context->onRelease;          $$ = context->onRelease;
93      }      }
94      | ON CONTROLLER statements END ON  {      | ON CONTROLLER body END ON  {
95          if (context->onController)          if (context->onController)
96              PARSE_ERR("Redeclaration of 'controller' event handler.");              PARSE_ERR(@2, "Redeclaration of 'controller' event handler.");
97          context->onController = new OnController($3);          context->onController = new OnController($3);
98          $$ = context->onController;          $$ = context->onController;
99      }      }
100    
101    body:
102        /* epsilon (empty argument) */  {
103            $$ = new Statements();
104        }
105        | statements  {
106            $$ = $1;
107        }
108    
109  statements:  statements:
110      statement  {      statement  {
111          $$ = new Statements();          $$ = new Statements();
112          if ($1) {          if ($1) {
113              if (!isNoOperation($1)) $$->add($1); // filter out NoOperation statements              if (!isNoOperation($1)) $$->add($1); // filter out NoOperation statements
114          } else          } else
115              PARSE_WRN("Not a statement.");              PARSE_WRN(@1, "Not a statement.");
116      }      }
117      | statements statement  {      | statements statement  {
118          $$ = $1;          $$ = $1;
119          if ($2) {          if ($2) {
120              if (!isNoOperation($2)) $$->add($2); // filter out NoOperation statements              if (!isNoOperation($2)) $$->add($2); // filter out NoOperation statements
121          } else          } else
122              PARSE_WRN("Not a statement.");              PARSE_WRN(@2, "Not a statement.");
123      }      }
124    
125  statement:  statement:
# Line 119  statement: Line 130  statement:
130          const char* name = $2;          const char* name = $2;
131          //printf("declared var '%s'\n", name);          //printf("declared var '%s'\n", name);
132          if (context->variableByName(name))          if (context->variableByName(name))
133              PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
134          if (name[0] == '@') {          if (name[0] == '@') {
135              context->vartable[name] = new StringVariable(context);              context->vartable[name] = new StringVariable(context);
136              $$ = new NoOperation;              $$ = new NoOperation;
# Line 132  statement: Line 143  statement:
143          const char* name = $3;          const char* name = $3;
144          //printf("declared polyphonic var '%s'\n", name);          //printf("declared polyphonic var '%s'\n", name);
145          if (context->variableByName(name))          if (context->variableByName(name))
146              PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str());
147          if (name[0] != '$') {          if (name[0] != '$') {
148              PARSE_ERR("Polyphonic variables may only be declared as integers.");              PARSE_ERR(@3, "Polyphonic variables may only be declared as integers.");
149              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
150          } else {          } else {
151              context->vartable[name] = new PolyphonicIntVariable(context);              context->vartable[name] = new PolyphonicIntVariable(context);
# Line 145  statement: Line 156  statement:
156          const char* name = $2;          const char* name = $2;
157          //printf("declared assign var '%s'\n", name);          //printf("declared assign var '%s'\n", name);
158          if (context->variableByName(name))          if (context->variableByName(name))
159              PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
160          if ($4->exprType() == STRING_EXPR) {          if ($4->exprType() == STRING_EXPR) {
161              if (name[0] == '$')              if (name[0] == '$')
162                  PARSE_WRN((String("Variable '") + name + "' declared as integer, string expression assigned though.").c_str());                  PARSE_WRN(@2, (String("Variable '") + name + "' declared as integer, string expression assigned though.").c_str());
163              StringExprRef expr = $4;              StringExprRef expr = $4;
164              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
165                  const String s = expr->evalStr();                  const String s = expr->evalStr();
# Line 162  statement: Line 173  statement:
173              }              }
174          } else {          } else {
175              if (name[0] == '@')              if (name[0] == '@')
176                  PARSE_WRN((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());
177              IntExprRef expr = $4;              IntExprRef expr = $4;
178              if (expr->isConstExpr()) {              if (expr->isConstExpr()) {
179                  const int i = expr->evalInt();                  const int i = expr->evalInt();
# Line 180  statement: Line 191  statement:
191          //printf("declare array without args\n");          //printf("declare array without args\n");
192          const char* name = $2;          const char* name = $2;
193          if (!$4->isConstExpr()) {          if (!$4->isConstExpr()) {
194              PARSE_ERR((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());
195              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
196          } else if ($4->exprType() != INT_EXPR) {          } else if ($4->exprType() != INT_EXPR) {
197              PARSE_ERR((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());
198              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
199          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
200              PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
201              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
202          } else {          } else {
203              IntExprRef expr = $4;              IntExprRef expr = $4;
204              int size = expr->evalInt();              int size = expr->evalInt();
205              if (size <= 0) {              if (size <= 0) {
206                  PARSE_ERR((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());
207                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever
208              } else {              } else {
209                  context->vartable[name] = new IntArrayVariable(context, size);                  context->vartable[name] = new IntArrayVariable(context, size);
# Line 203  statement: Line 214  statement:
214      | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {      | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')'  {
215          const char* name = $2;          const char* name = $2;
216          if (!$4->isConstExpr()) {          if (!$4->isConstExpr()) {
217              PARSE_ERR((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());
218              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
219          } else if ($4->exprType() != INT_EXPR) {          } else if ($4->exprType() != INT_EXPR) {
220              PARSE_ERR((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());
221              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
222          } else if (context->variableByName(name)) {          } else if (context->variableByName(name)) {
223              PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str());
224              $$ = new FunctionCall("nothing", new Args, NULL); // whatever              $$ = new FunctionCall("nothing", new Args, NULL); // whatever
225          } else {          } else {
226              IntExprRef sizeExpr = $4;              IntExprRef sizeExpr = $4;
227              ArgsRef args = $8;              ArgsRef args = $8;
228              int size = sizeExpr->evalInt();              int size = sizeExpr->evalInt();
229              if (size <= 0) {              if (size <= 0) {
230                  PARSE_ERR((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());
231                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever                  $$ = new FunctionCall("nothing", new Args, NULL); // whatever
232              } else if (args->argsCount() > size) {              } else if (args->argsCount() > size) {
233                  PARSE_ERR((String("Variable '") + name +                  PARSE_ERR(@8, (String("Variable '") + name +
234                            "' was declared with size " + ToString(size) +                            "' was declared with size " + ToString(size) +
235                            " but " + ToString(args->argsCount()) +                            " but " + ToString(args->argsCount()) +
236                            " values were assigned." ).c_str());                            " values were assigned." ).c_str());
# Line 229  statement: Line 240  statement:
240                  for (int i = 0; i < args->argsCount(); ++i) {                  for (int i = 0; i < args->argsCount(); ++i) {
241                      if (args->arg(i)->exprType() != INT_EXPR) {                      if (args->arg(i)->exprType() != INT_EXPR) {
242                          PARSE_ERR(                          PARSE_ERR(
243                                @8,
244                              (String("Array variable '") + name +                              (String("Array variable '") + name +
245                              "' declared with invalid assignment values. Assigned element " +                              "' declared with invalid assignment values. Assigned element " +
246                              ToString(i+1) + " is not an integer expression.").c_str()                              ToString(i+1) + " is not an integer expression.").c_str()
# Line 244  statement: Line 256  statement:
256              }              }
257          }          }
258      }      }
259      | DECLARE CONST VARIABLE ASSIGNMENT expr  {      | DECLARE CONST_ VARIABLE ASSIGNMENT expr  {
260          const char* name = $3;          const char* name = $3;
261          if ($5->exprType() == STRING_EXPR) {          if ($5->exprType() == STRING_EXPR) {
262              if (name[0] == '$')              if (name[0] == '$')
263                  PARSE_WRN("Variable declared as integer, string expression assigned though.");                  PARSE_WRN(@5, "Variable declared as integer, string expression assigned though.");
264              String s;              String s;
265              StringExprRef expr = $5;              StringExprRef expr = $5;
266              if (expr->isConstExpr())              if (expr->isConstExpr())
267                  s = expr->evalStr();                  s = expr->evalStr();
268              else              else
269                  PARSE_ERR((String("Assignment to const string variable '") + name + "' requires const expression.").c_str());                  PARSE_ERR(@5, (String("Assignment to const string variable '") + name + "' requires const expression.").c_str());
270              ConstStringVariableRef var = new ConstStringVariable(context, s);              ConstStringVariableRef var = new ConstStringVariable(context, s);
271              context->vartable[name] = var;              context->vartable[name] = var;
272              //$$ = new Assignment(var, new StringLiteral(s));              //$$ = new Assignment(var, new StringLiteral(s));
273              $$ = new NoOperation();              $$ = new NoOperation();
274          } else {          } else {
275              if (name[0] == '@')              if (name[0] == '@')
276                  PARSE_WRN("Variable declared as string, integer expression assigned though.");                  PARSE_WRN(@5, "Variable declared as string, integer expression assigned though.");
277              int i = 0;              int i = 0;
278              IntExprRef expr = $5;              IntExprRef expr = $5;
279              if (expr->isConstExpr())              if (expr->isConstExpr())
280                  i = expr->evalInt();                  i = expr->evalInt();
281              else              else
282                  PARSE_ERR((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());
283              ConstIntVariableRef var = new ConstIntVariable(i);              ConstIntVariableRef var = new ConstIntVariable(i);
284              context->vartable[name] = var;              context->vartable[name] = var;
285              //$$ = new Assignment(var, new IntLiteral(i));              //$$ = new Assignment(var, new IntLiteral(i));
# Line 281  statement: Line 293  statement:
293          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
294              $$ = new While($3, $5);              $$ = new While($3, $5);
295          } else {          } else {
296              PARSE_ERR("Condition for 'while' loops must be integer expression.");              PARSE_ERR(@3, "Condition for 'while' loops must be integer expression.");
297              $$ = new While(new IntLiteral(0), $5);              $$ = new While(new IntLiteral(0), $5);
298          }          }
299      }      }
# Line 295  statement: Line 307  statement:
307          if ($2->exprType() == INT_EXPR) {          if ($2->exprType() == INT_EXPR) {
308              $$ = new SelectCase($2, $3);              $$ = new SelectCase($2, $3);
309          } else {          } else {
310              PARSE_ERR("Statement 'select' can only by applied to integer expressions.");              PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions.");
311              $$ = new SelectCase(new IntLiteral(0), $3);              $$ = new SelectCase(new IntLiteral(0), $3);
312          }          }
313      }      }
# Line 330  functioncall: Line 342  functioncall:
342          ArgsRef args = $3;          ArgsRef args = $3;
343          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
344          if (!fn) {          if (!fn) {
345              PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
346              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
347          } else if (args->argsCount() < fn->minRequiredArgs()) {          } else if (args->argsCount() < fn->minRequiredArgs()) {
348              PARSE_ERR((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());
349              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
350          } else if (args->argsCount() > fn->maxAllowedArgs()) {          } else if (args->argsCount() > fn->maxAllowedArgs()) {
351              PARSE_ERR((String("Built-in function '") + name + "' accepts max. " + ToString(fn->maxAllowedArgs()) + " arguments.").c_str());              PARSE_ERR(@3, (String("Built-in function '") + name + "' accepts max. " + ToString(fn->maxAllowedArgs()) + " arguments.").c_str());
352              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
353          } else {          } else {
354              bool argsOK = true;              bool argsOK = true;
355              for (int i = 0; i < args->argsCount(); ++i) {              for (int i = 0; i < args->argsCount(); ++i) {
356                  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())) {
357                      PARSE_ERR((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());
358                        argsOK = false;
359                        break;
360                    } else if (fn->modifiesArg(i) && !args->arg(i)->isModifyable()) {
361                        PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects an assignable variable.").c_str());
362                      argsOK = false;                      argsOK = false;
363                      break;                      break;
364                  }                  }
# Line 356  functioncall: Line 372  functioncall:
372          ArgsRef args = new Args;          ArgsRef args = new Args;
373          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
374          if (!fn) {          if (!fn) {
375              PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
376              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
377          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
378              PARSE_ERR((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());
379              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
380          } else {          } else {
381              $$ = new FunctionCall(name, args, fn);              $$ = new FunctionCall(name, args, fn);
# Line 371  functioncall: Line 387  functioncall:
387          ArgsRef args = new Args;          ArgsRef args = new Args;
388          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
389          if (!fn) {          if (!fn) {
390              PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
391              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
392          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
393              PARSE_ERR((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());
394              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
395          } else {          } else {
396              $$ = new FunctionCall(name, args, fn);              $$ = new FunctionCall(name, args, fn);
# Line 400  assignment: Line 416  assignment:
416          const char* name = $1;          const char* name = $1;
417          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
418          if (!var)          if (!var)
419              PARSE_ERR((String("Variable assignment: No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("Variable assignment: No variable declared with name '") + name + "'.").c_str());
420          else if (var->isConstExpr())          else if (var->isConstExpr())
421              PARSE_ERR((String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());
422            else if (!var->isAssignable())
423                PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());
424          else if (var->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
425              PARSE_ERR((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());
426          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
427      }      }
428      | VARIABLE '[' expr ']' ASSIGNMENT expr  {      | VARIABLE '[' expr ']' ASSIGNMENT expr  {
429          const char* name = $1;          const char* name = $1;
430          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
431          if (!var)          if (!var)
432              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
433          else if (var->exprType() != INT_ARR_EXPR)          else if (var->exprType() != INT_ARR_EXPR)
434              PARSE_ERR((String("Variable '") + name + "' is not an array variable.").c_str());              PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
435          else if ($3->exprType() != INT_EXPR)          else if ($3->exprType() != INT_EXPR)
436              PARSE_ERR((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());
437          else if ($6->exprType() != INT_EXPR)          else if ($6->exprType() != INT_EXPR)
438              PARSE_ERR((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());
439          IntArrayElementRef element = new IntArrayElement(var, $3);          IntArrayElementRef element = new IntArrayElement(var, $3);
440          $$ = new Assignment(element, $6);          $$ = new Assignment(element, $6);
441      }      }
# Line 435  unary_expr: Line 453  unary_expr:
453          if (var)          if (var)
454              $$ = var;              $$ = var;
455          else {          else {
456              PARSE_ERR((String("No variable declared with name '") + $1 + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
457              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
458          }          }
459      }      }
# Line 443  unary_expr: Line 461  unary_expr:
461          const char* name = $1;          const char* name = $1;
462          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
463          if (!var) {          if (!var) {
464              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
465              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
466          } else if (var->exprType() != INT_ARR_EXPR) {          } else if (var->exprType() != INT_ARR_EXPR) {
467              PARSE_ERR((String("Variable '") + name + "' is not an array variable.").c_str());              PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str());
468              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
469          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
470              PARSE_ERR((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());
471              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
472          } else {          } else {
473              $$ = new IntArrayElement(var, $3);              $$ = new IntArrayElement(var, $3);
# Line 464  unary_expr: Line 482  unary_expr:
482      | '-' unary_expr  {      | '-' unary_expr  {
483          $$ = new Neg($2);          $$ = new Neg($2);
484      }      }
485        | BITWISE_NOT unary_expr  {
486            if ($2->exprType() != INT_EXPR) {
487                PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
488                $$ = new IntLiteral(0);
489            } else {
490                $$ = new BitwiseNot($2);
491            }
492        }
493      | NOT unary_expr  {      | NOT unary_expr  {
494          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
495              PARSE_ERR((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());
496              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
497          } else {          } else {
498              $$ = new Not($2);              $$ = new Not($2);
# Line 477  expr: Line 503  expr:
503      concat_expr      concat_expr
504    
505  concat_expr:  concat_expr:
506      or_expr      logical_or_expr
507      | concat_expr '&' or_expr  {      | concat_expr '&' logical_or_expr  {
508          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
509          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
510          if (lhs->isConstExpr() && rhs->isConstExpr()) {          if (lhs->isConstExpr() && rhs->isConstExpr()) {
# Line 490  concat_expr: Line 516  concat_expr:
516          }          }
517      }      }
518    
519  or_expr:  logical_or_expr:
520      and_expr      logical_and_expr
521      | or_expr OR and_expr  {      | logical_or_expr OR logical_and_expr  {
522          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
523          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
524          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
525              PARSE_ERR((String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
526              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
527          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
528              PARSE_ERR((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());
529              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
530          } else {          } else {
531              $$ = new Or(lhs, rhs);              $$ = new Or(lhs, rhs);
532          }          }
533      }      }
534    
535  and_expr:  logical_and_expr:
536      rel_expr  {      bitwise_or_expr  {
537          $$ = $1;          $$ = $1;
538      }      }
539      | and_expr AND rel_expr  {      | logical_and_expr AND bitwise_or_expr  {
540          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
541          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
542          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
543              PARSE_ERR((String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
544              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
545          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
546              PARSE_ERR((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());
547              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
548          } else {          } else {
549              $$ = new And(lhs, rhs);              $$ = new And(lhs, rhs);
550          }          }
551      }      }
552    
553    bitwise_or_expr:
554        bitwise_and_expr
555        | bitwise_or_expr BITWISE_OR bitwise_and_expr  {
556            ExpressionRef lhs = $1;
557            ExpressionRef rhs = $3;
558            if (lhs->exprType() != INT_EXPR) {
559                PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
560                $$ = new IntLiteral(0);
561            } else if (rhs->exprType() != INT_EXPR) {
562                PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
563                $$ = new IntLiteral(0);
564            } else {
565                $$ = new BitwiseOr(lhs, rhs);
566            }
567        }
568    
569    bitwise_and_expr:
570        rel_expr  {
571            $$ = $1;
572        }
573        | bitwise_and_expr BITWISE_AND rel_expr  {
574            ExpressionRef lhs = $1;
575            ExpressionRef rhs = $3;
576            if (lhs->exprType() != INT_EXPR) {
577                PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
578                $$ = new IntLiteral(0);
579            } else if (rhs->exprType() != INT_EXPR) {
580                PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
581                $$ = new IntLiteral(0);
582            } else {
583                $$ = new BitwiseAnd(lhs, rhs);
584            }
585        }
586    
587  rel_expr:  rel_expr:
588        add_expr        add_expr
589      | rel_expr '<' add_expr  {      | rel_expr '<' add_expr  {
590          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
591          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
592          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
593              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
594              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
595          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
596              PARSE_ERR((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());
597              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
598          } else {          } else {
599              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
# Line 543  rel_expr: Line 603  rel_expr:
603          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
604          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
605          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
606              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
607              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
608          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
609              PARSE_ERR((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());
610              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
611          } else {          } else {
612              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
# Line 556  rel_expr: Line 616  rel_expr:
616          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
617          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
618          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
619              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
620              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
621          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
622              PARSE_ERR((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());
623              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
624          } else {          } else {
625              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
# Line 569  rel_expr: Line 629  rel_expr:
629          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
630          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
631          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
632              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
633              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
634          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
635              PARSE_ERR((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());
636              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
637          } else {          } else {
638              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
# Line 591  add_expr: Line 651  add_expr:
651          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
652          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
653          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
654              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
655              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
656          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
657              PARSE_ERR((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());
658              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
659          } else {          } else {
660              $$ = new Add(lhs,rhs);              $$ = new Add(lhs,rhs);
# Line 604  add_expr: Line 664  add_expr:
664          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
665          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
666          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
667              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
668              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
669          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
670              PARSE_ERR((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());
671              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
672          } else {          } else {
673              $$ = new Sub(lhs,rhs);              $$ = new Sub(lhs,rhs);
# Line 620  mul_expr: Line 680  mul_expr:
680          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
681          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
682          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
683              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
684              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
685          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
686              PARSE_ERR((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());
687              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
688          } else {          } else {
689              $$ = new Mul(lhs,rhs);              $$ = new Mul(lhs,rhs);
# Line 633  mul_expr: Line 693  mul_expr:
693          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
694          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
695          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
696              PARSE_ERR((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 an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
697              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
698          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
699              PARSE_ERR((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());
700              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
701          } else {          } else {
702              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
# Line 646  mul_expr: Line 706  mul_expr:
706          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
707          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
708          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
709              PARSE_ERR((String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());              PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
710              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
711          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
712              PARSE_ERR((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());
713              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
714          } else {          } else {
715              $$ = new Mod(lhs,rhs);              $$ = new Mod(lhs,rhs);
# Line 660  mul_expr: Line 720  mul_expr:
720    
721  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
722      //fprintf(stderr, "%d: %s\n", locp->first_line, err);      //fprintf(stderr, "%d: %s\n", locp->first_line, err);
723      context->addErr(locp->first_line, err);      context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err);
724  }  }
725    
726  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
727      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
728      context->addWrn(locp->first_line, txt);      context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt);
729  }  }

Legend:
Removed from v.2581  
changed lines
  Added in v.2945

  ViewVC Help
Powered by ViewVC