/[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 2935 by schoenebeck, Sun Jul 10 14:24:13 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->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
419              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());
420          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
421      }      }
422      | VARIABLE '[' expr ']' ASSIGNMENT expr  {      | VARIABLE '[' expr ']' ASSIGNMENT expr  {
423          const char* name = $1;          const char* name = $1;
424          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
425          if (!var)          if (!var)
426              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
427          else if (var->exprType() != INT_ARR_EXPR)          else if (var->exprType() != INT_ARR_EXPR)
428              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());
429          else if ($3->exprType() != INT_EXPR)          else if ($3->exprType() != INT_EXPR)
430              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());
431          else if ($6->exprType() != INT_EXPR)          else if ($6->exprType() != INT_EXPR)
432              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());
433          IntArrayElementRef element = new IntArrayElement(var, $3);          IntArrayElementRef element = new IntArrayElement(var, $3);
434          $$ = new Assignment(element, $6);          $$ = new Assignment(element, $6);
435      }      }
# Line 435  unary_expr: Line 447  unary_expr:
447          if (var)          if (var)
448              $$ = var;              $$ = var;
449          else {          else {
450              PARSE_ERR((String("No variable declared with name '") + $1 + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str());
451              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
452          }          }
453      }      }
# Line 443  unary_expr: Line 455  unary_expr:
455          const char* name = $1;          const char* name = $1;
456          VariableRef var = context->variableByName(name);          VariableRef var = context->variableByName(name);
457          if (!var) {          if (!var) {
458              PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str());
459              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
460          } else if (var->exprType() != INT_ARR_EXPR) {          } else if (var->exprType() != INT_ARR_EXPR) {
461              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());
462              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
463          } else if ($3->exprType() != INT_EXPR) {          } else if ($3->exprType() != INT_EXPR) {
464              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());
465              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
466          } else {          } else {
467              $$ = new IntArrayElement(var, $3);              $$ = new IntArrayElement(var, $3);
# Line 464  unary_expr: Line 476  unary_expr:
476      | '-' unary_expr  {      | '-' unary_expr  {
477          $$ = new Neg($2);          $$ = new Neg($2);
478      }      }
479        | BITWISE_NOT unary_expr  {
480            if ($2->exprType() != INT_EXPR) {
481                PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
482                $$ = new IntLiteral(0);
483            } else {
484                $$ = new BitwiseNot($2);
485            }
486        }
487      | NOT unary_expr  {      | NOT unary_expr  {
488          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
489              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());
490              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
491          } else {          } else {
492              $$ = new Not($2);              $$ = new Not($2);
# Line 477  expr: Line 497  expr:
497      concat_expr      concat_expr
498    
499  concat_expr:  concat_expr:
500      or_expr      logical_or_expr
501      | concat_expr '&' or_expr  {      | concat_expr '&' logical_or_expr  {
502          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
503          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
504          if (lhs->isConstExpr() && rhs->isConstExpr()) {          if (lhs->isConstExpr() && rhs->isConstExpr()) {
# Line 490  concat_expr: Line 510  concat_expr:
510          }          }
511      }      }
512    
513  or_expr:  logical_or_expr:
514      and_expr      logical_and_expr
515      | or_expr OR and_expr  {      | logical_or_expr OR logical_and_expr  {
516          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
517          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
518          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
519              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());
520              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
521          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
522              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());
523              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
524          } else {          } else {
525              $$ = new Or(lhs, rhs);              $$ = new Or(lhs, rhs);
526          }          }
527      }      }
528    
529  and_expr:  logical_and_expr:
530      rel_expr  {      bitwise_or_expr  {
531          $$ = $1;          $$ = $1;
532      }      }
533      | and_expr AND rel_expr  {      | logical_and_expr AND bitwise_or_expr  {
534          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
535          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
536          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
537              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());
538              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
539          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
540              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());
541              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
542          } else {          } else {
543              $$ = new And(lhs, rhs);              $$ = new And(lhs, rhs);
544          }          }
545      }      }
546    
547    bitwise_or_expr:
548        bitwise_and_expr
549        | bitwise_or_expr BITWISE_OR bitwise_and_expr  {
550            ExpressionRef lhs = $1;
551            ExpressionRef rhs = $3;
552            if (lhs->exprType() != INT_EXPR) {
553                PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
554                $$ = new IntLiteral(0);
555            } else if (rhs->exprType() != INT_EXPR) {
556                PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
557                $$ = new IntLiteral(0);
558            } else {
559                $$ = new BitwiseOr(lhs, rhs);
560            }
561        }
562    
563    bitwise_and_expr:
564        rel_expr  {
565            $$ = $1;
566        }
567        | bitwise_and_expr BITWISE_AND rel_expr  {
568            ExpressionRef lhs = $1;
569            ExpressionRef rhs = $3;
570            if (lhs->exprType() != INT_EXPR) {
571                PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
572                $$ = new IntLiteral(0);
573            } else if (rhs->exprType() != INT_EXPR) {
574                PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
575                $$ = new IntLiteral(0);
576            } else {
577                $$ = new BitwiseAnd(lhs, rhs);
578            }
579        }
580    
581  rel_expr:  rel_expr:
582        add_expr        add_expr
583      | rel_expr '<' add_expr  {      | rel_expr '<' add_expr  {
584          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
585          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
586          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
587              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());
588              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
589          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
590              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());
591              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
592          } else {          } else {
593              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);              $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
# Line 543  rel_expr: Line 597  rel_expr:
597          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
598          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
599          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
600              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());
601              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
602          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
603              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());
604              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
605          } else {          } else {
606              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);              $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
# Line 556  rel_expr: Line 610  rel_expr:
610          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
611          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
612          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
613              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());
614              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
615          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
616              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());
617              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
618          } else {          } else {
619              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
# Line 569  rel_expr: Line 623  rel_expr:
623          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
624          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
625          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
626              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());
627              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
628          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
629              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());
630              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
631          } else {          } else {
632              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);              $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
# Line 591  add_expr: Line 645  add_expr:
645          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
646          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
647          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
648              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());
649              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
650          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
651              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());
652              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
653          } else {          } else {
654              $$ = new Add(lhs,rhs);              $$ = new Add(lhs,rhs);
# Line 604  add_expr: Line 658  add_expr:
658          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
659          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
660          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
661              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());
662              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
663          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
664              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());
665              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
666          } else {          } else {
667              $$ = new Sub(lhs,rhs);              $$ = new Sub(lhs,rhs);
# Line 620  mul_expr: Line 674  mul_expr:
674          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
675          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
676          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
677              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());
678              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
679          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
680              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());
681              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
682          } else {          } else {
683              $$ = new Mul(lhs,rhs);              $$ = new Mul(lhs,rhs);
# Line 633  mul_expr: Line 687  mul_expr:
687          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
688          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
689          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
690              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());
691              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
692          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
693              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());
694              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
695          } else {          } else {
696              $$ = new Div(lhs,rhs);              $$ = new Div(lhs,rhs);
# Line 646  mul_expr: Line 700  mul_expr:
700          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
701          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
702          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
703              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());
704              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
705          } else if (rhs->exprType() != INT_EXPR) {          } else if (rhs->exprType() != INT_EXPR) {
706              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());
707              $$ = new IntLiteral(0);              $$ = new IntLiteral(0);
708          } else {          } else {
709              $$ = new Mod(lhs,rhs);              $$ = new Mod(lhs,rhs);
# Line 660  mul_expr: Line 714  mul_expr:
714    
715  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {  void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
716      //fprintf(stderr, "%d: %s\n", locp->first_line, err);      //fprintf(stderr, "%d: %s\n", locp->first_line, err);
717      context->addErr(locp->first_line, err);      context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err);
718  }  }
719    
720  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {  void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
721      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);      //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
722      context->addWrn(locp->first_line, txt);      context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt);
723  }  }

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

  ViewVC Help
Powered by ViewVC