--- linuxsampler/trunk/src/scriptvm/parser.y 2019/08/29 13:44:35 3580 +++ linuxsampler/trunk/src/scriptvm/parser.y 2019/08/30 11:40:25 3581 @@ -190,9 +190,13 @@ } else if (name[0] == '@') { context->vartable[name] = new StringVariable(context); } else if (name[0] == '~') { - context->vartable[name] = new RealVariable(context); + context->vartable[name] = new RealVariable({ + .ctx = context + }); } else if (name[0] == '$') { - context->vartable[name] = new IntVariable(context); + context->vartable[name] = new IntVariable({ + .ctx = context + }); } else if (name[0] == '?') { PARSE_ERR(@2, (String("Real number array variable '") + name + "' declaration requires array size.").c_str()); } else if (name[0] == '%') { @@ -210,9 +214,13 @@ } else if (name[0] != '$' && name[0] != '~') { PARSE_ERR(@3, "Polyphonic variables must only be declared either as integer or real number type."); } else if (name[0] == '~') { - context->vartable[name] = new PolyphonicRealVariable(context); - } else { - context->vartable[name] = new PolyphonicIntVariable(context); + context->vartable[name] = new PolyphonicRealVariable({ + .ctx = context + }); + } else { + context->vartable[name] = new PolyphonicIntVariable({ + .ctx = context + }); } $$ = new NoOperation; } @@ -241,29 +249,41 @@ if (name[0] != '~') PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str()); RealExprRef expr = $4; - RealVariableRef var = new RealVariable(context); + RealVariableRef var = new RealVariable({ + .ctx = context, + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + }); if (expr->isConstExpr()) { - const vmfloat f = expr->evalReal(); - $$ = new Assignment(var, new RealLiteral(f)); + $$ = new Assignment(var, new RealLiteral({ + .value = expr->evalReal(), + .unitFactor = expr->unitFactor(), + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + })); } else { $$ = new Assignment(var, expr); } - var->copyUnitFrom(expr); - var->setFinal(expr->isFinal()); context->vartable[name] = var; } else if ($4->exprType() == INT_EXPR) { if (name[0] != '$') PARSE_WRN(@2, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str()); IntExprRef expr = $4; - IntVariableRef var = new IntVariable(context); + IntVariableRef var = new IntVariable({ + .ctx = context, + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + }); if (expr->isConstExpr()) { - const vmint i = expr->evalInt(); - $$ = new Assignment(var, new IntLiteral(i)); + $$ = new Assignment(var, new IntLiteral({ + .value = expr->evalInt(), + .unitFactor = expr->unitFactor(), + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + })); } else { $$ = new Assignment(var, expr); } - var->copyUnitFrom(expr); - var->setFinal(expr->isFinal()); context->vartable[name] = var; } else if ($4->exprType() == EMPTY_EXPR) { PARSE_ERR(@4, "Expression does not result in a value."); @@ -283,13 +303,13 @@ } else if (context->variableByName(name)) { PARSE_ERR(@2, (String("Redeclaration of variable '") + name + "'.").c_str()); } else { - IntExprRef expr = $4; - if (expr->unitType() || expr->unitPrefix(0)) { + IntExprRef sizeExpr = $4; + if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) { PARSE_ERR(@4, "Units are not allowed as array size."); } else { - if (expr->isFinal()) + if (sizeExpr->isFinal()) PARSE_WRN(@4, "Final operator '!' is meaningless here."); - vmint size = expr->evalInt(); + vmint size = sizeExpr->evalInt(); if (size <= 0) { PARSE_ERR(@4, (String("Array variable '") + name + "' declared with array size " + ToString(size) + ".").c_str()); } else { @@ -324,7 +344,7 @@ "' was declared with size " + ToString(size) + " but " + ToString(args->argsCount()) + " values were assigned." ).c_str()); - } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) { + } else if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) { PARSE_ERR(@4, "Units are not allowed as array size."); } else { if (sizeExpr->isFinal()) @@ -355,14 +375,21 @@ ); argsOK = false; break; - } else if (args->arg(i)->asInt()->unitType() || - args->arg(i)->asInt()->unitPrefix(0)) - { + } else if (args->arg(i)->asScalarNumberExpr()->unitType()) { + PARSE_ERR( + @8, + (String("Array variable '") + name + + "' declared with invalid assignment values. Assigned element " + + ToString(i+1) + " contains a unit type, only metric prefixes are allowed for arrays.").c_str() + ); + argsOK = false; + break; + } else if (args->arg(i)->asScalarNumberExpr()->isFinal()) { PARSE_ERR( @8, (String("Array variable '") + name + "' declared with invalid assignment values. Assigned element " + - ToString(i+1) + " contains a unit.").c_str() + ToString(i+1) + " declared as 'final' value.").c_str() ); argsOK = false; break; @@ -398,7 +425,7 @@ "' was declared with size " + ToString(size) + " but " + ToString(args->argsCount()) + " values were assigned." ).c_str()); - } else if (sizeExpr->unitType() || sizeExpr->unitPrefix(0)) { + } else if (sizeExpr->unitType() || sizeExpr->hasUnitFactorNow()) { PARSE_ERR(@5, "Units are not allowed as array size."); } else { if (sizeExpr->isFinal()) @@ -423,7 +450,7 @@ if (args->arg(i)->exprType() != declType) { PARSE_ERR( @9, - (String("Array variable '") + name + + (String("const array variable '") + name + "' declared with invalid assignment values. Assigned element " + ToString(i+1) + " is not an " + typeStr(declType) + " expression.").c_str() ); @@ -439,14 +466,21 @@ ); argsOK = false; break; - } else if (args->arg(i)->asInt()->unitType() || - args->arg(i)->asInt()->unitPrefix(0)) - { + } else if (args->arg(i)->asScalarNumberExpr()->unitType()) { + PARSE_ERR( + @9, + (String("const array variable '") + name + + "' declared with invalid assignment values. Assigned element " + + ToString(i+1) + " contains a unit type, only metric prefixes are allowed for arrays.").c_str() + ); + argsOK = false; + break; + } else if (args->arg(i)->asScalarNumberExpr()->isFinal()) { PARSE_ERR( @9, (String("const array variable '") + name + "' declared with invalid assignment values. Assigned element " + - ToString(i+1) + " contains a unit.").c_str() + ToString(i+1) + " declared as 'final' value.").c_str() ); argsOK = false; break; @@ -481,29 +515,31 @@ } else if ($5->exprType() == REAL_EXPR) { if (name[0] != '~') PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", real number expression assigned though.").c_str()); - vmfloat f = 0; RealExprRef expr = $5; - if (expr->isConstExpr()) - f = expr->evalReal(); - else + if (!expr->isConstExpr()) { PARSE_ERR(@5, (String("Assignment to const real number variable '") + name + "' requires const expression.").c_str()); - ConstRealVariableRef var = new ConstRealVariable(f); - var->copyUnitFrom(expr); - var->setFinal(expr->isFinal()); + } + ConstRealVariableRef var = new ConstRealVariable({ + .value = (expr->isConstExpr()) ? expr->evalReal() : vmfloat(0), + .unitFactor = (expr->isConstExpr()) ? expr->unitFactor() : VM_NO_FACTOR, + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + }); context->vartable[name] = var; //$$ = new Assignment(var, new IntLiteral(i)); } else if ($5->exprType() == INT_EXPR) { if (name[0] != '$') PARSE_WRN(@5, (String("Variable '") + name + "' declared as " + typeStr(declType) + ", integer expression assigned though.").c_str()); - vmint i = 0; IntExprRef expr = $5; - if (expr->isConstExpr()) - i = expr->evalInt(); - else + if (!expr->isConstExpr()) { PARSE_ERR(@5, (String("Assignment to const integer variable '") + name + "' requires const expression.").c_str()); - ConstIntVariableRef var = new ConstIntVariable(i); - var->copyUnitFrom(expr); - var->setFinal(expr->isFinal()); + } + ConstIntVariableRef var = new ConstIntVariable({ + .value = (expr->isConstExpr()) ? expr->evalInt() : 0, + .unitFactor = (expr->isConstExpr()) ? expr->unitFactor() : VM_NO_FACTOR, + .unitType = expr->unitType(), + .isFinal = expr->isFinal() + }); context->vartable[name] = var; //$$ = new Assignment(var, new IntLiteral(i)); } else if ($5->exprType() == EMPTY_EXPR) { @@ -519,12 +555,15 @@ | WHILE '(' expr ')' opt_statements END WHILE { if ($3->exprType() == INT_EXPR) { IntExprRef expr = $3; - if (expr->isFinal() && expr->isConstExpr()) + if (expr->asScalarNumberExpr()->unitType() || + expr->asScalarNumberExpr()->hasUnitFactorEver()) + PARSE_WRN(@3, "Condition for 'while' loops contains a unit."); + else if (expr->isFinal() && expr->isConstExpr()) PARSE_WRN(@3, "Final operator '!' is meaningless here."); $$ = new While(expr, $5); } else { PARSE_ERR(@3, "Condition for 'while' loops must be integer expression."); - $$ = new While(new IntLiteral(0), $5); + $$ = new While(new IntLiteral({ .value = 0 }), $5); } } | SYNCHRONIZED opt_statements END SYNCHRONIZED { @@ -533,30 +572,37 @@ | IF '(' expr ')' opt_statements ELSE opt_statements END IF { if ($3->exprType() == INT_EXPR) { IntExprRef expr = $3; - if (expr->isFinal() && expr->isConstExpr()) + if (expr->asScalarNumberExpr()->unitType() || + expr->asScalarNumberExpr()->hasUnitFactorEver()) + PARSE_WRN(@3, "Condition for 'if' contains a unit."); + else if (expr->isFinal() && expr->isConstExpr()) PARSE_WRN(@3, "Final operator '!' is meaningless here."); $$ = new If($3, $5, $7); } else { PARSE_ERR(@3, "Condition for 'if' must be integer expression."); - $$ = new If(new IntLiteral(0), $5, $7); + $$ = new If(new IntLiteral({ .value = 0 }), $5, $7); } } | IF '(' expr ')' opt_statements END IF { if ($3->exprType() == INT_EXPR) { IntExprRef expr = $3; - if (expr->isFinal() && expr->isConstExpr()) + if (expr->asScalarNumberExpr()->unitType() || + expr->asScalarNumberExpr()->hasUnitFactorEver()) + PARSE_WRN(@3, "Condition for 'if' contains a unit."); + else if (expr->isFinal() && expr->isConstExpr()) PARSE_WRN(@3, "Final operator '!' is meaningless here."); $$ = new If($3, $5); } else { PARSE_ERR(@3, "Condition for 'if' must be integer expression."); - $$ = new If(new IntLiteral(0), $5); + $$ = new If(new IntLiteral({ .value = 0 }), $5); } } | SELECT expr caseclauses END SELECT { if ($2->exprType() == INT_EXPR) { IntExprRef expr = $2; - if (expr->unitType() || expr->unitPrefix(0)) { + if (expr->unitType() || expr->hasUnitFactorEver()) { PARSE_ERR(@2, "Units are not allowed here."); + $$ = new SelectCase(new IntLiteral({ .value = 0 }), $3); } else { if (expr->isFinal() && expr->isConstExpr()) PARSE_WRN(@2, "Final operator '!' is meaningless here."); @@ -564,7 +610,7 @@ } } else { PARSE_ERR(@2, "Statement 'select' can only by applied to integer expressions."); - $$ = new SelectCase(new IntLiteral(0), $3); + $$ = new SelectCase(new IntLiteral({ .value = 0 }), $3); } } @@ -581,13 +627,13 @@ caseclause: CASE INTEGER opt_statements { $$ = CaseBranch(); - $$.from = new IntLiteral($2); + $$.from = new IntLiteral({ .value = $2 }); $$.statements = $3; } | CASE INTEGER TO INTEGER opt_statements { $$ = CaseBranch(); - $$.from = new IntLiteral($2); - $$.to = new IntLiteral($4); + $$.from = new IntLiteral({ .value = $2 }); + $$.to = new IntLiteral({ .value = $4 }); $$.statements = $5; } @@ -645,7 +691,7 @@ PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' expects a unit.").c_str()); argsOK = false; break; - } else if (isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->unitPrefix(0) && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asScalarNumberExpr()->unitType())) { + } else if (isScalarNumber(args->arg(i)->exprType()) && args->arg(i)->asScalarNumberExpr()->hasUnitFactorEver() && !fn->acceptsArgUnitPrefix(i, args->arg(i)->asScalarNumberExpr()->unitType())) { if (args->arg(i)->asScalarNumberExpr()->unitType()) PARSE_ERR(@3, (String("Argument ") + ToString(i+1) + " of built-in function '" + name + "' does not expect a unit prefix for unit" + unitTypeStr(args->arg(i)->asScalarNumberExpr()->unitType()) + ".").c_str()); else @@ -658,6 +704,15 @@ break; } } + if (argsOK) { + // perform built-in function's own, custom arguments checks (if any) + fn->checkArgs(&*args, [&](String err) { + PARSE_ERR(@3, (String("Built-in function '") + name + "()': " + err).c_str()); + argsOK = false; + }, [&](String wrn) { + PARSE_WRN(@3, (String("Built-in function '") + name + "()': " + wrn).c_str()); + }); + } $$ = new FunctionCall(name, args, argsOK ? fn : NULL); } } @@ -735,8 +790,6 @@ ScalarNumberExprRef expr = $3; if (numberVar->unitType() != expr->unitType()) PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has unit type " + unitTypeStr(numberVar->unitType()) + ", assignment has unit type " + unitTypeStr(expr->unitType()) + " though.").c_str()); - else if (numberVar->unitFactor() != expr->unitFactor()) - PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' has a different unit prefix.").c_str()); else if (numberVar->isFinal() != expr->isFinal()) PARSE_ERR(@3, (String("Variable assignment: Variable '") + name + "' was declared as " + String(numberVar->isFinal() ? "final" : "not final") + ", assignment is " + String(expr->isFinal() ? "final" : "not final") + " though.").c_str()); } @@ -777,25 +830,31 @@ RealArrayElementRef element = new RealArrayElement(var, $3); $$ = new Assignment(element, $6); } else { - $$ = new NoOperation; + $$ = new NoOperation; // actually not possible to ever get here } } unary_expr: INTEGER { - $$ = new IntLiteral($1); + $$ = new IntLiteral({ .value = $1 }); } | REAL { - $$ = new RealLiteral($1); + $$ = new RealLiteral({ .value = $1 }); } | INTEGER_UNIT { - IntLiteralRef literal = new IntLiteral($1.iValue); - literal->setUnit($1.prefix, $1.unit); + IntLiteralRef literal = new IntLiteral({ + .value = $1.iValue, + .unitFactor = VMUnit::unitFactor($1.prefix), + .unitType = $1.unit + }); $$ = literal; } | REAL_UNIT { - RealLiteralRef literal = new RealLiteral($1.fValue); - literal->setUnit($1.prefix, $1.unit); + RealLiteralRef literal = new RealLiteral({ + .value = $1.fValue, + .unitFactor = VMUnit::unitFactor($1.prefix), + .unitType = $1.unit + }); $$ = literal; } | STRING { @@ -808,7 +867,7 @@ $$ = var; else { PARSE_ERR(@1, (String("No variable declared with name '") + $1 + "'.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } } | VARIABLE '[' expr ']' { @@ -816,16 +875,16 @@ VariableRef var = context->variableByName(name); if (!var) { PARSE_ERR(@1, (String("No variable declared with name '") + name + "'.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isArray(var->exprType())) { PARSE_ERR(@2, (String("Variable '") + name + "' is not an array variable.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if ($3->exprType() != INT_EXPR) { PARSE_ERR(@3, (String("Array variable '") + name + "' accessed with non integer expression.").c_str()); - $$ = new IntLiteral(0); - } else if ($3->asInt()->unitType() || $3->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if ($3->asInt()->unitType() || $3->asInt()->hasUnitFactorEver()) { PARSE_ERR(@3, "Units are not allowed as array index."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { if ($3->isConstExpr() && $3->asInt()->evalInt() >= ((ArrayExprRef)var)->arraySize()) PARSE_WRN(@3, (String("Index ") + ToString($3->asInt()->evalInt()) + @@ -853,10 +912,10 @@ | 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 if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if ($2->asInt()->unitType() || $2->asInt()->hasUnitFactorEver()) { PARSE_ERR(@2, "Units are not allowed for operands of bitwise operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { $$ = new BitwiseNot($2); } @@ -864,10 +923,10 @@ | NOT unary_expr { if ($2->exprType() != INT_EXPR) { 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 if ($2->asInt()->unitType() || $2->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if ($2->asInt()->unitType() || $2->asInt()->hasUnitFactorEver()) { PARSE_ERR(@2, "Units are not allowed for operands of logical operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { $$ = new Not($2); } @@ -875,7 +934,7 @@ | '!' unary_expr { if (!isScalarNumber($2->exprType())) { PARSE_ERR(@2, (String("Right operand of \"final\" operator '!' must be a scalar number expression, is ") + typeStr($2->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { $$ = new Final($2); } @@ -905,17 +964,21 @@ ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { PARSE_ERR(@1, (String("Left operand of operator 'or' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (rhs->exprType() != INT_EXPR) { 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 if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@1, "Units are not allowed for operands of logical operations."); - $$ = new IntLiteral(0); - } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@3, "Units are not allowed for operands of logical operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal()) + PARSE_WRN(@3, "Right operand of 'or' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal()) + PARSE_WRN(@1, "Left operand of 'or' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Or(lhs, rhs); } } @@ -929,17 +992,21 @@ ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { PARSE_ERR(@1, (String("Left operand of operator 'and' must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (rhs->exprType() != INT_EXPR) { 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 if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@1, "Units are not allowed for operands of logical operations."); - $$ = new IntLiteral(0); - } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@3, "Units are not allowed for operands of logical operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal()) + PARSE_WRN(@3, "Right operand of 'and' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal()) + PARSE_WRN(@1, "Left operand of 'and' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new And(lhs, rhs); } } @@ -951,17 +1018,21 @@ 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); + $$ = new IntLiteral({ .value = 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 if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations."); - $$ = new IntLiteral(0); - } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal()) + PARSE_WRN(@3, "Right operand of '.or.' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal()) + PARSE_WRN(@1, "Left operand of '.or.' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new BitwiseOr(lhs, rhs); } } @@ -975,17 +1046,21 @@ 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); + $$ = new IntLiteral({ .value = 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 if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@1, "Units are not allowed for operands of bitwise operations."); - $$ = new IntLiteral(0); - } else if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) { + $$ = new IntLiteral({ .value = 0 }); + } else if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) { PARSE_ERR(@3, "Units are not allowed for operands of bitwise operations."); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal()) + PARSE_WRN(@3, "Right operand of '.and.' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal()) + PARSE_WRN(@1, "Left operand of '.and.' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new BitwiseAnd(lhs, rhs); } } @@ -997,16 +1072,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '<' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '<' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '<' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '<' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::LESS_THAN, rhs); } } @@ -1015,16 +1094,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '>' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '>' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '>' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '>' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::GREATER_THAN, rhs); } } @@ -1033,16 +1116,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '<=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '<=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '<=' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '<=' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::LESS_OR_EQUAL, rhs); } } @@ -1051,16 +1138,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '>=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '>=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '>=' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '>=' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::GREATER_OR_EQUAL, rhs); } } @@ -1069,16 +1160,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '=' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '=' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '=' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '=' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::EQUAL, rhs); } } @@ -1087,16 +1182,20 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '#' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@3, (String("Right operand of operator '#' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of relative operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of relative operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '#' comparison is not 'final', left operand is 'final' though."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '#' comparison is not 'final', right operand is 'final' though."); $$ = new Relation(lhs, Relation::NOT_EQUAL, rhs); } } @@ -1108,20 +1207,24 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '+' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@1, (String("Right operand of operator '+' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->exprType() != rhs->exprType()) { PARSE_ERR(@2, (String("Operands of operator '+' must have same type; left operand is ") + typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of '+' operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of '+' operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '+' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '+' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Add(lhs,rhs); } } @@ -1130,20 +1233,24 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '-' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@1, (String("Right operand of operator '-' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->exprType() != rhs->exprType()) { PARSE_ERR(@2, (String("Operands of operator '-' must have same type; left operand is ") + typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType() || - lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor()) - { - PARSE_ERR(@2, "Operands of '-' operations must have same unit."); - $$ = new IntLiteral(0); - } else { + $$ = new IntLiteral({ .value = 0 }); + } else if (lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { + PARSE_ERR(@2, (String("Operands of '-' operations must have same unit, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); + } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '-' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '-' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Sub(lhs,rhs); } } @@ -1155,21 +1262,24 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '*' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@1, (String("Right operand of operator '*' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) { - PARSE_ERR(@2, "Only one operand of operator '*' may have a unit type"); - $$ = new IntLiteral(0); + PARSE_ERR(@2, (String("Only one operand of operator '*' may have a unit type, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->exprType() != rhs->exprType()) { PARSE_ERR(@2, (String("Operands of operator '*' must have same type; left operand is ") + typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0)) { - PARSE_ERR(@2, "Only one operand of operator '*' may have a unit prefix"); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '*' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '*' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Mul(lhs,rhs); } } @@ -1178,33 +1288,30 @@ ExpressionRef rhs = $3; if (!isScalarNumber(lhs->exprType())) { PARSE_ERR(@1, (String("Left operand of operator '/' must be a scalar number expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (!isScalarNumber(rhs->exprType())) { PARSE_ERR(@1, (String("Right operand of operator '/' must be a scalar number expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType() && lhs->asScalarNumberExpr()->unitType() != rhs->asScalarNumberExpr()->unitType()) { - PARSE_ERR(@2, "Operands of operator '/' with two different unit types."); - $$ = new IntLiteral(0); + PARSE_ERR(@2, (String("Operands of operator '/' with two different unit types, left operand is ") + + unitTypeStr(lhs->asScalarNumberExpr()->unitType()) + " and right operand is " + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + " though.").c_str()); + $$ = new IntLiteral({ .value = 0 }); } else if (!lhs->asScalarNumberExpr()->unitType() && rhs->asScalarNumberExpr()->unitType()) { - PARSE_ERR(@3, ("Dividing left operand without any unit type by right operand with unit type " + typeStr(rhs->exprType()) + " is not possible.").c_str()); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor() && - lhs->asScalarNumberExpr()->unitPrefix(0) && rhs->asScalarNumberExpr()->unitPrefix(0)) - { - PARSE_ERR(@2, "Dividing two operands with two different unit prefixes is not possible."); - $$ = new IntLiteral(0); - } else if (lhs->asScalarNumberExpr()->unitFactor() != rhs->asScalarNumberExpr()->unitFactor() && - rhs->asScalarNumberExpr()->unitPrefix(0)) - { - PARSE_ERR(@3, "Dividing left operand without any unit prefix by right operand with unit prefix is not possible."); - $$ = new IntLiteral(0); + PARSE_ERR(@3, ("Dividing left operand without any unit type by right operand with unit type (" + + unitTypeStr(rhs->asScalarNumberExpr()->unitType()) + ") is not possible.").c_str()); + $$ = new IntLiteral({ .value = 0 }); } else if (lhs->exprType() != rhs->exprType()) { PARSE_ERR(@2, (String("Operands of operator '/' must have same type; left operand is ") + typeStr(lhs->exprType()) + " and right operand is " + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { + if (lhs->asScalarNumberExpr()->isFinal() && !rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@3, "Right operand of '/' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asScalarNumberExpr()->isFinal() && rhs->asScalarNumberExpr()->isFinal()) + PARSE_WRN(@1, "Left operand of '/' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Div(lhs,rhs); } } @@ -1213,15 +1320,19 @@ ExpressionRef rhs = $3; if (lhs->exprType() != INT_EXPR) { PARSE_ERR(@1, (String("Left operand of modulo operator must be an integer expression, is ") + typeStr(lhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else if (rhs->exprType() != INT_EXPR) { PARSE_ERR(@3, (String("Right operand of modulo operator must be an integer expression, is ") + typeStr(rhs->exprType()) + " though.").c_str()); - $$ = new IntLiteral(0); + $$ = new IntLiteral({ .value = 0 }); } else { - if (lhs->asInt()->unitType() || lhs->asInt()->unitPrefix(0)) + if (lhs->asInt()->unitType() || lhs->asInt()->hasUnitFactorEver()) PARSE_ERR(@1, "Operands of modulo operator must not use any unit."); - if (rhs->asInt()->unitType() || rhs->asInt()->unitPrefix(0)) + if (rhs->asInt()->unitType() || rhs->asInt()->hasUnitFactorEver()) PARSE_ERR(@3, "Operands of modulo operator must not use any unit."); + if (lhs->asInt()->isFinal() && !rhs->asInt()->isFinal()) + PARSE_WRN(@3, "Right operand of 'mod' operation is not 'final', result will be 'final' though since left operand is 'final'."); + else if (!lhs->asInt()->isFinal() && rhs->asInt()->isFinal()) + PARSE_WRN(@1, "Left operand of 'mod' operation is not 'final', result will be 'final' though since right operand is 'final'."); $$ = new Mod(lhs,rhs); } }