/// <summary> /// Performs the semantic analysis of the statement /// </summary> /// <param name="instance">the reference instance on which this element should analysed</param> /// <returns>True if semantic analysis should be continued</returns> public override bool SemanticAnalysis(Utils.INamable instance) { bool retVal = base.SemanticAnalysis(instance); if (retVal) { ListExpression.SemanticAnalysis(instance); Types.Collection collectionType = ListExpression.GetExpressionType() as Types.Collection; if (collectionType != null) { IteratorVariable.Type = collectionType.Type; } Value.SemanticAnalysis(instance); Types.Type valueType = Value.GetExpressionType(); if (valueType != null) { if (!valueType.Match(collectionType.Type)) { AddError("Type of " + Value + " does not match collection type " + collectionType); } } else { AddError("Cannot determine type of " + Value); } if (Condition != null) { Condition.SemanticAnalysis(instance); } } return(retVal); }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { Types.Type targetType = VariableIdentification.GetExpressionType(); if (targetType == null) { Root.AddError("Cannot determine type of target " + VariableIdentification.ToString()); } else if (Expression != null) { Expression.checkExpression(); Types.Type type = Expression.GetExpressionType(); if (type != null) { if (targetType != null) { if (!targetType.Match(type)) { UnaryExpression unaryExpression = Expression as UnaryExpression; if (unaryExpression != null && unaryExpression.Term.LiteralValue != null) { if (targetType.getValue(unaryExpression.ToString()) == null) { Root.AddError("Expression " + Expression.ToString() + " does not fit in variable " + VariableIdentification.ToString()); } } else { Root.AddError("Expression [" + Expression.ToString() + "] type (" + type.FullName + ") does not match variable [" + VariableIdentification.ToString() + "] type (" + targetType.FullName + ")"); } } } else { Root.AddError("Cannot determine variable type"); } } else { Root.AddError("Cannot determine expression type (3) for " + Expression.ToString()); } } else { Root.AddError("Invalid expression in assignment"); } }
/// <summary> /// Provides the type of this expression /// </summary> /// <returns></returns> public override Types.Type GetExpressionType() { Types.Type retVal = null; Types.Type leftType = Left.GetExpressionType(); if (leftType == null) { AddError("Cannot determine expression type (1) for " + Left.ToString()); } else { Types.Type rightType = Right.GetExpressionType(); if (rightType == null) { AddError("Cannot determine expression type (2) for " + Right.ToString()); } else { switch (Operation) { case OPERATOR.EXP: case OPERATOR.MULT: case OPERATOR.DIV: case OPERATOR.ADD: case OPERATOR.SUB: if (leftType.Match(rightType)) { if (leftType is Types.IntegerType || leftType is Types.DoubleType) { retVal = rightType; } else { retVal = leftType; } } else { retVal = leftType.CombineType(rightType, Operation); } break; case OPERATOR.AND: case OPERATOR.OR: if (leftType == EFSSystem.BoolType && rightType == EFSSystem.BoolType) { retVal = EFSSystem.BoolType; } break; case OPERATOR.EQUAL: case OPERATOR.NOT_EQUAL: case OPERATOR.LESS: case OPERATOR.LESS_OR_EQUAL: case OPERATOR.GREATER: case OPERATOR.GREATER_OR_EQUAL: if (leftType.Match(rightType) || rightType.Match(leftType)) { retVal = EFSSystem.BoolType; } break; case OPERATOR.IN: case OPERATOR.NOT_IN: Types.Collection collection = rightType as Types.Collection; if (collection != null) { if (collection.Type == null) { retVal = EFSSystem.BoolType; } else if (collection.Type == leftType) { retVal = EFSSystem.BoolType; } } else { Types.StateMachine stateMachine = rightType as Types.StateMachine; if (stateMachine != null && leftType.Match(stateMachine)) { retVal = EFSSystem.BoolType; } } break; case OPERATOR.UNDEF: break; } } } return(retVal); }
public override ICallable getStaticCallable() { if (__staticCallable == null) { ICallable left = Left.getStaticCallable(); if (left != null) { ICallable right = Right.getStaticCallable(); if (right != null) { if (left.FormalParameters.Count == right.FormalParameters.Count) { bool match = true; for (int i = 0; i < left.FormalParameters.Count; i++) { Types.Type leftType = ((Parameter)left.FormalParameters[i]).Type; Types.Type rightType = ((Parameter)right.FormalParameters[i]).Type; if (!leftType.Equals(rightType)) { AddError("Non matching formal parameter type for parameter " + i + " " + leftType + " vs " + rightType); match = false; } } if (left.ReturnType != right.ReturnType) { AddError("Non matching return types " + left.ReturnType + " vs " + right.ReturnType); match = false; } if (match) { // Create a dummy funciton for type analysis Function function = (Function)Generated.acceptor.getFactory().createFunction(); function.Name = ToString(); function.ReturnType = left.ReturnType; foreach (Parameter param in left.FormalParameters) { Parameter parameter = (Parameter)Generated.acceptor.getFactory().createParameter(); parameter.Name = param.Name; parameter.Type = param.Type; parameter.Enclosing = function; function.appendParameters(parameter); } function.Enclosing = Root; __staticCallable = function; } } else { AddError("Invalid number of parameters, " + Left + " and " + Right + " should have the same number of parameters"); } } else { // Left is not null, but right is. // Ensure that right type corresponds to left return type // and return left Types.Type rightType = Right.GetExpressionType(); if (rightType.Match(left.ReturnType)) { __staticCallable = left; } else { AddError(Left + "(" + left.ReturnType + " ) does not correspond to " + Right + "(" + rightType + ")"); } } } else { ICallable right = Right.getStaticCallable(); if (right != null) { // Right is not null, but left is. // Ensure that left type corresponds to right return type // and return right Types.Type leftType = Left.GetExpressionType(); if ((leftType.Match(right.ReturnType))) { __staticCallable = right; } else { AddError(Left + "(" + leftType + ") does not correspond to " + Right + "(" + right.ReturnType + ")"); } } } } return(__staticCallable); }