/[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 2889 by schoenebeck, Mon Apr 25 17:28:23 2016 UTC revision 2951 by schoenebeck, Fri Jul 15 20:07:47 2016 UTC
# Line 38  Line 38 
38  %token <sValue> STRING  %token <sValue> STRING
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 FUNCTION CALL
42    %token BITWISE_OR BITWISE_AND BITWISE_NOT
43  %token CONTROLLER SELECT CASE TO NOT CONST_ POLYPHONIC MOD  %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 sections
47  %type <nEventHandler> eventhandler  %type <nEventHandler> section eventhandler
48  %type <nStatements> statements  %type <nStatements> statements opt_statements userfunctioncall
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 57  Line 58 
58  %%  %%
59    
60  script:  script:
61      eventhandlers  {      sections  {
62          $$ = context->handlers = $1;          $$ = context->handlers = $1;
63      }      }
64    
65  eventhandlers:  sections:
66      eventhandler  {      section  {
67          $$ = new EventHandlers();          $$ = new EventHandlers();
68          $$->add($1);          if ($1) $$->add($1);
69      }      }
70      | eventhandlers eventhandler  {      | sections section  {
71            $$ = $1;
72            if ($2) $$->add($2);
73        }
74    
75    section:
76        function_declaration  {
77            $$ = EventHandlerRef();
78        }
79        | eventhandler  {
80          $$ = $1;          $$ = $1;
         $$->add($2);  
81      }      }
82    
83  eventhandler:  eventhandler:
84      ON NOTE statements END ON  {      ON NOTE opt_statements END ON  {
85          if (context->onNote)          if (context->onNote)
86              PARSE_ERR(@2, "Redeclaration of 'note' event handler.");              PARSE_ERR(@2, "Redeclaration of 'note' event handler.");
87          context->onNote = new OnNote($3);          context->onNote = new OnNote($3);
88          $$ = context->onNote;          $$ = context->onNote;
89      }      }
90      | ON INIT statements END ON  {      | ON INIT opt_statements END ON  {
91          if (context->onInit)          if (context->onInit)
92              PARSE_ERR(@2, "Redeclaration of 'init' event handler.");              PARSE_ERR(@2, "Redeclaration of 'init' event handler.");
93          context->onInit = new OnInit($3);          context->onInit = new OnInit($3);
94          $$ = context->onInit;          $$ = context->onInit;
95      }      }
96      | ON RELEASE statements END ON  {      | ON RELEASE opt_statements END ON  {
97          if (context->onRelease)          if (context->onRelease)
98              PARSE_ERR(@2, "Redeclaration of 'release' event handler.");              PARSE_ERR(@2, "Redeclaration of 'release' event handler.");
99          context->onRelease = new OnRelease($3);          context->onRelease = new OnRelease($3);
100          $$ = context->onRelease;          $$ = context->onRelease;
101      }      }
102      | ON CONTROLLER statements END ON  {      | ON CONTROLLER opt_statements END ON  {
103          if (context->onController)          if (context->onController)
104              PARSE_ERR(@2, "Redeclaration of 'controller' event handler.");              PARSE_ERR(@2, "Redeclaration of 'controller' event handler.");
105          context->onController = new OnController($3);          context->onController = new OnController($3);
106          $$ = context->onController;          $$ = context->onController;
107      }      }
108    
109    function_declaration:
110        FUNCTION IDENTIFIER opt_statements END FUNCTION  {
111            const char* name = $2;
112            if (context->functionProvider->functionByName(name)) {
113                PARSE_ERR(@2, (String("There is already a built-in function with name '") + name + "'.").c_str());
114            } else if (context->userFunctionByName(name)) {
115                PARSE_ERR(@2, (String("There is already a user defined function with name '") + name + "'.").c_str());
116            } else {
117                context->userFnTable[name] = $3;
118            }
119        }
120    
121    opt_statements:
122        /* epsilon (empty argument) */  {
123            $$ = new Statements();
124        }
125        | statements  {
126            $$ = $1;
127        }
128    
129  statements:  statements:
130      statement  {      statement  {
131          $$ = new Statements();          $$ = new Statements();
# Line 117  statement: Line 146  statement:
146      functioncall  {      functioncall  {
147          $$ = $1;          $$ = $1;
148      }      }
149        | userfunctioncall  {
150            $$ = $1;
151        }
152      | DECLARE VARIABLE  {      | DECLARE VARIABLE  {
153          const char* name = $2;          const char* name = $2;
154          //printf("declared var '%s'\n", name);          //printf("declared var '%s'\n", name);
# Line 280  statement: Line 312  statement:
312      | assignment  {      | assignment  {
313          $$ = $1;          $$ = $1;
314      }      }
315      | WHILE '(' expr ')' statements END WHILE  {      | WHILE '(' expr ')' opt_statements END WHILE  {
316          if ($3->exprType() == INT_EXPR) {          if ($3->exprType() == INT_EXPR) {
317              $$ = new While($3, $5);              $$ = new While($3, $5);
318          } else {          } else {
# Line 288  statement: Line 320  statement:
320              $$ = new While(new IntLiteral(0), $5);              $$ = new While(new IntLiteral(0), $5);
321          }          }
322      }      }
323      | IF '(' expr ')' statements ELSE statements END IF  {      | IF '(' expr ')' opt_statements ELSE opt_statements END IF  {
324          $$ = new If($3, $5, $7);          $$ = new If($3, $5, $7);
325      }      }
326      | IF '(' expr ')' statements END IF  {      | IF '(' expr ')' opt_statements END IF  {
327          $$ = new If($3, $5);          $$ = new If($3, $5);
328      }      }
329      | SELECT expr caseclauses END SELECT  {      | SELECT expr caseclauses END SELECT  {
# Line 314  caseclauses: Line 346  caseclauses:
346      }      }
347    
348  caseclause:  caseclause:
349      CASE INTEGER statements  {      CASE INTEGER opt_statements  {
350          $$ = CaseBranch();          $$ = CaseBranch();
351          $$.from = new IntLiteral($2);          $$.from = new IntLiteral($2);
352          $$.statements = $3;          $$.statements = $3;
353      }      }
354      | CASE INTEGER TO INTEGER statements  {      | CASE INTEGER TO INTEGER opt_statements  {
355          $$ = CaseBranch();          $$ = CaseBranch();
356          $$.from = new IntLiteral($2);          $$.from = new IntLiteral($2);
357          $$.to   = new IntLiteral($4);          $$.to   = new IntLiteral($4);
358          $$.statements = $5;          $$.statements = $5;
359      }      }
360    
361    userfunctioncall:
362        CALL IDENTIFIER  {
363            const char* name = $2;
364            StatementsRef fn = context->userFunctionByName(name);
365            if (context->functionProvider->functionByName(name)) {
366                PARSE_ERR(@1, (String("Keyword 'call' must only be used for user defined functions, not for any built-in function like '") + name + "'.").c_str());
367                $$ = StatementsRef();
368            } else if (!fn) {
369                PARSE_ERR(@2, (String("No user defined function with name '") + name + "'.").c_str());
370                $$ = StatementsRef();
371            } else {
372                $$ = fn;
373            }
374        }
375    
376  functioncall:  functioncall:
377      IDENTIFIER '(' args ')'  {      IDENTIFIER '(' args ')'  {
378          const char* name = $1;          const char* name = $1;
379          //printf("function call of '%s' with args\n", name);          //printf("function call of '%s' with args\n", name);
380          ArgsRef args = $3;          ArgsRef args = $3;
381          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
382          if (!fn) {          if (context->userFunctionByName(name)) {
383                PARSE_ERR(@1, (String("Missing 'call' keyword before user defined function name '") + name + "'.").c_str());
384                $$ = new FunctionCall(name, args, NULL);
385            } else if (!fn) {
386              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
387              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
388          } else if (args->argsCount() < fn->minRequiredArgs()) {          } else if (args->argsCount() < fn->minRequiredArgs()) {
# Line 348  functioncall: Line 398  functioncall:
398                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects " + typeStr(fn->argType(i)) + " type, but type " + typeStr(args->arg(i)->exprType()) + " was given instead.").c_str());                      PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects " + typeStr(fn->argType(i)) + " type, but type " + typeStr(args->arg(i)->exprType()) + " was given instead.").c_str());
399                      argsOK = false;                      argsOK = false;
400                      break;                      break;
401                    } else if (fn->modifiesArg(i) && !args->arg(i)->isModifyable()) {
402                        PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects an assignable variable.").c_str());
403                        argsOK = false;
404                        break;
405                  }                  }
406              }              }
407              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);              $$ = new FunctionCall(name, args, argsOK ? fn : NULL);
# Line 358  functioncall: Line 412  functioncall:
412          //printf("function call of '%s' (with empty args)\n", name);          //printf("function call of '%s' (with empty args)\n", name);
413          ArgsRef args = new Args;          ArgsRef args = new Args;
414          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
415          if (!fn) {          if (context->userFunctionByName(name)) {
416                PARSE_ERR(@1, (String("Missing 'call' keyword before user defined function name '") + name + "'.").c_str());
417                $$ = new FunctionCall(name, args, NULL);
418            } else if (!fn) {
419              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
420              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
421          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
# Line 373  functioncall: Line 430  functioncall:
430          //printf("function call of '%s' (without args)\n", name);          //printf("function call of '%s' (without args)\n", name);
431          ArgsRef args = new Args;          ArgsRef args = new Args;
432          VMFunction* fn = context->functionProvider->functionByName(name);          VMFunction* fn = context->functionProvider->functionByName(name);
433          if (!fn) {          if (context->userFunctionByName(name)) {
434                PARSE_ERR(@1, (String("Missing 'call' keyword before user defined function name '") + name + "'.").c_str());
435                $$ = new FunctionCall(name, args, NULL);
436            } else if (!fn) {
437              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());              PARSE_ERR(@1, (String("No built-in function with name '") + name + "'.").c_str());
438              $$ = new FunctionCall(name, args, NULL);              $$ = new FunctionCall(name, args, NULL);
439          } else if (fn->minRequiredArgs() > 0) {          } else if (fn->minRequiredArgs() > 0) {
# Line 406  assignment: Line 466  assignment:
466              PARSE_ERR(@1, (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());
467          else if (var->isConstExpr())          else if (var->isConstExpr())
468              PARSE_ERR(@2, (String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());              PARSE_ERR(@2, (String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());
469            else if (!var->isAssignable())
470                PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str());
471          else if (var->exprType() != $3->exprType())          else if (var->exprType() != $3->exprType())
472              PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());              PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());
473          $$ = new Assignment(var, $3);          $$ = new Assignment(var, $3);
# Line 467  unary_expr: Line 529  unary_expr:
529      | '-' unary_expr  {      | '-' unary_expr  {
530          $$ = new Neg($2);          $$ = new Neg($2);
531      }      }
532        | BITWISE_NOT unary_expr  {
533            if ($2->exprType() != INT_EXPR) {
534                PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
535                $$ = new IntLiteral(0);
536            } else {
537                $$ = new BitwiseNot($2);
538            }
539        }
540      | NOT unary_expr  {      | NOT unary_expr  {
541          if ($2->exprType() != INT_EXPR) {          if ($2->exprType() != INT_EXPR) {
542              PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());              PARSE_ERR(@2, (String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
# Line 480  expr: Line 550  expr:
550      concat_expr      concat_expr
551    
552  concat_expr:  concat_expr:
553      or_expr      logical_or_expr
554      | concat_expr '&' or_expr  {      | concat_expr '&' logical_or_expr  {
555          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
556          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
557          if (lhs->isConstExpr() && rhs->isConstExpr()) {          if (lhs->isConstExpr() && rhs->isConstExpr()) {
# Line 493  concat_expr: Line 563  concat_expr:
563          }          }
564      }      }
565    
566  or_expr:  logical_or_expr:
567      and_expr      logical_and_expr
568      | or_expr OR and_expr  {      | logical_or_expr OR logical_and_expr  {
569          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
570          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
571          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
# Line 509  or_expr: Line 579  or_expr:
579          }          }
580      }      }
581    
582  and_expr:  logical_and_expr:
583      rel_expr  {      bitwise_or_expr  {
584          $$ = $1;          $$ = $1;
585      }      }
586      | and_expr AND rel_expr  {      | logical_and_expr AND bitwise_or_expr  {
587          ExpressionRef lhs = $1;          ExpressionRef lhs = $1;
588          ExpressionRef rhs = $3;          ExpressionRef rhs = $3;
589          if (lhs->exprType() != INT_EXPR) {          if (lhs->exprType() != INT_EXPR) {
# Line 527  and_expr: Line 597  and_expr:
597          }          }
598      }      }
599    
600    bitwise_or_expr:
601        bitwise_and_expr
602        | bitwise_or_expr BITWISE_OR bitwise_and_expr  {
603            ExpressionRef lhs = $1;
604            ExpressionRef rhs = $3;
605            if (lhs->exprType() != INT_EXPR) {
606                PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
607                $$ = new IntLiteral(0);
608            } else if (rhs->exprType() != INT_EXPR) {
609                PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
610                $$ = new IntLiteral(0);
611            } else {
612                $$ = new BitwiseOr(lhs, rhs);
613            }
614        }
615    
616    bitwise_and_expr:
617        rel_expr  {
618            $$ = $1;
619        }
620        | bitwise_and_expr BITWISE_AND rel_expr  {
621            ExpressionRef lhs = $1;
622            ExpressionRef rhs = $3;
623            if (lhs->exprType() != INT_EXPR) {
624                PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
625                $$ = new IntLiteral(0);
626            } else if (rhs->exprType() != INT_EXPR) {
627                PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
628                $$ = new IntLiteral(0);
629            } else {
630                $$ = new BitwiseAnd(lhs, rhs);
631            }
632        }
633    
634  rel_expr:  rel_expr:
635        add_expr        add_expr
636      | rel_expr '<' add_expr  {      | rel_expr '<' add_expr  {

Legend:
Removed from v.2889  
changed lines
  Added in v.2951

  ViewVC Help
Powered by ViewVC