|
@@ -1,275 +1,284 @@
|
|
|
-/**
|
|
|
- * Copyright (c) 2014 committers of YAKINDU and others.
|
|
|
- * All rights reserved. This program and the accompanying materials
|
|
|
- * are made available under the terms of the Eclipse Public License v1.0
|
|
|
- * which accompanies this distribution, and is available at
|
|
|
- * http://www.eclipse.org/legal/epl-v10.html
|
|
|
- * Contributors:
|
|
|
- * committers of YAKINDU - initial API and implementation
|
|
|
- *
|
|
|
- */
|
|
|
-package org.yakindu.base.expressions.inferrer;
|
|
|
-
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.BOOLEAN;
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.INTEGER;
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.NULL;
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.REAL;
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.STRING;
|
|
|
-import static org.yakindu.base.types.typesystem.ITypeSystem.VOID;
|
|
|
-
|
|
|
-import org.eclipse.emf.common.util.EList;
|
|
|
-import org.eclipse.xtext.EcoreUtil2;
|
|
|
-import org.yakindu.base.expressions.expressions.AssignmentExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.BitwiseAndExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.BitwiseOrExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.BitwiseXorExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.BoolLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.ConditionalExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.DoubleLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.Expression;
|
|
|
-import org.yakindu.base.expressions.expressions.FeatureCall;
|
|
|
-import org.yakindu.base.expressions.expressions.FloatLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.HexLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.IntLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.LogicalAndExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.LogicalNotExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.LogicalOrExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.LogicalRelationExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.NullLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.NumericalUnaryExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.ParenthesizedExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.ShiftExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.StringLiteral;
|
|
|
-import org.yakindu.base.expressions.expressions.TypeCastExpression;
|
|
|
-import org.yakindu.base.expressions.expressions.UnaryOperator;
|
|
|
-import org.yakindu.base.types.EnumerationType;
|
|
|
-import org.yakindu.base.types.Enumerator;
|
|
|
-import org.yakindu.base.types.Operation;
|
|
|
-import org.yakindu.base.types.Parameter;
|
|
|
-import org.yakindu.base.types.Property;
|
|
|
-import org.yakindu.base.types.Type;
|
|
|
-import org.yakindu.base.types.TypeAlias;
|
|
|
-import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
|
|
|
-
|
|
|
-/**
|
|
|
- * @author andreas muelder - Initial contribution and API
|
|
|
- *
|
|
|
- */
|
|
|
-public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implements ExpressionsTypeInferrerMessages {
|
|
|
-
|
|
|
- public Type infer(AssignmentExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getVarRef());
|
|
|
- Type type2 = inferTypeDispatch(e.getExpression());
|
|
|
- assertAssignable(type1, type2, String.format(ASSIGNMENT_OPERATOR, e.getOperator(), type1, type2));
|
|
|
- return inferTypeDispatch(e.getVarRef());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(ConditionalExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getTrueCase());
|
|
|
- Type type2 = inferTypeDispatch(e.getFalseCase());
|
|
|
- assertCompatible(type1, type2, String.format(COMMON_TYPE, type1, type2));
|
|
|
- assertIsType(inferTypeDispatch(e.getCondition()), CONDITIONAL_BOOLEAN, getType(BOOLEAN));
|
|
|
- return getCommonType(type1, type2);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(LogicalOrExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
|
|
|
- assertIsType(type2, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
|
|
|
- return getType(BOOLEAN);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(LogicalAndExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
|
|
|
- assertIsType(type2, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
|
|
|
- return getType(BOOLEAN);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(LogicalNotExpression e) {
|
|
|
- Type type = inferTypeDispatch(e.getOperand());
|
|
|
- assertIsType(type, String.format(LOGICAL_OPERATOR, "!", type), getType(BOOLEAN));
|
|
|
- return getType(BOOLEAN);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(BitwiseXorExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
|
|
|
- assertIsType(type2, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(BitwiseOrExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
|
|
|
- assertIsType(type2, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(BitwiseAndExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
|
|
|
- assertIsType(type2, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(ShiftExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertIsType(type1, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
|
|
|
- assertIsType(type2, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(LogicalRelationExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertCompatible(type1, type2, String.format(COMPARSION_OPERATOR, e.getOperator(), type1, type2));
|
|
|
- Type result = getType(BOOLEAN);
|
|
|
- return result;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(NumericalAddSubtractExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertCompatible(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
|
|
|
- assertIsType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
- getType(REAL));
|
|
|
- return getCommonType(e.getLeftOperand(), e.getRightOperand());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(NumericalMultiplyDivideExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
- assertCompatible(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
|
|
|
- assertIsType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
- getType(REAL));
|
|
|
- return getCommonType(type1, type2);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(NumericalUnaryExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getOperand());
|
|
|
- if (e.getOperator() == UnaryOperator.COMPLEMENT)
|
|
|
- assertIsType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER));
|
|
|
- else {
|
|
|
- assertCompatible(type1, getType(REAL), String.format(ARITHMETIC_OPERATOR, e.getOperator(), type1));
|
|
|
- }
|
|
|
- return type1;
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(TypeCastExpression e) {
|
|
|
- Type type1 = inferTypeDispatch(e.getOperand());
|
|
|
- Type type2 = inferTypeDispatch(e.getType());
|
|
|
- assertCompatible(type1, type2, String.format(CAST_OPERATORS, type1, type2));
|
|
|
- return inferTypeDispatch(e.getType());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(EnumerationType enumType) {
|
|
|
- return enumType;
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(Enumerator enumerator) {
|
|
|
- return EcoreUtil2.getContainerOfType(enumerator, Type.class);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(Type type) {
|
|
|
- return type;
|
|
|
- }
|
|
|
-
|
|
|
- // TODO: How to handle TypeAlias, like in C as weak types or like Lint
|
|
|
- // strong types?
|
|
|
- public Object infer(TypeAlias typeAlias) {
|
|
|
- return inferTypeDispatch(typeAlias.getType());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(FeatureCall e) {
|
|
|
- if (e.isOperationCall()) {
|
|
|
- Operation operation = (Operation) e.getFeature();
|
|
|
- EList<Parameter> parameters = operation.getParameters();
|
|
|
- EList<Expression> args = e.getArgs();
|
|
|
- inferParameter(parameters, args);
|
|
|
- }
|
|
|
- return inferTypeDispatch(e.getFeature());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(ElementReferenceExpression e) {
|
|
|
- if (e.isOperationCall()) {
|
|
|
- Operation operation = (Operation) e.getReference();
|
|
|
- EList<Parameter> parameters = operation.getParameters();
|
|
|
- EList<Expression> args = e.getArgs();
|
|
|
- inferParameter(parameters, args);
|
|
|
- }
|
|
|
- return inferTypeDispatch(e.getReference());
|
|
|
- }
|
|
|
-
|
|
|
- protected void inferParameter(EList<Parameter> parameters, EList<Expression> args) {
|
|
|
- if (parameters.size() == args.size()) {
|
|
|
- for (int i = 0; i < parameters.size(); i++) {
|
|
|
- Type type1 = inferTypeDispatch(parameters.get(i));
|
|
|
- Type type2 = inferTypeDispatch(args.get(i));
|
|
|
- assertCompatible(type2, type1, String.format(INCOMPATIBLE_TYPES, type2, type1));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(ParenthesizedExpression e) {
|
|
|
- return inferTypeDispatch(e.getExpression());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(PrimitiveValueExpression e) {
|
|
|
- return inferTypeDispatch(e.getValue());
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(BoolLiteral literal) {
|
|
|
- return getType(BOOLEAN);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(IntLiteral literal) {
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(HexLiteral literal) {
|
|
|
- return getType(INTEGER);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(DoubleLiteral literal) {
|
|
|
- return getType(REAL);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(FloatLiteral literal){
|
|
|
- return getType(REAL);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(StringLiteral literal) {
|
|
|
- return getType(STRING);
|
|
|
- }
|
|
|
-
|
|
|
- public Type infer(NullLiteral literal) {
|
|
|
- return getType(NULL);
|
|
|
- }
|
|
|
-
|
|
|
- public Object infer(Property p) {
|
|
|
- Type type = inferTypeDispatch(p.getType());
|
|
|
- assertNotType(type, VARIABLE_VOID_TYPE, getType(VOID));
|
|
|
- return inferTypeDispatch(type);
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public Object infer(Operation e) {
|
|
|
- return inferTypeDispatch(e.getType() != null ? e.getType() : getType(VOID));
|
|
|
- }
|
|
|
-
|
|
|
- public Object infer(Parameter e) {
|
|
|
- return inferTypeDispatch(e.getType());
|
|
|
- }
|
|
|
-}
|
|
|
+/**
|
|
|
+ * Copyright (c) 2014 committers of YAKINDU and others.
|
|
|
+ * All rights reserved. This program and the accompanying materials
|
|
|
+ * are made available under the terms of the Eclipse Public License v1.0
|
|
|
+ * which accompanies this distribution, and is available at
|
|
|
+ * http://www.eclipse.org/legal/epl-v10.html
|
|
|
+ * Contributors:
|
|
|
+ * committers of YAKINDU - initial API and implementation
|
|
|
+ *
|
|
|
+ */
|
|
|
+package org.yakindu.base.expressions.inferrer;
|
|
|
+
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.BOOLEAN;
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.INTEGER;
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.NULL;
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.REAL;
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.STRING;
|
|
|
+import static org.yakindu.base.types.typesystem.ITypeSystem.VOID;
|
|
|
+
|
|
|
+import org.eclipse.emf.common.util.EList;
|
|
|
+import org.eclipse.xtext.EcoreUtil2;
|
|
|
+import org.yakindu.base.expressions.expressions.AssignmentExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseAndExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseOrExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.BitwiseXorExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.BoolLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.ConditionalExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.DoubleLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.ElementReferenceExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.Expression;
|
|
|
+import org.yakindu.base.expressions.expressions.FeatureCall;
|
|
|
+import org.yakindu.base.expressions.expressions.FloatLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.HexLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.IntLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalAndExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalNotExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalOrExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.LogicalRelationExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.NullLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalAddSubtractExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalMultiplyDivideExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.NumericalUnaryExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.ParenthesizedExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.PrimitiveValueExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.ShiftExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.StringLiteral;
|
|
|
+import org.yakindu.base.expressions.expressions.TypeCastExpression;
|
|
|
+import org.yakindu.base.expressions.expressions.UnaryOperator;
|
|
|
+import org.yakindu.base.types.EnumerationType;
|
|
|
+import org.yakindu.base.types.Enumerator;
|
|
|
+import org.yakindu.base.types.Operation;
|
|
|
+import org.yakindu.base.types.Parameter;
|
|
|
+import org.yakindu.base.types.Property;
|
|
|
+import org.yakindu.base.types.Type;
|
|
|
+import org.yakindu.base.types.TypeAlias;
|
|
|
+import org.yakindu.base.types.inferrer.AbstractTypeSystemInferrer;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author andreas muelder - Initial contribution and API
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class ExpressionsTypeInferrer extends AbstractTypeSystemInferrer implements ExpressionsTypeInferrerMessages {
|
|
|
+
|
|
|
+ public Type infer(AssignmentExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getVarRef());
|
|
|
+ Type type2 = inferTypeDispatch(e.getExpression());
|
|
|
+ assertAssignable(type1, type2, String.format(ASSIGNMENT_OPERATOR, e.getOperator(), type1, type2));
|
|
|
+ return inferTypeDispatch(e.getVarRef());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(ConditionalExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getTrueCase());
|
|
|
+ Type type2 = inferTypeDispatch(e.getFalseCase());
|
|
|
+ assertCompatible(type1, type2, String.format(COMMON_TYPE, type1, type2));
|
|
|
+ assertIsType(inferTypeDispatch(e.getCondition()), CONDITIONAL_BOOLEAN, getType(BOOLEAN));
|
|
|
+ return getCommonType(type1, type2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(LogicalOrExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
|
|
|
+ assertIsType(type2, String.format(LOGICAL_OPERATORS, "||", type1, type2), getType(BOOLEAN));
|
|
|
+ return getType(BOOLEAN);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(LogicalAndExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
|
|
|
+ assertIsType(type2, String.format(LOGICAL_OPERATORS, "&&", type1, type2), getType(BOOLEAN));
|
|
|
+ return getType(BOOLEAN);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(LogicalNotExpression e) {
|
|
|
+ Type type = inferTypeDispatch(e.getOperand());
|
|
|
+ assertIsType(type, String.format(LOGICAL_OPERATOR, "!", type), getType(BOOLEAN));
|
|
|
+ return getType(BOOLEAN);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(BitwiseXorExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
|
|
|
+ assertIsType(type2, String.format(BITWISE_OPERATORS, "^", type1, type2), getType(INTEGER));
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(BitwiseOrExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
|
|
|
+ assertIsType(type2, String.format(BITWISE_OPERATORS, "|", type1, type2), getType(INTEGER));
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(BitwiseAndExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
|
|
|
+ assertIsType(type2, String.format(BITWISE_OPERATORS, "&", type1, type2), getType(INTEGER));
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(ShiftExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertIsType(type1, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
|
|
|
+ assertIsType(type2, String.format(BITWISE_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER));
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(LogicalRelationExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertCompatible(type1, type2, String.format(COMPARSION_OPERATOR, e.getOperator(), type1, type2));
|
|
|
+ Type result = getType(BOOLEAN);
|
|
|
+ return result;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(NumericalAddSubtractExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ if (registry.isSame(type1, getType(STRING))) {
|
|
|
+ assertCompatibleWithConversion(type1, type2, String.format(CAN_NOT_CONVERT, type2, type1));
|
|
|
+ return getType(STRING);
|
|
|
+ } else {
|
|
|
+ assertCompatible(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
|
|
|
+ assertIsType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
+ getType(REAL));
|
|
|
+ assertIsType(type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
+ getType(REAL));
|
|
|
+ return getCommonType(e.getLeftOperand(), e.getRightOperand());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(NumericalMultiplyDivideExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getLeftOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getRightOperand());
|
|
|
+ assertCompatible(type1, type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2));
|
|
|
+ assertIsType(type1, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
+ getType(REAL));
|
|
|
+ assertIsType(type2, String.format(ARITHMETIC_OPERATORS, e.getOperator(), type1, type2), getType(INTEGER),
|
|
|
+ getType(REAL));
|
|
|
+ return getCommonType(type1, type2);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(NumericalUnaryExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getOperand());
|
|
|
+ if (e.getOperator() == UnaryOperator.COMPLEMENT)
|
|
|
+ assertIsType(type1, String.format(BITWISE_OPERATOR, '~', type1), getType(INTEGER));
|
|
|
+ else {
|
|
|
+ assertCompatible(type1, getType(REAL), String.format(ARITHMETIC_OPERATOR, e.getOperator(), type1));
|
|
|
+ }
|
|
|
+ return type1;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(TypeCastExpression e) {
|
|
|
+ Type type1 = inferTypeDispatch(e.getOperand());
|
|
|
+ Type type2 = inferTypeDispatch(e.getType());
|
|
|
+ assertAssignable(type1, type2, String.format(CAST_OPERATORS, type1, type2));
|
|
|
+ return inferTypeDispatch(e.getType());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(EnumerationType enumType) {
|
|
|
+ return enumType;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(Enumerator enumerator) {
|
|
|
+ return EcoreUtil2.getContainerOfType(enumerator, Type.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(Type type) {
|
|
|
+ return type;
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: How to handle TypeAlias, like in C as weak types or like Lint
|
|
|
+ // strong types?
|
|
|
+ public Object infer(TypeAlias typeAlias) {
|
|
|
+ return inferTypeDispatch(typeAlias.getType());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(FeatureCall e) {
|
|
|
+ if (e.isOperationCall()) {
|
|
|
+ Operation operation = (Operation) e.getFeature();
|
|
|
+ EList<Parameter> parameters = operation.getParameters();
|
|
|
+ EList<Expression> args = e.getArgs();
|
|
|
+ inferParameter(parameters, args);
|
|
|
+ }
|
|
|
+ return inferTypeDispatch(e.getFeature());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(ElementReferenceExpression e) {
|
|
|
+ if (e.isOperationCall()) {
|
|
|
+ Operation operation = (Operation) e.getReference();
|
|
|
+ EList<Parameter> parameters = operation.getParameters();
|
|
|
+ EList<Expression> args = e.getArgs();
|
|
|
+ inferParameter(parameters, args);
|
|
|
+ }
|
|
|
+ return inferTypeDispatch(e.getReference());
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void inferParameter(EList<Parameter> parameters, EList<Expression> args) {
|
|
|
+ if (parameters.size() == args.size()) {
|
|
|
+ for (int i = 0; i < parameters.size(); i++) {
|
|
|
+ Type type1 = inferTypeDispatch(parameters.get(i));
|
|
|
+ Type type2 = inferTypeDispatch(args.get(i));
|
|
|
+ assertCompatible(type2, type1, String.format(INCOMPATIBLE_TYPES, type2, type1));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(ParenthesizedExpression e) {
|
|
|
+ return inferTypeDispatch(e.getExpression());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(PrimitiveValueExpression e) {
|
|
|
+ return inferTypeDispatch(e.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(BoolLiteral literal) {
|
|
|
+ return getType(BOOLEAN);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(IntLiteral literal) {
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(HexLiteral literal) {
|
|
|
+ return getType(INTEGER);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(DoubleLiteral literal) {
|
|
|
+ return getType(REAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(FloatLiteral literal) {
|
|
|
+ return getType(REAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(StringLiteral literal) {
|
|
|
+ return getType(STRING);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Type infer(NullLiteral literal) {
|
|
|
+ return getType(NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Object infer(Property p) {
|
|
|
+ Type type = inferTypeDispatch(p.getType());
|
|
|
+ assertNotType(type, VARIABLE_VOID_TYPE, getType(VOID));
|
|
|
+ return inferTypeDispatch(type);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public Object infer(Operation e) {
|
|
|
+ return inferTypeDispatch(e.getType() != null ? e.getType() : getType(VOID));
|
|
|
+ }
|
|
|
+
|
|
|
+ public Object infer(Parameter e) {
|
|
|
+ return inferTypeDispatch(e.getType());
|
|
|
+ }
|
|
|
+}
|