--- linuxsampler/trunk/src/scriptvm/parser.y 2014/05/31 21:09:25 2585 +++ linuxsampler/trunk/src/scriptvm/parser.y 2016/07/14 10:37:28 2947 @@ -1,11 +1,13 @@ /* - * Copyright (c) 2014 Christian Schoenebeck and Andreas Persson + * Copyright (c) 2014-2016 Christian Schoenebeck and Andreas Persson * * http://www.linuxsampler.org * * This file is part of LinuxSampler and released under the same terms. * See README file for details. */ + +/* Parser for NKSP real-time instrument script language. */ %{ #define YYERROR_VERBOSE 1 @@ -18,8 +20,8 @@ void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt); int InstrScript_lex(YYSTYPE* lvalp, YYLTYPE* llocp, void* scanner); #define scanner context->scanner - #define PARSE_ERR(txt) yyerror(&yylloc, context, txt) - #define PARSE_WRN(txt) InstrScript_warning(&yylloc, context, txt) + #define PARSE_ERR(loc,txt) yyerror(&loc, context, txt) + #define PARSE_WRN(loc,txt) InstrScript_warning(&loc, context, txt) %} // generate reentrant safe parser @@ -37,16 +39,17 @@ %token IDENTIFIER %token VARIABLE %token ON END INIT NOTE DECLARE ASSIGNMENT WHILE IF OR RELEASE AND ELSE +%token BITWISE_OR BITWISE_AND BITWISE_NOT %token CONTROLLER SELECT CASE TO NOT CONST_ POLYPHONIC MOD %token LE GE %type script eventhandlers %type eventhandler -%type statements +%type statements opt_statements %type statement assignment %type functioncall %type args -%type arg expr or_expr and_expr rel_expr add_expr mul_expr unary_expr concat_expr +%type arg expr logical_or_expr logical_and_expr bitwise_or_expr bitwise_and_expr rel_expr add_expr mul_expr unary_expr concat_expr %type caseclause %type caseclauses @@ -70,45 +73,53 @@ } eventhandler: - ON NOTE statements END ON { + ON NOTE opt_statements END ON { if (context->onNote) - PARSE_ERR("Redeclaration of 'note' event handler."); + PARSE_ERR(@2, "Redeclaration of 'note' event handler."); context->onNote = new OnNote($3); $$ = context->onNote; } - | ON INIT statements END ON { + | ON INIT opt_statements END ON { if (context->onInit) - PARSE_ERR("Redeclaration of 'init' event handler."); + PARSE_ERR(@2, "Redeclaration of 'init' event handler."); context->onInit = new OnInit($3); $$ = context->onInit; } - | ON RELEASE statements END ON { + | ON RELEASE opt_statements END ON { if (context->onRelease) - PARSE_ERR("Redeclaration of 'release' event handler."); + PARSE_ERR(@2, "Redeclaration of 'release' event handler."); context->onRelease = new OnRelease($3); $$ = context->onRelease; } - | ON CONTROLLER statements END ON { + | ON CONTROLLER opt_statements END ON { if (context->onController) - PARSE_ERR("Redeclaration of 'controller' event handler."); + PARSE_ERR(@2, "Redeclaration of 'controller' event handler."); context->onController = new OnController($3); $$ = context->onController; } +opt_statements: + /* epsilon (empty argument) */ { + $$ = new Statements(); + } + | statements { + $$ = $1; + } + statements: statement { $$ = new Statements(); if ($1) { if (!isNoOperation($1)) $$->add($1); // filter out NoOperation statements } else - PARSE_WRN("Not a statement."); + PARSE_WRN(@1, "Not a statement."); } | statements statement { $$ = $1; if ($2) { if (!isNoOperation($2)) $$->add($2); // filter out NoOperation statements } else - PARSE_WRN("Not a statement."); + PARSE_WRN(@2, "Not a statement."); } statement: @@ -119,7 +130,7 @@ const char* name = $2; //printf("declared var '%s'\n", name); if (context->variableByName(name)) - PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str()); + PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str()); if (name[0] == '@') { context->vartable[name] = new StringVariable(context); $$ = new NoOperation; @@ -132,9 +143,9 @@ const char* name = $3; //printf("declared polyphonic var '%s'\n", name); if (context->variableByName(name)) - PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str()); + PARSE_ERR(@3, (String("Redeclaration of variable '") + name + "'.").c_str()); if (name[0] != '$') { - PARSE_ERR("Polyphonic variables may only be declared as integers."); + PARSE_ERR(@3, "Polyphonic variables may only be declared as integers."); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else { context->vartable[name] = new PolyphonicIntVariable(context); @@ -145,10 +156,10 @@ const char* name = $2; //printf("declared assign var '%s'\n", name); if (context->variableByName(name)) - PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str()); + PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str()); if ($4->exprType() == STRING_EXPR) { if (name[0] == '$') - 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()); StringExprRef expr = $4; if (expr->isConstExpr()) { const String s = expr->evalStr(); @@ -162,7 +173,7 @@ } } else { if (name[0] == '@') - 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()); IntExprRef expr = $4; if (expr->isConstExpr()) { const int i = expr->evalInt(); @@ -180,19 +191,19 @@ //printf("declare array without args\n"); const char* name = $2; if (!$4->isConstExpr()) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else if ($4->exprType() != INT_EXPR) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else if (context->variableByName(name)) { - PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str()); + PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else { IntExprRef expr = $4; int size = expr->evalInt(); if (size <= 0) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else { context->vartable[name] = new IntArrayVariable(context, size); @@ -203,23 +214,23 @@ | DECLARE VARIABLE '[' expr ']' ASSIGNMENT '(' args ')' { const char* name = $2; if (!$4->isConstExpr()) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else if ($4->exprType() != INT_EXPR) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else if (context->variableByName(name)) { - PARSE_ERR((String("Redeclaration of variable '") + name + "'.").c_str()); + PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else { IntExprRef sizeExpr = $4; ArgsRef args = $8; int size = sizeExpr->evalInt(); if (size <= 0) { - 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()); $$ = new FunctionCall("nothing", new Args, NULL); // whatever } else if (args->argsCount() > size) { - PARSE_ERR((String("Variable '") + name + + PARSE_ERR(@8, (String("Variable '") + name + "' was declared with size " + ToString(size) + " but " + ToString(args->argsCount()) + " values were assigned." ).c_str()); @@ -229,6 +240,7 @@ for (int i = 0; i < args->argsCount(); ++i) { if (args->arg(i)->exprType() != INT_EXPR) { PARSE_ERR( + @8, (String("Array variable '") + name + "' declared with invalid assignment values. Assigned element " + ToString(i+1) + " is not an integer expression.").c_str() @@ -248,26 +260,26 @@ const char* name = $3; if ($5->exprType() == STRING_EXPR) { if (name[0] == '$') - PARSE_WRN("Variable declared as integer, string expression assigned though."); + PARSE_WRN(@5, "Variable declared as integer, string expression assigned though."); String s; StringExprRef expr = $5; if (expr->isConstExpr()) s = expr->evalStr(); else - 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()); ConstStringVariableRef var = new ConstStringVariable(context, s); context->vartable[name] = var; //$$ = new Assignment(var, new StringLiteral(s)); $$ = new NoOperation(); } else { if (name[0] == '@') - PARSE_WRN("Variable declared as string, integer expression assigned though."); + PARSE_WRN(@5, "Variable declared as string, integer expression assigned though."); int i = 0; IntExprRef expr = $5; if (expr->isConstExpr()) i = expr->evalInt(); else - 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()); ConstIntVariableRef var = new ConstIntVariable(i); context->vartable[name] = var; //$$ = new Assignment(var, new IntLiteral(i)); @@ -277,25 +289,25 @@ | assignment { $$ = $1; } - | WHILE '(' expr ')' statements END WHILE { + | WHILE '(' expr ')' opt_statements END WHILE { if ($3->exprType() == INT_EXPR) { $$ = new While($3, $5); } else { - PARSE_ERR("Condition for 'while' loops must be integer expression."); + PARSE_ERR(@3, "Condition for 'while' loops must be integer expression."); $$ = new While(new IntLiteral(0), $5); } } - | IF '(' expr ')' statements ELSE statements END IF { + | IF '(' expr ')' opt_statements ELSE opt_statements END IF { $$ = new If($3, $5, $7); } - | IF '(' expr ')' statements END IF { + | IF '(' expr ')' opt_statements END IF { $$ = new If($3, $5); } | SELECT expr caseclauses END SELECT { if ($2->exprType() == INT_EXPR) { $$ = new SelectCase($2, $3); } else { - PARSE_ERR("Statement 'select' can only by applied to integer expressions."); + PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions."); $$ = new SelectCase(new IntLiteral(0), $3); } } @@ -311,12 +323,12 @@ } caseclause: - CASE INTEGER statements { + CASE INTEGER opt_statements { $$ = CaseBranch(); $$.from = new IntLiteral($2); $$.statements = $3; } - | CASE INTEGER TO INTEGER statements { + | CASE INTEGER TO INTEGER opt_statements { $$ = CaseBranch(); $$.from = new IntLiteral($2); $$.to = new IntLiteral($4); @@ -330,19 +342,23 @@ ArgsRef args = $3; VMFunction* fn = context->functionProvider->functionByName(name); if (!fn) { - 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()); $$ = new FunctionCall(name, args, NULL); } else if (args->argsCount() < fn->minRequiredArgs()) { - 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()); $$ = new FunctionCall(name, args, NULL); } else if (args->argsCount() > fn->maxAllowedArgs()) { - 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()); $$ = new FunctionCall(name, args, NULL); } else { bool argsOK = true; for (int i = 0; i < args->argsCount(); ++i) { if (args->arg(i)->exprType() != fn->argType(i) && !fn->acceptsArgType(i, args->arg(i)->exprType())) { - 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()); + argsOK = false; + break; + } else if (fn->modifiesArg(i) && !args->arg(i)->isModifyable()) { + PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects an assignable variable.").c_str()); argsOK = false; break; } @@ -356,10 +372,10 @@ ArgsRef args = new Args; VMFunction* fn = context->functionProvider->functionByName(name); if (!fn) { - 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()); $$ = new FunctionCall(name, args, NULL); } else if (fn->minRequiredArgs() > 0) { - 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()); $$ = new FunctionCall(name, args, NULL); } else { $$ = new FunctionCall(name, args, fn); @@ -371,10 +387,10 @@ ArgsRef args = new Args; VMFunction* fn = context->functionProvider->functionByName(name); if (!fn) { - 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()); $$ = new FunctionCall(name, args, NULL); } else if (fn->minRequiredArgs() > 0) { - 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()); $$ = new FunctionCall(name, args, NULL); } else { $$ = new FunctionCall(name, args, fn); @@ -400,24 +416,26 @@ const char* name = $1; VariableRef var = context->variableByName(name); if (!var) - 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()); else if (var->isConstExpr()) - 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()); + else if (!var->isAssignable()) + PARSE_ERR(@2, (String("Variable assignment: Variable '") + name + "' is not assignable.").c_str()); else if (var->exprType() != $3->exprType()) - 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()); $$ = new Assignment(var, $3); } | VARIABLE '[' expr ']' ASSIGNMENT expr { const char* name = $1; VariableRef var = context->variableByName(name); if (!var) - PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str()); + PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str()); else if (var->exprType() != INT_ARR_EXPR) - 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()); else if ($3->exprType() != INT_EXPR) - 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()); else if ($6->exprType() != INT_EXPR) - 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()); IntArrayElementRef element = new IntArrayElement(var, $3); $$ = new Assignment(element, $6); } @@ -435,7 +453,7 @@ if (var) $$ = var; else { - PARSE_ERR((String("No variable declared with name '") + $1 + "'.").c_str()); + PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str()); $$ = new IntLiteral(0); } } @@ -443,13 +461,13 @@ const char* name = $1; VariableRef var = context->variableByName(name); if (!var) { - PARSE_ERR((String("No variable declared with name '") + name + "'.").c_str()); + PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str()); $$ = new IntLiteral(0); } else if (var->exprType() != INT_ARR_EXPR) { - 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()); $$ = new IntLiteral(0); } else if ($3->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new IntArrayElement(var, $3); @@ -464,9 +482,17 @@ | '-' unary_expr { $$ = new Neg($2); } + | BITWISE_NOT unary_expr { + if ($2->exprType() != INT_EXPR) { + PARSE_ERR(@2, (String("Right operand of bitwise operator '.not.' must be an integer expression, is ") + typeStr($2->exprType()) + " though.").c_str()); + $$ = new IntLiteral(0); + } else { + $$ = new BitwiseNot($2); + } + } | NOT unary_expr { if ($2->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Not($2); @@ -477,8 +503,8 @@ concat_expr concat_expr: - or_expr - | concat_expr '&' or_expr { + logical_or_expr + | concat_expr '&' logical_or_expr { ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->isConstExpr() && rhs->isConstExpr()) { @@ -490,50 +516,84 @@ } } -or_expr: - and_expr - | or_expr OR and_expr { +logical_or_expr: + logical_and_expr + | logical_or_expr OR logical_and_expr { ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Or(lhs, rhs); } } -and_expr: - rel_expr { +logical_and_expr: + bitwise_or_expr { $$ = $1; } - | and_expr AND rel_expr { + | logical_and_expr AND bitwise_or_expr { ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new And(lhs, rhs); } } +bitwise_or_expr: + bitwise_and_expr + | bitwise_or_expr BITWISE_OR bitwise_and_expr { + ExpressionRef lhs = $1; + ExpressionRef rhs = $3; + if (lhs->exprType() != INT_EXPR) { + PARSE_ERR(@1, (String("Left operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); + $$ = new IntLiteral(0); + } else if (rhs->exprType() != INT_EXPR) { + PARSE_ERR(@3, (String("Right operand of bitwise operator '.or.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); + $$ = new IntLiteral(0); + } else { + $$ = new BitwiseOr(lhs, rhs); + } + } + +bitwise_and_expr: + rel_expr { + $$ = $1; + } + | bitwise_and_expr BITWISE_AND rel_expr { + ExpressionRef lhs = $1; + ExpressionRef rhs = $3; + if (lhs->exprType() != INT_EXPR) { + PARSE_ERR(@1, (String("Left operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); + $$ = new IntLiteral(0); + } else if (rhs->exprType() != INT_EXPR) { + PARSE_ERR(@3, (String("Right operand of bitwise operator '.and.' must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); + $$ = new IntLiteral(0); + } else { + $$ = new BitwiseAnd(lhs, rhs); + } + } + rel_expr: add_expr | rel_expr '<' add_expr { ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Relation(lhs, Relation::LESS_THAN, rhs); @@ -543,10 +603,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Relation(lhs, Relation::GREATER_THAN, rhs); @@ -556,10 +616,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs); @@ -569,10 +629,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs); @@ -591,10 +651,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Add(lhs,rhs); @@ -604,10 +664,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Sub(lhs,rhs); @@ -620,10 +680,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Mul(lhs,rhs); @@ -633,10 +693,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Div(lhs,rhs); @@ -646,10 +706,10 @@ ExpressionRef lhs = $1; ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else if (rhs->exprType() != INT_EXPR) { - 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()); $$ = new IntLiteral(0); } else { $$ = new Mod(lhs,rhs); @@ -660,10 +720,10 @@ void InstrScript_error(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* err) { //fprintf(stderr, "%d: %s\n", locp->first_line, err); - context->addErr(locp->first_line, err); + context->addErr(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, err); } void InstrScript_warning(YYLTYPE* locp, LinuxSampler::ParserContext* context, const char* txt) { //fprintf(stderr, "WRN %d: %s\n", locp->first_line, txt); - context->addWrn(locp->first_line, txt); + context->addWrn(locp->first_line, locp->last_line, locp->first_column+1, locp->last_column+1, txt); }