Example #1
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;
        }