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();
        }
Example #2
0
        public override AstNode Visit(AssignmentExpression node)
        {
            // Get the variable and value expression.
            Expression variable = node.GetVariable();
            Expression value = node.GetValue();

            // Visit them.
            variable.Accept(this);
            value.Accept(this);

            // Get their types.
            IChelaType variableType = variable.GetNodeType();
            IChelaType valueType = value.GetNodeType();

            // Set the node type.
            node.SetNodeType(variableType);

            // The variable must be a reference.
            if(!variableType.IsReference())
                Error(node, "trying to set something that isn't a reference.");

            // Check the variable is not a constant.
            variableType = DeReferenceType(variableType);
            if(variableType.IsConstant())
                Error(node, "cannot modify constants.");

            // Check for the read-only constraint.
            Variable variableSlot = variable.GetNodeValue() as Variable;
            if(variableSlot != null && variableSlot.IsReadOnly())
                CheckReadOnlyConstraint(node, variableSlot);

            // Set the coercion type.
            node.SetCoercionType(variableType);

            // Check the type compatibility.
            //System.Console.WriteLine("{0}->{1}", valueType, variableType);
            if(variableType != valueType &&
               Coerce(node, variableType, valueType, value.GetNodeValue()) != variableType)
            {
                // Delay integer constants casting.
                if(valueType.IsConstant())
                {
                    valueType = DeConstType(valueType);
                    if(valueType.IsInteger() &&
                        valueType != ChelaType.GetBoolType() &&
                        valueType != ChelaType.GetCharType())
                        node.DelayedCoercion = true;
                }

                if(!node.DelayedCoercion)
                    Error(value, "cannot implicitly cast from {0} to {1}.",
                        valueType.GetDisplayName(), variableType.GetDisplayName());
            }

            return node;
        }