23 |
#define scanner context->scanner |
#define scanner context->scanner |
24 |
#define PARSE_ERR(loc,txt) yyerror(&loc, context, txt) |
#define PARSE_ERR(loc,txt) yyerror(&loc, context, txt) |
25 |
#define PARSE_WRN(loc,txt) InstrScript_warning(&loc, context, txt) |
#define PARSE_WRN(loc,txt) InstrScript_warning(&loc, context, txt) |
26 |
|
#define PARSE_DROP(loc) context->addPreprocessorComment(loc.first_line, loc.last_line, loc.first_column+1, loc.last_column+1); |
27 |
#define yytnamerr(res,str) InstrScript_tnamerr(res, str) |
#define yytnamerr(res,str) InstrScript_tnamerr(res, str) |
28 |
%} |
%} |
29 |
|
|
53 |
%token CONST_ "keyword 'const'" |
%token CONST_ "keyword 'const'" |
54 |
%token POLYPHONIC "keyword 'polyphonic'" |
%token POLYPHONIC "keyword 'polyphonic'" |
55 |
%token WHILE "keyword 'while'" |
%token WHILE "keyword 'while'" |
56 |
|
%token SYNCHRONIZED "keyword 'synchronized'" |
57 |
%token IF "keyword 'if'" |
%token IF "keyword 'if'" |
58 |
%token ELSE "keyword 'else'" |
%token ELSE "keyword 'else'" |
59 |
%token SELECT "keyword 'select'" |
%token SELECT "keyword 'select'" |
71 |
%token LE "operator '<='" |
%token LE "operator '<='" |
72 |
%token GE "operator '>='" |
%token GE "operator '>='" |
73 |
%token END_OF_FILE 0 "end of file" |
%token END_OF_FILE 0 "end of file" |
74 |
|
%token UNKNOWN_CHAR "unknown character" |
75 |
|
|
76 |
%type <nEventHandlers> script sections |
%type <nEventHandlers> script sections |
77 |
%type <nEventHandler> section eventhandler |
%type <nEventHandler> section eventhandler |
229 |
PARSE_WRN(@2, (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()); |
230 |
IntExprRef expr = $4; |
IntExprRef expr = $4; |
231 |
if (expr->isConstExpr()) { |
if (expr->isConstExpr()) { |
232 |
const int i = expr->evalInt(); |
const vmint i = expr->evalInt(); |
233 |
IntVariableRef var = new IntVariable(context); |
IntVariableRef var = new IntVariable(context); |
234 |
context->vartable[name] = var; |
context->vartable[name] = var; |
235 |
$$ = new Assignment(var, new IntLiteral(i)); |
$$ = new Assignment(var, new IntLiteral(i)); |
254 |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
255 |
} else { |
} else { |
256 |
IntExprRef expr = $4; |
IntExprRef expr = $4; |
257 |
int size = expr->evalInt(); |
vmint size = expr->evalInt(); |
258 |
if (size <= 0) { |
if (size <= 0) { |
259 |
PARSE_ERR(@4, (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()); |
260 |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
278 |
} else { |
} else { |
279 |
IntExprRef sizeExpr = $4; |
IntExprRef sizeExpr = $4; |
280 |
ArgsRef args = $8; |
ArgsRef args = $8; |
281 |
int size = sizeExpr->evalInt(); |
vmint size = sizeExpr->evalInt(); |
282 |
if (size <= 0) { |
if (size <= 0) { |
283 |
PARSE_ERR(@4, (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()); |
284 |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
285 |
} else if (args->argsCount() > size) { |
} else if (args->argsCount() > size) { |
286 |
PARSE_ERR(@8, (String("Variable '") + name + |
PARSE_ERR(@8, (String("Array variable '") + name + |
287 |
"' was declared with size " + ToString(size) + |
"' was declared with size " + ToString(size) + |
288 |
" but " + ToString(args->argsCount()) + |
" but " + ToString(args->argsCount()) + |
289 |
" values were assigned." ).c_str()); |
" values were assigned." ).c_str()); |
290 |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
291 |
} else { |
} else { |
292 |
bool argsOK = true; |
bool argsOK = true; |
293 |
for (int i = 0; i < args->argsCount(); ++i) { |
for (vmint i = 0; i < args->argsCount(); ++i) { |
294 |
if (args->arg(i)->exprType() != INT_EXPR) { |
if (args->arg(i)->exprType() != INT_EXPR) { |
295 |
PARSE_ERR( |
PARSE_ERR( |
296 |
@8, |
@8, |
310 |
} |
} |
311 |
} |
} |
312 |
} |
} |
313 |
|
| DECLARE CONST_ VARIABLE '[' expr ']' ASSIGNMENT '(' args ')' { |
314 |
|
const char* name = $3; |
315 |
|
if (!$5->isConstExpr()) { |
316 |
|
PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with constant array size.").c_str()); |
317 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
318 |
|
} else if ($5->exprType() != INT_EXPR) { |
319 |
|
PARSE_ERR(@5, (String("Size of array variable '") + name + "' declared with non integer expression.").c_str()); |
320 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
321 |
|
} else if (context->variableByName(name)) { |
322 |
|
PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str()); |
323 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
324 |
|
} else { |
325 |
|
IntExprRef sizeExpr = $5; |
326 |
|
ArgsRef args = $9; |
327 |
|
vmint size = sizeExpr->evalInt(); |
328 |
|
if (size <= 0) { |
329 |
|
PARSE_ERR(@5, (String("Array variable '") + name + "' must be declared with positive array size.").c_str()); |
330 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
331 |
|
} else if (args->argsCount() > size) { |
332 |
|
PARSE_ERR(@9, (String("Array variable '") + name + |
333 |
|
"' was declared with size " + ToString(size) + |
334 |
|
" but " + ToString(args->argsCount()) + |
335 |
|
" values were assigned." ).c_str()); |
336 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
337 |
|
} else { |
338 |
|
bool argsOK = true; |
339 |
|
for (vmint i = 0; i < args->argsCount(); ++i) { |
340 |
|
if (args->arg(i)->exprType() != INT_EXPR) { |
341 |
|
PARSE_ERR( |
342 |
|
@9, |
343 |
|
(String("Array variable '") + name + |
344 |
|
"' declared with invalid assignment values. Assigned element " + |
345 |
|
ToString(i+1) + " is not an integer expression.").c_str() |
346 |
|
); |
347 |
|
argsOK = false; |
348 |
|
break; |
349 |
|
} |
350 |
|
if (!args->arg(i)->isConstExpr()) { |
351 |
|
PARSE_ERR( |
352 |
|
@9, |
353 |
|
(String("const array variable '") + name + |
354 |
|
"' must be defined with const values. Assigned element " + |
355 |
|
ToString(i+1) + " is not a const expression though.").c_str() |
356 |
|
); |
357 |
|
argsOK = false; |
358 |
|
break; |
359 |
|
} |
360 |
|
} |
361 |
|
if (argsOK) { |
362 |
|
context->vartable[name] = new IntArrayVariable(context, size, args, true); |
363 |
|
$$ = new NoOperation; |
364 |
|
} else |
365 |
|
$$ = new FunctionCall("nothing", new Args, NULL); // whatever |
366 |
|
} |
367 |
|
} |
368 |
|
} |
369 |
| DECLARE CONST_ VARIABLE ASSIGNMENT expr { |
| DECLARE CONST_ VARIABLE ASSIGNMENT expr { |
370 |
const char* name = $3; |
const char* name = $3; |
371 |
if ($5->exprType() == STRING_EXPR) { |
if ($5->exprType() == STRING_EXPR) { |
384 |
} else { |
} else { |
385 |
if (name[0] == '@') |
if (name[0] == '@') |
386 |
PARSE_WRN(@5, "Variable declared as string, integer expression assigned though."); |
PARSE_WRN(@5, "Variable declared as string, integer expression assigned though."); |
387 |
int i = 0; |
vmint i = 0; |
388 |
IntExprRef expr = $5; |
IntExprRef expr = $5; |
389 |
if (expr->isConstExpr()) |
if (expr->isConstExpr()) |
390 |
i = expr->evalInt(); |
i = expr->evalInt(); |
407 |
$$ = new While(new IntLiteral(0), $5); |
$$ = new While(new IntLiteral(0), $5); |
408 |
} |
} |
409 |
} |
} |
410 |
|
| SYNCHRONIZED opt_statements END SYNCHRONIZED { |
411 |
|
$$ = new SyncBlock($2); |
412 |
|
} |
413 |
| IF '(' expr ')' opt_statements ELSE opt_statements END IF { |
| IF '(' expr ')' opt_statements ELSE opt_statements END IF { |
414 |
$$ = new If($3, $5, $7); |
$$ = new If($3, $5, $7); |
415 |
} |
} |
475 |
} else if (!fn) { |
} else if (!fn) { |
476 |
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()); |
477 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
478 |
|
} else if (context->functionProvider->isFunctionDisabled(fn,context)) { |
479 |
|
PARSE_DROP(@$); |
480 |
|
$$ = new NoFunctionCall; |
481 |
} else if (args->argsCount() < fn->minRequiredArgs()) { |
} else if (args->argsCount() < fn->minRequiredArgs()) { |
482 |
PARSE_ERR(@3, (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()); |
483 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
486 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
487 |
} else { |
} else { |
488 |
bool argsOK = true; |
bool argsOK = true; |
489 |
for (int i = 0; i < args->argsCount(); ++i) { |
for (vmint i = 0; i < args->argsCount(); ++i) { |
490 |
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())) { |
491 |
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()); |
492 |
argsOK = false; |
argsOK = false; |
511 |
} else if (!fn) { |
} else if (!fn) { |
512 |
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()); |
513 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
514 |
|
} else if (context->functionProvider->isFunctionDisabled(fn,context)) { |
515 |
|
PARSE_DROP(@$); |
516 |
|
$$ = new NoFunctionCall; |
517 |
} else if (fn->minRequiredArgs() > 0) { |
} else if (fn->minRequiredArgs() > 0) { |
518 |
PARSE_ERR(@3, (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()); |
519 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
532 |
} else if (!fn) { |
} else if (!fn) { |
533 |
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()); |
534 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
535 |
|
} else if (context->functionProvider->isFunctionDisabled(fn,context)) { |
536 |
|
PARSE_DROP(@$); |
537 |
|
$$ = new NoFunctionCall; |
538 |
} else if (fn->minRequiredArgs() > 0) { |
} else if (fn->minRequiredArgs() > 0) { |
539 |
PARSE_ERR(@1, (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()); |
540 |
$$ = new FunctionCall(name, args, NULL); |
$$ = new FunctionCall(name, args, NULL); |
586 |
PARSE_ERR(@3, (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()); |
587 |
else if ($6->exprType() != INT_EXPR) |
else if ($6->exprType() != INT_EXPR) |
588 |
PARSE_ERR(@5, (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()); |
589 |
|
else if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize()) |
590 |
|
PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) + |
591 |
|
" exceeds size of array variable '" + name + |
592 |
|
"' which was declared with size " + |
593 |
|
ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str()); |
594 |
IntArrayElementRef element = new IntArrayElement(var, $3); |
IntArrayElementRef element = new IntArrayElement(var, $3); |
595 |
$$ = new Assignment(element, $6); |
$$ = new Assignment(element, $6); |
596 |
} |
} |
625 |
PARSE_ERR(@3, (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()); |
626 |
$$ = new IntLiteral(0); |
$$ = new IntLiteral(0); |
627 |
} else { |
} else { |
628 |
|
if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((IntArrayVariableRef)var)->arraySize()) |
629 |
|
PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) + |
630 |
|
" exceeds size of array variable '" + name + |
631 |
|
"' which was declared with size " + |
632 |
|
ToString(((IntArrayVariableRef)var)->arraySize()) + ".").c_str()); |
633 |
$$ = new IntArrayElement(var, $3); |
$$ = new IntArrayElement(var, $3); |
634 |
} |
} |
635 |
} |
} |