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(); }
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; }