public override AstNode Visit(IndirectAccess node) { // Begin the node. builder.BeginNode(node); // Get the pointer expression. Expression basePointer = node.GetBasePointer(); // Visit it. basePointer.Accept(this); // Get the pointer and coercion type. IChelaType pointerType = basePointer.GetNodeType(); IChelaType coercionType = node.GetCoercionType(); if(pointerType != coercionType) Cast(node, basePointer.GetNodeValue(), pointerType, coercionType); return builder.EndNode(); }
public override AstNode Visit(IndirectAccess node) { // Evaluate the base pointer. Expression basePointer = node.GetBasePointer(); basePointer.Accept(this); // Get the base pointer type. IChelaType pointerType = basePointer.GetNodeType(); if(pointerType.IsReference()) { // Dereference the variable. ReferenceType refType = (ReferenceType) pointerType; pointerType = refType.GetReferencedType(); } if(!pointerType.IsPointer()) Error(node, "expected pointer indirection."); // Set the coercion type. node.SetCoercionType(pointerType); // Get the pointed type. PointerType pointer = (PointerType) pointerType; IChelaType pointedType = pointer.GetPointedType(); // Only structure type are supported. if(!pointedType.IsStructure()) Error(node, "only structure indirection is supported."); // Cast the structure type. Structure structType = (Structure) pointedType; // Check that the structure has the member. ScopeMember member = structType.FindMemberRecursive(node.GetName()); if(member == null) Error(node, "couldn't find the member '{0}'.", node.GetName()); // Check the flags. if((member.GetFlags() & MemberFlags.InstanceMask) == MemberFlags.Static) Error(node, "cannot use pointer indirectionto access static members."); // TODO: Check the access flags. // Perform checks depending on the type of the member. if(member.IsVariable()) { Variable variable = (Variable) member; if(!variable.IsField() && !variable.IsProperty()) Error(node, "expected field/property member."); IChelaType varType = variable.GetVariableType(); if(varType.IsStructure()) varType = ReferenceType.Create(varType); // Required for nested access. node.SetNodeType(ReferenceType.Create(varType)); node.SetNodeValue(variable); if(variable.IsField()) { FieldVariable field = (FieldVariable) variable; node.SetSlot(field.GetSlot()); } } else if(member.IsFunction()) { Function function = (Function) member; if(!function.IsMethod()) Error(node, "expected a method member."); Method method = (Method) function; node.SetSlot(method.GetVSlot()); node.SetNodeType(method.GetFunctionType()); node.SetNodeValue(method); } else if(member.IsFunctionGroup()) { FunctionGroup functionGroup = (FunctionGroup)member; FunctionGroupSelector selector = new FunctionGroupSelector(functionGroup); node.SetNodeType(ChelaType.GetFunctionGroupType()); node.SetNodeValue(selector); } else { Error(node, "expected field or method member."); } return node; }