/[svn]/linuxsampler/trunk/src/scriptvm/parser.y
ViewVC logotype

Contents of /linuxsampler/trunk/src/scriptvm/parser.y

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2585 - (show annotations) (download)
Sat May 31 21:09:25 2014 UTC (9 years, 10 months ago) by schoenebeck
File size: 27007 byte(s)
* Fixed compile error on Windows.

1 /*
2 * Copyright (c) 2014 Christian Schoenebeck and Andreas Persson
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 %{
11 #define YYERROR_VERBOSE 1
12 #include "parser_shared.h"
13 #include <string>
14 #include <map>
15 using namespace LinuxSampler;
16
17 void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err);
18 void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt);
19 int InstrScript_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner);
20 #define scanner context->scanner
21 #define PARSE_ERR(txt) yyerror(&yylloc, context, txt)
22 #define PARSE_WRN(txt) InstrScript_warning(&yylloc, context, txt)
23 %}
24
25 // generate reentrant safe parser
26 %pure-parser
27 %parse-param { LinuxSampler::ParserContext* context }
28 %lex-param { void* scanner }
29 // avoid symbol collision with other (i.e. future) auto generated (f)lex scanners
30 %name-prefix "InstrScript_"
31 %locations
32 %defines
33 %error-verbose
34
35 %token <iValue> INTEGER
36 %token <sValue> STRING
37 %token <sValue> IDENTIFIER
38 %token <sValue> VARIABLE
39 %token ON END INIT NOTE DECLARE ASSIGNMENT WHILE IF OR RELEASE AND ELSE
40 %token CONTROLLER SELECT CASE TO NOT CONST_ POLYPHONIC MOD
41 %token LE GE
42
43 %type <nEventHandlers> script eventhandlers
44 %type <nEventHandler> eventhandler
45 %type <nStatements> statements
46 %type <nStatement> statement assignment
47 %type <nFunctionCall> functioncall
48 %type <nArgs> args
49 %type <nExpression> arg expr or_expr and_expr rel_expr add_expr mul_expr unary_expr concat_expr
50 %type <nCaseBranch> caseclause
51 %type <nCaseBranches> caseclauses
52
53 %start script
54
55 %%
56
57 script:
58 eventhandlers {
59 $$ = context->handlers = $1;
60 }
61
62 eventhandlers:
63 eventhandler {
64 $$ = new EventHandlers();
65 $$->add($1);
66 }
67 | eventhandlers eventhandler {
68 $$ = $1;
69 $$->add($2);
70 }
71
72 eventhandler:
73 ON NOTE statements END ON {
74 if (context->onNote)
75 PARSE_ERR("Redeclaration of 'note' event handler.");
76 context->onNote = new OnNote($3);
77 $$ = context->onNote;
78 }
79 | ON INIT statements END ON {
80 if (context->onInit)
81 PARSE_ERR("Redeclaration of 'init' event handler.");
82 context->onInit = new OnInit($3);
83 $$ = context->onInit;
84 }
85 | ON RELEASE statements END ON {
86 if (context->onRelease)
87 PARSE_ERR("Redeclaration of 'release' event handler.");
88 context->onRelease = new OnRelease($3);
89 $$ = context->onRelease;
90 }
91 | ON CONTROLLER statements END ON {
92 if (context->onController)
93 PARSE_ERR("Redeclaration of 'controller' event handler.");
94 context->onController = new OnController($3);
95 $$ = context->onController;
96 }
97
98 statements:
99 statement {
100 $$ = new Statements();
101 if ($1) {
102 if (!isNoOperation($1)) $$->add($1); // filter out NoOperation statements
103 } else
104 PARSE_WRN("Not a statement.");
105 }
106 | statements statement {
107 $$ = $1;
108 if ($2) {
109 if (!isNoOperation($2)) $$->add($2); // filter out NoOperation statements
110 } else
111 PARSE_WRN("Not a statement.");
112 }
113
114 statement:
115 functioncall {
116 $$ = $1;
117 }
118 | DECLARE VARIABLE {
119 const char* name = $2;
120 //printf("declared var '%s'\n", name);
121 if (context->variableByName(name))
122 PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());
123 if (name[0] == '@') {
124 context->vartable[name] = new StringVariable(context);
125 $$ = new NoOperation;
126 } else {
127 context->vartable[name] = new IntVariable(context);
128 $$ = new NoOperation;
129 }
130 }
131 | DECLARE POLYPHONIC VARIABLE {
132 const char* name = $3;
133 //printf("declared polyphonic var '%s'\n", name);
134 if (context->variableByName(name))
135 PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());
136 if (name[0] != '$') {
137 PARSE_ERR("Polyphonic variables may only be declared as integers.");
138 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
139 } else {
140 context->vartable[name] = new PolyphonicIntVariable(context);
141 $$ = new NoOperation;
142 }
143 }
144 | DECLARE VARIABLE ASSIGNMENT expr {
145 const char* name = $2;
146 //printf("declared assign var '%s'\n", name);
147 if (context->variableByName(name))
148 PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());
149 if ($4->exprType() == STRING_EXPR) {
150 if (name[0] == '$')
151 PARSE_WRN((String("Variable '") + name + "' declared as integer, string expression assigned though.").c_str());
152 StringExprRef expr = $4;
153 if (expr->isConstExpr()) {
154 const String s = expr->evalStr();
155 StringVariableRef var = new StringVariable(context);
156 context->vartable[name] = var;
157 $$ = new Assignment(var, new StringLiteral(s));
158 } else {
159 StringVariableRef var = new StringVariable(context);
160 context->vartable[name] = var;
161 $$ = new Assignment(var, expr);
162 }
163 } else {
164 if (name[0] == '@')
165 PARSE_WRN((String("Variable '") + name + "' declared as string, integer expression assigned though.").c_str());
166 IntExprRef expr = $4;
167 if (expr->isConstExpr()) {
168 const int i = expr->evalInt();
169 IntVariableRef var = new IntVariable(context);
170 context->vartable[name] = var;
171 $$ = new Assignment(var, new IntLiteral(i));
172 } else {
173 IntVariableRef var = new IntVariable(context);
174 context->vartable[name] = var;
175 $$ = new Assignment(var, expr);
176 }
177 }
178 }
179 | DECLARE VARIABLE '[' expr ']' {
180 //printf("declare array without args\n");
181 const char* name = $2;
182 if (!$4->isConstExpr()) {
183 PARSE_ERR((String("Array variable '") + name + "' must be declared with constant array size.").c_str());
184 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
185 } else if ($4->exprType() != INT_EXPR) {
186 PARSE_ERR((String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
187 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
188 } else if (context->variableByName(name)) {
189 PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());
190 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
191 } else {
192 IntExprRef expr = $4;
193 int size = expr->evalInt();
194 if (size <= 0) {
195 PARSE_ERR((String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str());
196 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
197 } else {
198 context->vartable[name] = new IntArrayVariable(context, size);
199 $$ = new NoOperation;
200 }
201 }
202 }
203 | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')' {
204 const char* name = $2;
205 if (!$4->isConstExpr()) {
206 PARSE_ERR((String("Array variable '") + name + "' must be declared with constant array size.").c_str());
207 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
208 } else if ($4->exprType() != INT_EXPR) {
209 PARSE_ERR((String("Size of array variable '") + name + "' declared with non integer expression.").c_str());
210 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
211 } else if (context->variableByName(name)) {
212 PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str());
213 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
214 } else {
215 IntExprRef sizeExpr = $4;
216 ArgsRef args = $8;
217 int size = sizeExpr->evalInt();
218 if (size <= 0) {
219 PARSE_ERR((String("Array variable '") + name + "' must be declared with positive array size.").c_str());
220 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
221 } else if (args->argsCount() > size) {
222 PARSE_ERR((String("Variable '") + name +
223 "' was declared with size " + ToString(size) +
224 " but " + ToString(args->argsCount()) +
225 " values were assigned." ).c_str());
226 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
227 } else {
228 bool argsOK = true;
229 for (int i = 0; i < args->argsCount(); ++i) {
230 if (args->arg(i)->exprType() != INT_EXPR) {
231 PARSE_ERR(
232 (String("Array variable '") + name +
233 "' declared with invalid assignment values. Assigned element " +
234 ToString(i+1) + " is not an integer expression.").c_str()
235 );
236 argsOK = false;
237 break;
238 }
239 }
240 if (argsOK)
241 $$ = context->vartable[name] = new IntArrayVariable(context, size, args);
242 else
243 $$ = new FunctionCall("nothing", new Args, NULL); // whatever
244 }
245 }
246 }
247 | DECLARE CONST_ VARIABLE ASSIGNMENT expr {
248 const char* name = $3;
249 if ($5->exprType() == STRING_EXPR) {
250 if (name[0] == '$')
251 PARSE_WRN("Variable declared as integer, string expression assigned though.");
252 String s;
253 StringExprRef expr = $5;
254 if (expr->isConstExpr())
255 s = expr->evalStr();
256 else
257 PARSE_ERR((String("Assignment to const string variable '") + name + "' requires const expression.").c_str());
258 ConstStringVariableRef var = new ConstStringVariable(context, s);
259 context->vartable[name] = var;
260 //$$ = new Assignment(var, new StringLiteral(s));
261 $$ = new NoOperation();
262 } else {
263 if (name[0] == '@')
264 PARSE_WRN("Variable declared as string, integer expression assigned though.");
265 int i = 0;
266 IntExprRef expr = $5;
267 if (expr->isConstExpr())
268 i = expr->evalInt();
269 else
270 PARSE_ERR((String("Assignment to const integer variable '") + name + "' requires const expression.").c_str());
271 ConstIntVariableRef var = new ConstIntVariable(i);
272 context->vartable[name] = var;
273 //$$ = new Assignment(var, new IntLiteral(i));
274 $$ = new NoOperation();
275 }
276 }
277 | assignment {
278 $$ = $1;
279 }
280 | WHILE '(' expr ')' statements END WHILE {
281 if ($3->exprType() == INT_EXPR) {
282 $$ = new While($3, $5);
283 } else {
284 PARSE_ERR("Condition for 'while' loops must be integer expression.");
285 $$ = new While(new IntLiteral(0), $5);
286 }
287 }
288 | IF '(' expr ')' statements ELSE statements END IF {
289 $$ = new If($3, $5, $7);
290 }
291 | IF '(' expr ')' statements END IF {
292 $$ = new If($3, $5);
293 }
294 | SELECT expr caseclauses END SELECT {
295 if ($2->exprType() == INT_EXPR) {
296 $$ = new SelectCase($2, $3);
297 } else {
298 PARSE_ERR("Statement 'select' can only by applied to integer expressions.");
299 $$ = new SelectCase(new IntLiteral(0), $3);
300 }
301 }
302
303 caseclauses:
304 caseclause {
305 $$ = CaseBranches();
306 $$.push_back($1);
307 }
308 | caseclauses caseclause {
309 $$ = $1;
310 $$.push_back($2);
311 }
312
313 caseclause:
314 CASE INTEGER statements {
315 $$ = CaseBranch();
316 $$.from = new IntLiteral($2);
317 $$.statements = $3;
318 }
319 | CASE INTEGER TO INTEGER statements {
320 $$ = CaseBranch();
321 $$.from = new IntLiteral($2);
322 $$.to = new IntLiteral($4);
323 $$.statements = $5;
324 }
325
326 functioncall:
327 IDENTIFIER '(' args ')' {
328 const char* name = $1;
329 //printf("function call of '%s' with args\n", name);
330 ArgsRef args = $3;
331 VMFunction* fn = context->functionProvider->functionByName(name);
332 if (!fn) {
333 PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());
334 $$ = new FunctionCall(name, args, NULL);
335 } else if (args->argsCount() < fn->minRequiredArgs()) {
336 PARSE_ERR((String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
337 $$ = new FunctionCall(name, args, NULL);
338 } else if (args->argsCount() > fn->maxAllowedArgs()) {
339 PARSE_ERR((String("Built-in function '") + name + "' accepts max. " + ToString(fn->maxAllowedArgs()) + " arguments.").c_str());
340 $$ = new FunctionCall(name, args, NULL);
341 } else {
342 bool argsOK = true;
343 for (int i = 0; i < args->argsCount(); ++i) {
344 if (args->arg(i)->exprType() != fn->argType(i) && !fn->acceptsArgType(i, args->arg(i)->exprType())) {
345 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());
346 argsOK = false;
347 break;
348 }
349 }
350 $$ = new FunctionCall(name, args, argsOK ? fn : NULL);
351 }
352 }
353 | IDENTIFIER '(' ')' {
354 const char* name = $1;
355 //printf("function call of '%s' (with empty args)\n", name);
356 ArgsRef args = new Args;
357 VMFunction* fn = context->functionProvider->functionByName(name);
358 if (!fn) {
359 PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());
360 $$ = new FunctionCall(name, args, NULL);
361 } else if (fn->minRequiredArgs() > 0) {
362 PARSE_ERR((String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
363 $$ = new FunctionCall(name, args, NULL);
364 } else {
365 $$ = new FunctionCall(name, args, fn);
366 }
367 }
368 | IDENTIFIER {
369 const char* name = $1;
370 //printf("function call of '%s' (without args)\n", name);
371 ArgsRef args = new Args;
372 VMFunction* fn = context->functionProvider->functionByName(name);
373 if (!fn) {
374 PARSE_ERR((String("No built-in function with name '") + name + "'.").c_str());
375 $$ = new FunctionCall(name, args, NULL);
376 } else if (fn->minRequiredArgs() > 0) {
377 PARSE_ERR((String("Built-in function '") + name + "' requires at least " + ToString(fn->minRequiredArgs()) + " arguments.").c_str());
378 $$ = new FunctionCall(name, args, NULL);
379 } else {
380 $$ = new FunctionCall(name, args, fn);
381 }
382 }
383
384 args:
385 arg {
386 $$ = new Args();
387 $$->add($1);
388 }
389 | args ',' arg {
390 $$ = $1;
391 $$->add($3);
392 }
393
394 arg:
395 expr
396
397 assignment:
398 VARIABLE ASSIGNMENT expr {
399 //printf("variable lookup with name '%s' as assignment expr\n", $1);
400 const char* name = $1;
401 VariableRef var = context->variableByName(name);
402 if (!var)
403 PARSE_ERR((String("Variable assignment: No variable declared with name '") + name + "'.").c_str());
404 else if (var->isConstExpr())
405 PARSE_ERR((String("Variable assignment: Cannot modify const variable '") + name + "'.").c_str());
406 else if (var->exprType() != $3->exprType())
407 PARSE_ERR((String("Variable assignment: Variable '") + name + "' is of type " + typeStr(var->exprType()) + ", assignment is of type " + typeStr($3->exprType()) + " though.").c_str());
408 $$ = new Assignment(var, $3);
409 }
410 | VARIABLE '[' expr ']' ASSIGNMENT expr {
411 const char* name = $1;
412 VariableRef var = context->variableByName(name);
413 if (!var)
414 PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());
415 else if (var->exprType() != INT_ARR_EXPR)
416 PARSE_ERR((String("Variable '") + name + "' is not an array variable.").c_str());
417 else if ($3->exprType() != INT_EXPR)
418 PARSE_ERR((String("Array variable '") + name + "' accessed with non integer expression.").c_str());
419 else if ($6->exprType() != INT_EXPR)
420 PARSE_ERR((String("Value assigned to array variable '") + name + "' must be an integer expression.").c_str());
421 IntArrayElementRef element = new IntArrayElement(var, $3);
422 $$ = new Assignment(element, $6);
423 }
424
425 unary_expr:
426 INTEGER {
427 $$ = new IntLiteral($1);
428 }
429 | STRING {
430 $$ = new StringLiteral($1);
431 }
432 | VARIABLE {
433 //printf("variable lookup with name '%s' as unary expr\n", $1);
434 VariableRef var = context->variableByName($1);
435 if (var)
436 $$ = var;
437 else {
438 PARSE_ERR((String("No variable declared with name '") + $1 + "'.").c_str());
439 $$ = new IntLiteral(0);
440 }
441 }
442 | VARIABLE '[' expr ']' {
443 const char* name = $1;
444 VariableRef var = context->variableByName(name);
445 if (!var) {
446 PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str());
447 $$ = new IntLiteral(0);
448 } else if (var->exprType() != INT_ARR_EXPR) {
449 PARSE_ERR((String("Variable '") + name + "' is not an array variable.").c_str());
450 $$ = new IntLiteral(0);
451 } else if ($3->exprType() != INT_EXPR) {
452 PARSE_ERR((String("Array variable '") + name + "' accessed with non integer expression.").c_str());
453 $$ = new IntLiteral(0);
454 } else {
455 $$ = new IntArrayElement(var, $3);
456 }
457 }
458 | '(' expr ')' {
459 $$ = $2;
460 }
461 | functioncall {
462 $$ = $1;
463 }
464 | '-' unary_expr {
465 $$ = new Neg($2);
466 }
467 | NOT unary_expr {
468 if ($2->exprType() != INT_EXPR) {
469 PARSE_ERR((String("Right operand of operator 'not' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str());
470 $$ = new IntLiteral(0);
471 } else {
472 $$ = new Not($2);
473 }
474 }
475
476 expr:
477 concat_expr
478
479 concat_expr:
480 or_expr
481 | concat_expr '&' or_expr {
482 ExpressionRef lhs = $1;
483 ExpressionRef rhs = $3;
484 if (lhs->isConstExpr() && rhs->isConstExpr()) {
485 $$ = new StringLiteral(
486 lhs->evalCastToStr() + rhs->evalCastToStr()
487 );
488 } else {
489 $$ = new ConcatString(lhs, rhs);
490 }
491 }
492
493 or_expr:
494 and_expr
495 | or_expr OR and_expr {
496 ExpressionRef lhs = $1;
497 ExpressionRef rhs = $3;
498 if (lhs->exprType() != INT_EXPR) {
499 PARSE_ERR((String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
500 $$ = new IntLiteral(0);
501 } else if (rhs->exprType() != INT_EXPR) {
502 PARSE_ERR((String("Right operand of operator 'or' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
503 $$ = new IntLiteral(0);
504 } else {
505 $$ = new Or(lhs, rhs);
506 }
507 }
508
509 and_expr:
510 rel_expr {
511 $$ = $1;
512 }
513 | and_expr AND rel_expr {
514 ExpressionRef lhs = $1;
515 ExpressionRef rhs = $3;
516 if (lhs->exprType() != INT_EXPR) {
517 PARSE_ERR((String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
518 $$ = new IntLiteral(0);
519 } else if (rhs->exprType() != INT_EXPR) {
520 PARSE_ERR((String("Right operand of operator 'and' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
521 $$ = new IntLiteral(0);
522 } else {
523 $$ = new And(lhs, rhs);
524 }
525 }
526
527 rel_expr:
528 add_expr
529 | rel_expr '<' add_expr {
530 ExpressionRef lhs = $1;
531 ExpressionRef rhs = $3;
532 if (lhs->exprType() != INT_EXPR) {
533 PARSE_ERR((String("Left operand of operator '<' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
534 $$ = new IntLiteral(0);
535 } else if (rhs->exprType() != INT_EXPR) {
536 PARSE_ERR((String("Right operand of operator '<' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
537 $$ = new IntLiteral(0);
538 } else {
539 $$ = new Relation(lhs, Relation::LESS_THAN, rhs);
540 }
541 }
542 | rel_expr '>' add_expr {
543 ExpressionRef lhs = $1;
544 ExpressionRef rhs = $3;
545 if (lhs->exprType() != INT_EXPR) {
546 PARSE_ERR((String("Left operand of operator '>' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
547 $$ = new IntLiteral(0);
548 } else if (rhs->exprType() != INT_EXPR) {
549 PARSE_ERR((String("Right operand of operator '>' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
550 $$ = new IntLiteral(0);
551 } else {
552 $$ = new Relation(lhs, Relation::GREATER_THAN, rhs);
553 }
554 }
555 | rel_expr LE add_expr {
556 ExpressionRef lhs = $1;
557 ExpressionRef rhs = $3;
558 if (lhs->exprType() != INT_EXPR) {
559 PARSE_ERR((String("Left operand of operator '<=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
560 $$ = new IntLiteral(0);
561 } else if (rhs->exprType() != INT_EXPR) {
562 PARSE_ERR((String("Right operand of operator '<=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
563 $$ = new IntLiteral(0);
564 } else {
565 $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs);
566 }
567 }
568 | rel_expr GE add_expr {
569 ExpressionRef lhs = $1;
570 ExpressionRef rhs = $3;
571 if (lhs->exprType() != INT_EXPR) {
572 PARSE_ERR((String("Left operand of operator '>=' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
573 $$ = new IntLiteral(0);
574 } else if (rhs->exprType() != INT_EXPR) {
575 PARSE_ERR((String("Right operand of operator '>=' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
576 $$ = new IntLiteral(0);
577 } else {
578 $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs);
579 }
580 }
581 | rel_expr '=' add_expr {
582 $$ = new Relation($1, Relation::EQUAL, $3);
583 }
584 | rel_expr '#' add_expr {
585 $$ = new Relation($1, Relation::NOT_EQUAL, $3);
586 }
587
588 add_expr:
589 mul_expr
590 | add_expr '+' mul_expr {
591 ExpressionRef lhs = $1;
592 ExpressionRef rhs = $3;
593 if (lhs->exprType() != INT_EXPR) {
594 PARSE_ERR((String("Left operand of operator '+' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
595 $$ = new IntLiteral(0);
596 } else if (rhs->exprType() != INT_EXPR) {
597 PARSE_ERR((String("Right operand of operator '+' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
598 $$ = new IntLiteral(0);
599 } else {
600 $$ = new Add(lhs,rhs);
601 }
602 }
603 | add_expr '-' mul_expr {
604 ExpressionRef lhs = $1;
605 ExpressionRef rhs = $3;
606 if (lhs->exprType() != INT_EXPR) {
607 PARSE_ERR((String("Left operand of operator '-' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
608 $$ = new IntLiteral(0);
609 } else if (rhs->exprType() != INT_EXPR) {
610 PARSE_ERR((String("Right operand of operator '-' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
611 $$ = new IntLiteral(0);
612 } else {
613 $$ = new Sub(lhs,rhs);
614 }
615 }
616
617 mul_expr:
618 unary_expr
619 | mul_expr '*' unary_expr {
620 ExpressionRef lhs = $1;
621 ExpressionRef rhs = $3;
622 if (lhs->exprType() != INT_EXPR) {
623 PARSE_ERR((String("Left operand of operator '*' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
624 $$ = new IntLiteral(0);
625 } else if (rhs->exprType() != INT_EXPR) {
626 PARSE_ERR((String("Right operand of operator '*' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
627 $$ = new IntLiteral(0);
628 } else {
629 $$ = new Mul(lhs,rhs);
630 }
631 }
632 | mul_expr '/' unary_expr {
633 ExpressionRef lhs = $1;
634 ExpressionRef rhs = $3;
635 if (lhs->exprType() != INT_EXPR) {
636 PARSE_ERR((String("Left operand of operator '/' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
637 $$ = new IntLiteral(0);
638 } else if (rhs->exprType() != INT_EXPR) {
639 PARSE_ERR((String("Right operand of operator '/' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
640 $$ = new IntLiteral(0);
641 } else {
642 $$ = new Div(lhs,rhs);
643 }
644 }
645 | mul_expr MOD unary_expr {
646 ExpressionRef lhs = $1;
647 ExpressionRef rhs = $3;
648 if (lhs->exprType() != INT_EXPR) {
649 PARSE_ERR((String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str());
650 $$ = new IntLiteral(0);
651 } else if (rhs->exprType() != INT_EXPR) {
652 PARSE_ERR((String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str());
653 $$ = new IntLiteral(0);
654 } else {
655 $$ = new Mod(lhs,rhs);
656 }
657 }
658
659 %%
660
661 void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) {
662 //fprintf(stderr, "%d: %s\n", locp->first_line, err);
663 context->addErr(locp->first_line, err);
664 }
665
666 void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) {
667 //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt);
668 context->addWrn(locp->first_line, txt);
669 }

  ViewVC Help
Powered by ViewVC