Example #1
0
        public override AstNode Visit(AssignmentExpression node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Get the variable and his value.
            Expression variable = node.GetVariable();
            Expression value = node.GetValue();

            // Get the types.
            //IChelaType variableType = variable.GetNodeType();
            IChelaType valueType = value.GetNodeType();
            IChelaType coercionType = node.GetCoercionType();

            // Get the variable data.
            Variable variableData = (Variable)variable.GetNodeValue();

            // Visit the variable.
            variable.Accept(this);

            // Duplicate the reference.
            DuplicateReference(node, variableData);

            // Visit the value.
            value.Accept(this);

            // Check for delayed coercion
            if(node.DelayedCoercion)
            {
                ConstantValue constant = (ConstantValue) value.GetNodeValue();
                uint size = coercionType.GetSize();
                if(coercionType.IsUnsigned())
                {
                    // Check unsigned ranges.
                    ulong cval = constant.GetULongValue();
                    if(size <= 1 && cval > 0xFFu ||
                       size <= 2 && cval > 0xFFFFu ||
                       size <= 4 && cval > 0xFFFFFFFFu)
                        Error(node, "cannot implicitly convert {0} into a {1}.", cval, coercionType.GetName());
                }
                else
                {
                    // Check for unsigned constraint.
                    long cval = constant.GetLongValue();
                    if(cval < 0)
                    {
                        if(coercionType.IsUnsigned())
                            Error(node, "cannot convert signed {0} into {1}.", cval, coercionType.GetName());
                        cval = -cval;
                    }

                    // Check signed ranges.
                    if(size <= 1 && cval > 0x7Fu ||
                       size <= 2 && cval > 0x7FFFu ||
                       size <= 4 && cval > 0x7FFFFFFFu)
                        Error(node, "cannot implicitly convert {0} into a {1}.", cval, coercionType.GetName());
                }
            }

            // Cast the value.
            if(valueType != coercionType)
                Cast(node, value.GetNodeValue(), valueType, coercionType);

            // Store the value into the variable.
            PerformAssignment(node, variableData);

            // Set the node value.
            node.SetNodeValue(variableData);

            return builder.EndNode();
        }