|
@@ -1,7 +1,7 @@
|
|
MODULE ExpressionTree;
|
|
MODULE ExpressionTree;
|
|
IMPORT
|
|
IMPORT
|
|
Cast, Context, ContextHierarchy,
|
|
Cast, Context, ContextHierarchy,
|
|
- JS,
|
|
|
|
|
|
+ JS, Format, Message,
|
|
Errors, Expression, LanguageContext, Operator, Record, String, Types, TypeId;
|
|
Errors, Expression, LanguageContext, Operator, Record, String, Types, TypeId;
|
|
TYPE
|
|
TYPE
|
|
BinaryOperator* = PROCEDURE(l, r: Expression.PType): Expression.PType;
|
|
BinaryOperator* = PROCEDURE(l, r: Expression.PType): Expression.PType;
|
|
@@ -120,7 +120,7 @@ VAR
|
|
|
|
|
|
PROCEDURE throwTypeNameExpected*();
|
|
PROCEDURE throwTypeNameExpected*();
|
|
BEGIN
|
|
BEGIN
|
|
- Errors.raise("type name expected");
|
|
|
|
|
|
+ Errors.raise(Message.typeNameExpected);
|
|
END;
|
|
END;
|
|
|
|
|
|
PROCEDURE castCode*(type: Types.PType; cx: Context.Type): STRING;
|
|
PROCEDURE castCode*(type: Types.PType; cx: Context.Type): STRING;
|
|
@@ -161,8 +161,7 @@ VAR
|
|
t := t.base;
|
|
t := t.base;
|
|
END;
|
|
END;
|
|
IF t = NIL THEN
|
|
IF t = NIL THEN
|
|
- Errors.raise(prefix + ": '" + to.description()
|
|
|
|
- + "' is not an extension of '" + from.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format3(Message.isNotAnExtencion, prefix, to.description(), from.description()));
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
|
|
@@ -171,24 +170,17 @@ BEGIN
|
|
|
|
|
|
pointerExpected <- fromType IS Record.PPointer;
|
|
pointerExpected <- fromType IS Record.PPointer;
|
|
IF ~pointerExpected & ~(fromType IS Record.PType) THEN
|
|
IF ~pointerExpected & ~(fromType IS Record.PType) THEN
|
|
- Errors.raise(
|
|
|
|
- prefix + ": POINTER to type or RECORD expected, got '"
|
|
|
|
- + fromType.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format2(Message.ptrToTypeExpected, prefix, fromType.description()));
|
|
END;
|
|
END;
|
|
|
|
|
|
IF ~pointerExpected THEN
|
|
IF ~pointerExpected THEN
|
|
IF (fromInfo # NIL) & ~fromInfo.isReference() THEN
|
|
IF (fromInfo # NIL) & ~fromInfo.isReference() THEN
|
|
- Errors.raise(
|
|
|
|
- prefix + ": a value variable cannot be used");
|
|
|
|
|
|
+ Errors.raise(Format.format1(Message.valueVarCantBeUsed, prefix));
|
|
ELSIF ~(toType IS Record.PType) THEN
|
|
ELSIF ~(toType IS Record.PType) THEN
|
|
- Errors.raise(
|
|
|
|
- prefix + ": RECORD type expected as an argument of RECORD " + msg + ", got '"
|
|
|
|
- + toType.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format3(Message.recTypeExpectedAsArg, prefix, msg, toType.description()));
|
|
END;
|
|
END;
|
|
ELSIF ~(toType IS Record.PPointer) THEN
|
|
ELSIF ~(toType IS Record.PPointer) THEN
|
|
- Errors.raise(
|
|
|
|
- prefix + ": POINTER type expected as an argument of POINTER " + msg + ", got '"
|
|
|
|
- + toType.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format3(Message.ptrTypeExpectedAsArg, prefix, msg, toType.description()));
|
|
END;
|
|
END;
|
|
|
|
|
|
IF pointerExpected THEN
|
|
IF pointerExpected THEN
|
|
@@ -225,16 +217,12 @@ BEGIN
|
|
ELSE
|
|
ELSE
|
|
fromDescription := "no type (proper procedure call)";
|
|
fromDescription := "no type (proper procedure call)";
|
|
END;
|
|
END;
|
|
- Errors.raise("type mismatch: expected '" + to.description()
|
|
|
|
- + "', got " + fromDescription);
|
|
|
|
|
|
+ Errors.raise(Format.format2(Message.typeMismatch, to.description(), fromDescription));
|
|
END;
|
|
END;
|
|
|
|
|
|
PROCEDURE throwOperatorTypeMismatch(op, expect: STRING; type: Types.PType);
|
|
PROCEDURE throwOperatorTypeMismatch(op, expect: STRING; type: Types.PType);
|
|
BEGIN
|
|
BEGIN
|
|
- Errors.raise(
|
|
|
|
- "operator '" + op +
|
|
|
|
- "' type mismatch: " + expect + " expected, got '" +
|
|
|
|
- type.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format3(Message.opTypeMismatch, op, expect, type.description()));
|
|
END;
|
|
END;
|
|
|
|
|
|
PROCEDURE checkTypeMatch(from, to: Types.PType);
|
|
PROCEDURE checkTypeMatch(from, to: Types.PType);
|
|
@@ -298,7 +286,7 @@ PROCEDURE notTypeId(e: Expression.PType);
|
|
BEGIN
|
|
BEGIN
|
|
info <- e.info();
|
|
info <- e.info();
|
|
IF info IS TypeId.PType THEN
|
|
IF info IS TypeId.PType THEN
|
|
- Errors.raise("type name '" + info.type().description() + "' cannot be used as an expression");
|
|
|
|
|
|
+ Errors.raise(Format.format1(Message.typeNameCantBeExpr, info.type().description()));
|
|
END;
|
|
END;
|
|
END;
|
|
END;
|
|
|
|
|
|
@@ -381,7 +369,7 @@ BEGIN
|
|
o := assertNumericOrSetOp(type, s, Operator.mulReal, Operator.mulInt, Operator.setIntersection);
|
|
o := assertNumericOrSetOp(type, s, Operator.mulReal, Operator.mulInt, Operator.setIntersection);
|
|
ELSIF s = "/" THEN
|
|
ELSIF s = "/" THEN
|
|
IF Types.isInt(type) THEN
|
|
IF Types.isInt(type) THEN
|
|
- Errors.raise("operator DIV expected for integer division");
|
|
|
|
|
|
+ Errors.raise(Message.opDivExpected);
|
|
END;
|
|
END;
|
|
o := assertNumericOrSetOp(type, s, Operator.divReal, NIL, Operator.setSymmetricDiff);
|
|
o := assertNumericOrSetOp(type, s, Operator.divReal, NIL, Operator.setSymmetricDiff);
|
|
ELSIF s = "DIV" THEN
|
|
ELSIF s = "DIV" THEN
|
|
@@ -390,8 +378,7 @@ BEGIN
|
|
o := assertIntOp(type, s, Operator.mod);
|
|
o := assertIntOp(type, s, Operator.mod);
|
|
ELSIF s = "&" THEN
|
|
ELSIF s = "&" THEN
|
|
IF type # Types.basic.bool THEN
|
|
IF type # Types.basic.bool THEN
|
|
- Errors.raise("BOOLEAN expected as operand of '&', got '"
|
|
|
|
- + type.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format1(Message.boolExpectedAsOperand, type.description()));
|
|
END;
|
|
END;
|
|
o := Operator.and;
|
|
o := Operator.and;
|
|
ELSE
|
|
ELSE
|
|
@@ -466,8 +453,7 @@ BEGIN
|
|
result := assertNumericOrSetOp(type, s, Operator.subReal, Operator.subInt, Operator.setDiff);
|
|
result := assertNumericOrSetOp(type, s, Operator.subReal, Operator.subInt, Operator.setDiff);
|
|
ELSIF s = "OR" THEN
|
|
ELSIF s = "OR" THEN
|
|
IF type # Types.basic.bool THEN
|
|
IF type # Types.basic.bool THEN
|
|
- Errors.raise("BOOLEAN expected as operand of 'OR', got '"
|
|
|
|
- + type.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format1(Message.boolExpectedAsOperandOfOr, type.description()));
|
|
END;
|
|
END;
|
|
result := Operator.or;
|
|
result := Operator.or;
|
|
END;
|
|
END;
|
|
@@ -509,7 +495,7 @@ BEGIN
|
|
|
|
|
|
type <- result.type();
|
|
type <- result.type();
|
|
IF type = NIL THEN
|
|
IF type = NIL THEN
|
|
- Errors.raise("procedure returning no result cannot be used in an expression");
|
|
|
|
|
|
+ Errors.raise(Message.procReturningNoResult);
|
|
END;
|
|
END;
|
|
RETURN result;
|
|
RETURN result;
|
|
END;
|
|
END;
|
|
@@ -539,8 +525,7 @@ END;
|
|
PROCEDURE Ops.in(left, right: Types.PType; cx: ContextHierarchy.Node): BinaryOperatorCx;
|
|
PROCEDURE Ops.in(left, right: Types.PType; cx: ContextHierarchy.Node): BinaryOperatorCx;
|
|
BEGIN
|
|
BEGIN
|
|
IF ~Types.isInt(left) THEN
|
|
IF ~Types.isInt(left) THEN
|
|
- Errors.raise(Types.intsDescription()
|
|
|
|
- + " expected as an element of SET, got '" + left.description() + "'");
|
|
|
|
|
|
+ Errors.raise(Format.format2(Message.expectedAsElemOfSet, Types.intsDescription(), left.description()));
|
|
END;
|
|
END;
|
|
checkImplicitCast(cx.root()^, right, Types.basic.set);
|
|
checkImplicitCast(cx.root()^, right, Types.basic.set);
|
|
|
|
|
|
@@ -808,4 +793,4 @@ PROCEDURE NumericOrSetOpTypeCheck.check(t: Types.PType): BOOLEAN;
|
|
RETURN SUPER(t) OR (t = Types.basic.set);
|
|
RETURN SUPER(t) OR (t = Types.basic.set);
|
|
END;
|
|
END;
|
|
|
|
|
|
-END ExpressionTree.
|
|
|
|
|
|
+END ExpressionTree.
|