/// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }