protected void VisitList(AstNode list) { try { while (list != null) { list.Accept(this); list = list.GetNext(); } } catch (System.SystemException sysException) { System.Console.WriteLine("Compiler bug near {0}", list.GetPosition().ToString()); System.Console.WriteLine(sysException.ToString()); System.Console.WriteLine(sysException.StackTrace); System.Environment.Exit(-1); } }
public Structure ExtractClass(AstNode where, ScopeMember member) { // Make sure its a structure or type group. if(!member.IsClass() && !member.IsStructure() &&!member.IsInternal() && !member.IsTypeGroup()) Error(where, "coudn't load runtime class."); // Read the type group. if(member.IsTypeGroup()) { TypeGroup group = (TypeGroup)member; Structure building = group.GetDefaultType(); if(building == null) Error(where, "unexpected type group {0}", @group.GetDisplayName()); // Prevent ambiguity of merged type group. building.CheckAmbiguity(where.GetPosition()); return building; } return (Structure)member; }
protected LexicalScope CreateLexicalScope(AstNode where, Function parentFunction) { LexicalScope ret = new LexicalScope(currentContainer, parentFunction); ret.Position = where.GetPosition(); return ret; }
public IChelaType ExtractActualType(AstNode where, IChelaType type) { // Extract from the meta type. if(!type.IsMetaType()) Error(where, "expected a type."); type = ExtractMetaType(type); // Use the default element from the type group. if(type.IsTypeGroup()) { TypeGroup group = (TypeGroup)type; Structure building = group.GetDefaultType(); type = building; if(building == null) Error(where, "unexpected type group {0}", @group.GetDisplayName()); // Prevent ambiguity of merged type group. building.CheckAmbiguity(where.GetPosition()); } return type; }
protected void Warning(AstNode where, string what) { System.Console.Error.Write(where.GetPosition().ToString() + ": warning: " + what + "\n"); }
protected void VisitList(AstNode list) { try { while(list != null) { list.Accept(this); list = list.GetNext(); } } catch(System.SystemException sysException) { System.Console.WriteLine("Compiler bug near {0}", list.GetPosition().ToString()); System.Console.WriteLine(sysException.ToString()); System.Console.WriteLine(sysException.StackTrace); System.Environment.Exit(-1); } }
protected void Error(AstNode where, string what) { throw new CompilerException(what, where.GetPosition()); }
private void CreateSimplifiedEventFunction(AstNode node, EventVariable eventVariable, FunctionType functionType, bool isAdd) { // Create the function name. string functionName = (isAdd ? "add_" : "remove_") + eventVariable.GetName(); // Create the function. Function function; if(functionType.GetArgumentCount() > 1) function = new Method(functionName, eventVariable.GetFlags(), currentContainer); else function = new Function(functionName, eventVariable.GetFlags(), currentContainer); // Set the function type. function.SetFunctionType(functionType); // Set the function position. function.Position = node.GetPosition(); // Store the function in the event. if(isAdd) eventVariable.AddModifier = function; else eventVariable.RemoveModifier = function; // Store the function in his container. if(currentContainer.IsStructure() || currentContainer.IsClass() || currentContainer.IsInterface()) { Structure building = (Structure)currentContainer; building.AddFunction(functionName, function); } else if(currentContainer.IsNamespace()) { Namespace space = (Namespace)currentContainer; space.AddMember(function); } else { Error(node, "an event cannot be declared here."); } }
private Function PickFunction(AstNode node, FunctionGroup fgroup, bool isStatic, FunctionGroupSelector selector, List<object> arguments, bool forgive) { // Count the number of arguments. int startIndex = isStatic ? 0 : 1; int numargs = startIndex + arguments.Count; // Store the generic arguments. IChelaType[] genericArguments = null; if(selector != null) genericArguments = selector.GenericParameters; // Select a function in the group. List<Function> bestMatches = new List<Function> (); int bestCoercions = -1; int numfunctions = fgroup.GetFunctionCount(); bool nonKernelContext = !currentContainer.IsKernel(); foreach(FunctionGroupName groupName in fgroup.GetFunctions()) { // Only use the same static-ness. if(groupName.IsStatic() != isStatic) continue; // Get the candidate prototype. Function function = groupName.GetFunction(); FunctionType prototype = groupName.GetFunctionType(); // Use the kernel entry point when it exists, and calling a kernel from a non-kernel context. if(nonKernelContext && function.IsKernel() && function.EntryPoint != null) { function = function.EntryPoint; prototype = function.GetFunctionType(); } // Check for generics. IChelaType[] genericArgumentsMatched = null; GenericPrototype genProto = null; if(function != null) { genProto = function.GetGenericPrototype(); if(genProto.GetPlaceHolderCount() > 0 && genericArguments != null) { // Check if the generic function is matched. if(!CheckGenericArguments(fgroup.GetFunctionCount() == 1 ? node : null, genProto, genericArguments)) continue; // Matched function, store the arguments and substitute in the prototype genericArgumentsMatched = genericArguments; function = function.InstanceGeneric(new GenericInstance(genProto, genericArguments), currentModule); prototype = function.GetFunctionType(); } else if(genProto.GetPlaceHolderCount() > 0) { // Try replacing arguments. genericArgumentsMatched = new IChelaType[genProto.GetPlaceHolderCount()]; } } // TODO: Add variable arguments. if(numargs != prototype.GetArgumentCount()) continue; // Check the arguments. int index = startIndex; bool match = true; int coercions = 0; for(int i = 0; i < arguments.Count; ++i) { // Get the argument type. object argObject = arguments[i]; object argValue = null; AstNode arg = null; IChelaType argExprType = null; if(argObject is IChelaType) { argExprType = (IChelaType)argObject; } else { arg = (AstNode)argObject; argExprType = arg.GetNodeType(); argValue = arg.GetNodeValue(); } // Get the argument type. IChelaType argType = prototype.GetArgument(index); // Check for reference value. Variable argValueVar = argValue as Variable; bool refValue = argValueVar != null && argValueVar.IsTemporalReferencedSlot(); // Reference argument requires exact match. bool cantMatch = false; bool refArg = false; if(argType.IsReference()) { IChelaType referencedArg = DeReferenceType(argType); // Check for reference argument. if(!referencedArg.IsPassedByReference() || referencedArg.IsReference()) { refArg = true; if(!argExprType.IsReference() || argValueVar == null || !refValue) { cantMatch = true; } else if(argType != argExprType) { // Extract the expression base type. IChelaType exprValueType = DeReferenceType(argExprType); exprValueType = DeConstType(exprValueType); // Check for some type equivalences. IChelaType argValueType = referencedArg; // Check for out-ref differences. if(exprValueType == argValueType) { // Out-ref difference, so don't match. cantMatch = true; } else { // Check primitive-associated pairs. if(!exprValueType.IsFirstClass() || argValueType != currentModule.GetAssociatedClass(exprValueType)) { if(!argValueType.IsFirstClass() || exprValueType != currentModule.GetAssociatedClass(argValueType)) cantMatch = true; } } } } else if(refValue) { // Ignore not references candidates when the argument is a reference. cantMatch = true; } } else if(refValue) { // Ignore not references candidates when the argument is a reference. cantMatch = true; } // Check coercion. if(argExprType != argType || cantMatch) { int argCoercions = 0; IChelaType coercedArgument = null; // Perform coercion. if(!cantMatch) { if(argType.IsGenericType() && !argType.IsGenericImplicit() && genericArguments == null) { // Perform generic coercion. coercedArgument = GenericCoercion(arg, argType, argExprType, genProto, genericArgumentsMatched, out argCoercions); } else { // Perform ordinary coercion. if(refArg) coercedArgument = RefCoerceCounted(arg, argType, argExprType, argValue, out argCoercions); else coercedArgument = CoerceCounted(arg, argType, argExprType, argValue, out argCoercions); } } // Check for coercion success. if(cantMatch || coercedArgument != argType) { // Print early error message. if(numfunctions == 1 && !forgive) Error(node, "cannot implicitly cast argument {0} from {1} to {2}.{3}", i+1, argExprType.GetDisplayName(), argType.GetDisplayName(), cantMatch ? " Must use ref/out operator." : null); match = false; break; } else coercions += argCoercions; } // Check the next argument. index++; } // Ignore not matching candidates. if(!match) continue; // Has at least one match. if(bestMatches.Count == 0) { bestMatches.Add(function); bestCoercions = coercions; continue; } // Prefer the candidates with less coercions. if(coercions < bestCoercions || bestCoercions < 0) { bestMatches.Clear(); bestMatches.Add(function); bestCoercions = coercions; } else if(coercions == bestCoercions) { bestMatches.Add(function); } } // Only one function can be the match. if(bestMatches.Count == 0 && !forgive) { string error = "cannot find a matching function for '" + fgroup.GetName() + "'"; if(fgroup.GetFunctionCount() > 1) error += "\ncandidates are:"; else error += " the option is:"; foreach(FunctionGroupName gname in fgroup.GetFunctions()) { Function function = gname.GetFunction(); FunctionType functionType = function.GetFunctionType(); if(nonKernelContext && function.IsKernel() && function.EntryPoint != null) functionType = function.EntryPoint.GetFunctionType(); error += "\n\t" + functionType.GetDisplayName(); } Error(node, error); } else if(bestMatches.Count > 1) { string error = "ambiguous matches for '" + fgroup.GetName() + "'\n" + "candidates are:"; foreach(Function candidate in bestMatches) { error += "\n\t" + candidate.GetFunctionType().GetName(); } Error(node, error); } // Get the selected function. Function matched = null; if(bestMatches.Count != 0) { matched = (Function)bestMatches[0]; // Prevent ambiguity. matched.CheckAmbiguity(node.GetPosition()); // Perform coercion again, required by delegates. FunctionType prototype = matched.GetFunctionType(); int index = startIndex; for(int i = 0; i < arguments.Count; ++i) { // Get the argument type. object argObject = arguments[i]; if(argObject is IChelaType) continue; // Read the argument data. AstNode arg = (AstNode)argObject; IChelaType argExprType = arg.GetNodeType(); object argValue = arg.GetNodeValue(); // Perform the coercion again. IChelaType argType = prototype.GetArgument(index); if(argExprType != argType) { int argCoercions = 0; CoerceCounted(arg, argType, argExprType, argValue, out argCoercions); } // Coerce the next argument. index++; } } // Return the matched function. return matched; }