/[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 2942 by schoenebeck, Wed Jul 13 15:51:06 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;                      argsOK = false;
359                      break;                      break;
360                  }                  }
# Line 356  functioncall: Line 368  functioncall:
368          ArgsRef args = new Args;          ArgsRef args = new Args;
369          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
370          if (!fn) {          if (!fn) {
371              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());
372              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
373          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
374              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());
375              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
376          } else {          } else {
377              $$ = new FunctionCall(name, args, fn);              $$ = new FunctionCall(name, args, fn);
# Line 371  functioncall: Line 383  functioncall:
383          ArgsRef args = new Args;          ArgsRef args = new Args;
384          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
385          if (!fn) {          if (!fn) {
386              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());
387              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
388          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
389              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());
390              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
391          } else {          } else {
392              $$ = new FunctionCall(name, args, fn);              $$ = new FunctionCall(name, args, fn);
# Line 400  assignment: Line 412  assignment:
412          const char* name = $1;          const char* name = $1;
413          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
414          if (!var)          if (!var)
415              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());
416          else if (var->isConstExpr())          else if (var->isConstExpr())
417              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());
418            else if (!var->isAssignable())
419                PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());
420          else if (var->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
421              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());
422          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
423      }      }
424      | VARIABLE '[' expr ']' ASSIGNMENT expr  {      | VARIABLE '[' expr ']' ASSIGNMENT expr  {
425          const char* name = $1;          const char* name = $1;
426          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
427          if (!var)          if (!var)
428              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
429          else if (var->exprType() != INT_ARR_EXPR)          else if (var->exprType() != INT_ARR_EXPR)
430              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());
431          else if ($3->exprType() != INT_EXPR)          else if ($3->exprType() != INT_EXPR)
432              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());
433          else if ($6->exprType() != INT_EXPR)          else if ($6->exprType() != INT_EXPR)
434              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());
435          IntArrayElementRef element = new IntArrayElement(var, $3);          IntArrayElementRef element = new IntArrayElement(var, $3);
436          $$ = new Assignment(element, $6);          $$ = new Assignment(element, $6);
437      }      }
# Line 435  unary_expr: Line 449  unary_expr:
449          if (var)          if (var)
450              $$ = var;              $$ = var;
451          else {          else {
452              PARSE_ERR((String("No variable declared with name '") + $1 + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
453              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
454          }          }
455      }      }
# Line 443  unary_expr: Line 457  unary_expr:
457          const char* name = $1;          const char* name = $1;
458          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
459          if (!var) {          if (!var) {
460              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
461              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
462          } else if (var->exprType() != INT_ARR_EXPR) {          } else if (var->exprType() != INT_ARR_EXPR) {
463              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());
464              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
465          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
466              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());
467              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
468          } else {          } else {
469              $$ = new IntArrayElement(var, $3);              $$ = new IntArrayElement(var, $3);
# Line 464  unary_expr: Line 478  unary_expr:
478      | '-' unary_expr  {      | '-' unary_expr  {
479          $$ = new Neg($2);          $$ = new Neg($2);
480      }      }
481        | BITWISE_NOT unary_expr  {
482            if ($2->exprType() != INT_EXPR) {
483                PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
484                $$ = new IntLiteral(0);
485            } else {
486                $$ = new BitwiseNot($2);
487            }
488        }
489      | NOT unary_expr  {      | NOT unary_expr  {
490          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
491              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());
492              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
493          } else {          } else {
494              $$ = new Not($2);              $$ = new Not($2);
# Line 477  expr: Line 499  expr:
499      concat_expr      concat_expr
500    
501  concat_expr:  concat_expr:
502      or_expr      logical_or_expr
503      | concat_expr '&' or_expr  {      | concat_expr '&' logical_or_expr  {
504          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
505          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
506          if (lhs->isConstExpr() && rhs->isConstExpr()) {          if (lhs->isConstExpr() && rhs->isConstExpr()) {
# Line 490  concat_expr: Line 512  concat_expr:
512          }          }
513      }      }
514    
515  or_expr:  logical_or_expr:
516      and_expr      logical_and_expr
517      | or_expr OR and_expr  {      | logical_or_expr OR logical_and_expr  {
518          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
519          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
520          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
521              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());
522              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
523          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
524              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());
525              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
526          } else {          } else {
527              $$ = new Or(lhs, rhs);              $$ = new Or(lhs, rhs);
528          }          }
529      }      }
530    
531  and_expr:  logical_and_expr:
532      rel_expr  {      bitwise_or_expr  {
533          $$ = $1;          $$ = $1;
534      }      }
535      | and_expr AND rel_expr  {      | logical_and_expr AND bitwise_or_expr  {
536          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
537          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
538          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
539              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());
540              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
541          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
542              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());
543              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
544          } else {          } else {
545              $$ = new And(lhs, rhs);              $$ = new And(lhs, rhs);
546          }          }
547      }      }
548    
549    bitwise_or_expr:
550        bitwise_and_expr
551        | bitwise_or_expr BITWISE_OR bitwise_and_expr  {
552            ExpressionRef lhs = $1;
553            ExpressionRef rhs = $3;
554            if (lhs->exprType() != INT_EXPR) {
555                PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
556                $$ = new IntLiteral(0);
557            } else if (rhs->exprType() != INT_EXPR) {
558                PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
559                $$ = new IntLiteral(0);
560            } else {
561                $$ = new BitwiseOr(lhs, rhs);
562            }
563        }
564    
565    bitwise_and_expr:
566        rel_expr  {
567            $$ = $1;
568        }
569        | bitwise_and_expr BITWISE_AND rel_expr  {
570            ExpressionRef lhs = $1;
571            ExpressionRef rhs = $3;
572            if (lhs->exprType() != INT_EXPR) {
573                PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
574                $$ = new IntLiteral(0);
575            } else if (rhs->exprType() != INT_EXPR) {
576                PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
577                $$ = new IntLiteral(0);
578            } else {
579                $$ = new BitwiseAnd(lhs, rhs);
580            }
581        }
582    
583  rel_expr:  rel_expr:
584        add_expr        add_expr
585      | rel_expr '<' add_expr  {      | rel_expr '<' add_expr  {
586          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
587          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
588          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
589              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());
590              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
591          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
592              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());
593              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
594          } else {          } else {
595              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
# Line 543  rel_expr: Line 599  rel_expr:
599          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
600          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
601          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
602              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());
603              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
604          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
605              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());
606              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
607          } else {          } else {
608              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
# Line 556  rel_expr: Line 612  rel_expr:
612          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
613          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
614          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
615              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());
616              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
617          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
618              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());
619              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
620          } else {          } else {
621              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
# Line 569  rel_expr: Line 625  rel_expr:
625          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
626          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
627          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
628              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());
629              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
630          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
631              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());
632              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
633          } else {          } else {
634              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
# Line 591  add_expr: Line 647  add_expr:
647          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
648          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
649          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
650              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());
651              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
652          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
653              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());
654              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
655          } else {          } else {
656              $$ = new Add(lhs,rhs);              $$ = new Add(lhs,rhs);
# Line 604  add_expr: Line 660  add_expr:
660          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
661          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
662          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
663              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());
664              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
665          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
666              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());
667              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
668          } else {          } else {
669              $$ = new Sub(lhs,rhs);              $$ = new Sub(lhs,rhs);
# Line 620  mul_expr: Line 676  mul_expr:
676          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
677          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
678          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
679              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());
680              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
681          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
682              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());
683              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
684          } else {          } else {
685              $$ = new Mul(lhs,rhs);              $$ = new Mul(lhs,rhs);
# Line 633  mul_expr: Line 689  mul_expr:
689          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
690          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
691          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
692              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());
693              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
694          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
695              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());
696              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
697          } else {          } else {
698              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
# Line 646  mul_expr: Line 702  mul_expr:
702          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
703          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
704          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
705              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());
706              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
707          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
708              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());
709              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
710          } else {          } else {
711              $$ = new Mod(lhs,rhs);              $$ = new Mod(lhs,rhs);
# Line 660  mul_expr: Line 716  mul_expr:
716    
717  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
718      //fprintf(stderr, "%d: %s\n", locp->first_line, err);      //fprintf(stderr, "%d: %s\n", locp->first_line, err);
719      context->addErr(locp->first_line, err);      context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err);
720  }  }
721    
722  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
723      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
724      context->addWrn(locp->first_line, txt);      context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt);
725  }  }

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

  ViewVC Help
Powered by ViewVC