public PropertyOperation(CompiledMethod method,CompiledFragment of,string name):base(method){ if(of!=null){ of.ParentFragment=this; } Of=(of!=null)?of:new ThisOperation(method); Name=name; }
public override CompiledFragment Compile(CompiledMethod method) { if (FirstChild == null) { return(null); } // Apply the current line: method.CurrentLine = LineNumber; try{ // Compile operator chains: (d=a+b+c;) CompilationServices.CompileOperators(this, method); // Compile the now singular operator: CompiledFragment cFrag = FirstChild.Compile(method) as CompiledFragment; return(cFrag); }catch (CompilationException e) { if (e.LineNumber == -1) { // Setup line number: e.LineNumber = LineNumber; } // Rethrow: throw e; } }
/// <summary>Compiles a set of parameters into an array of compiled fragments.</summary> /// <param name="brackets">The parent block which contains each parameter as a child.</param> /// <param name="parentBlock">The method the parameters are for.</param> /// <returns>A set of compiled fragments.</returns> public static CompiledFragment[] CompileParameters(CodeFragment brackets, CompiledMethod parentBlock) { if (!brackets.IsParent) { return(null); } int count = 0; brackets.Compile(parentBlock); CodeFragment child = brackets.FirstChild; CompiledFragment[] output = new CompiledFragment[brackets.ChildCount()]; while (child != null) { CompiledFragment frag = (CompiledFragment)child; if (frag == null) { return(null); } output[count] = frag; count++; child = child.NextChild; } return(output); }
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ CompiledFragment frag=left; if(left==null){ frag=right; } return new SetOperation(method,frag,new AddOperation(method,frag,new CompiledFragment(1))); }
public SwitchOperation(CompiledMethod method,BracketFragment switching,BracketFragment body):base(method){ Body=body; if(switching.ChildCount()!=1){ switching.Error("Too many entries inside this switches brackets. Should be e.g. switch(name){ .. }"); } // Compile the switching frag: CompiledFragment variableFrag=switching.FirstChild.Compile(method); // Get the active value - this should be a variable object: object activeValue=variableFrag.ActiveValue(); // Try and apply it: Switching=activeValue as Variable; if(Switching==null){ switching.Error("Can only switch variables."); } }
/// <summary>Adds a method that was found into this classes set of methods to compile.</summary> /// <param name="fragment">The first fragment of the method, used for generating errors. This gives a valid line number.</param> /// <param name="body">The block of code for this method.</param> /// <param name="name">The name of the method. Null if anonymous is true.</param> /// <param name="anonymous">True if this method is an anonymous one and requires a name.</param> /// <param name="parameters">The set of parameters for this method.</param> /// <param name="returnType">The type that this method returns.</param> /// <param name="isPublic">True if this is a public method; false for private.</param> /// <returns>The first fragment following the method, if there is one.</returns> protected virtual CodeFragment AddFoundMethod(CodeFragment fragment, CodeFragment body, string name, bool anonymous, BracketFragment parameters, TypeFragment returnType, bool isPublic) { if (body == null) { fragment.Error("Invalid function definition (" + name + "). The content block {} is missing or isnt valid."); } if (anonymous) { name = "Compiler-Generated-$" + AnonymousCount; AnonymousCount++; } // The following is the explicit code block for this function: BracketFragment codeBlock = (BracketFragment)body; CompiledMethod cMethod = new CompiledMethod(this, name, parameters, codeBlock, returnType, isPublic); MethodOverloads set = MakeOrFind(name, cMethod.Builder.ReturnType); CodeFragment next = body.NextChild; if (anonymous) { CodeFragment newChild = DynamicMethodCompiler.Compile(cMethod, name, set.ReturnType, new ThisOperation(cMethod)); newChild.AddAfter(body); } body.Remove(); set.AddMethod(cMethod); FindMethods(codeBlock); return(next); }
public override CompiledFragment Compile(CompiledMethod parent) { if (Float) { return(new CompiledFragment(float.Parse(Value))); } return(new CompiledFragment(int.Parse(Value))); }
public override CompiledFragment Compile(CompiledMethod method){ CompiledFragment cfrag=MethodName.Compile(method); if(!Types.IsTypeOf(cfrag.ActiveValue(),typeof(ISettable))){ Error("Unable to compile a method call - didn't recognise an invokable object."); } CompiledFragment[] parameters=CompilationServices.CompileParameters(Brackets,method); return new MethodOperation(method,cfrag,parameters); }
/// <summary>Outputs the given argument set into the given IL stream.</summary> /// <param name="args">The compiled set of arguments to be outputted.</param> /// <param name="method">The method that they are being used in.</param> /// <param name="into">The IL stream to output the arguments into.</param> /// <param name="parameters">The parameter info used to correctly match the location of the parameters.</param> public static void OutputParameters(CompiledFragment[] args, CompiledMethod method, NitroIL into, ParameterInfo[] parameters) { int argID = 0; int argCount = 0; if (args != null) { argCount = args.Length; } for (int paramID = 0; paramID < parameters.Length; paramID++) { ParameterInfo param = parameters[paramID]; Type paramType = param.ParameterType; if (IsParams(param)) { // The rest are going into an array Operation. // Get the type we want to cast them all to (because paramType at this stage must be an array): paramType = paramType.GetElementType(); CompiledFragment[] ops = new CompiledFragment[argCount - argID]; int Index = 0; for (int i = argID; i < argCount; i++) { CompiledFragment frag = args[i]; Type fragType = frag.OutputType(out frag); if (fragType != paramType) { frag = TryCast(method, frag, paramType); if (frag == null) { args[i].Error("Unable to box or cast " + fragType + " to " + paramType + " at parameter " + argID + ". Note that you can't null a value type."); } } ops[Index++] = frag; } CompiledFragment arrayOp = new ArrayOperation(method, paramType, ops); arrayOp.OutputType(out arrayOp); arrayOp.OutputIL(into); return; } CompiledFragment argFrag = args[argID++]; Type argType = argFrag.OutputType(out argFrag); if (argType != paramType) { CompiledFragment originalFragment = argFrag; argFrag = TryCast(method, argFrag, paramType); if (argFrag == null) { originalFragment.Error("Unable to box or cast " + argType + " to " + paramType + " at parameter " + argID + " of method call " + param.Member.Name + ". Note that you can't null a value type."); } } argFrag.OutputIL(into); } }
public IndexOperation(CompiledMethod method,CompiledFragment appliedTo,CompiledFragment[] indices):base(method){ AppliedTo=appliedTo; if(indices.Length==0){ Error("No index value given. must be e.g. array[1]."); }else if(indices.Length>1){ Error("Multidimension arrays are not currently supported."); } Index=indices[0]; }
public PropertyOperation(CompiledMethod method, CompiledFragment of, string name) : base(method) { if (of != null) { of.ParentFragment = this; } Of = (of != null)?of:new ThisOperation(method); Name = name; }
/// <summary>Makes sure that two overloads don't have the same parameter set. Throws an error if </summary> /// <param name="method">The method to check for matches against existing methods in this set.</param> public void ParametersOk(CompiledMethod method){ foreach(CompiledMethod Method in Methods){ if(Method==method||!Method.ParametersLoaded){ continue; } if(Types.TypeSetsMatchExactly(method.ParameterTypes,Method.ParameterTypes)){ method.Error("Unable to add method "+method.Name+" - two overloads exist with the same parameters."); } } }
public IfOperation(CompiledMethod method,BracketFragment condition,BracketFragment ifTrue,BracketFragment ifFalse):base(method){ IfTrue=ifTrue; IfFalse=ifFalse; Conditions=CompilationServices.CompileParameters(condition,method); if(Conditions==null||Conditions.Length==0){ Error("An if was defined but with nothing to check (e.g. if(this is empty!){..} )"); } }
public override CompiledFragment Compile(CompiledMethod method) { CompiledFragment cfrag = MethodName.Compile(method); if (!Types.IsTypeOf(cfrag.ActiveValue(), typeof(ISettable))) { Error("Unable to compile a method call - didn't recognise an invokable object."); } CompiledFragment[] parameters = CompilationServices.CompileParameters(Brackets, method); return(new MethodOperation(method, cfrag, parameters)); }
/// <summary>Gets the ToString method of the given type, being called on the given fragment.</summary> /// <param name="method">The function this operation is occuring in.</param> /// <param name="frag">The object that the ToString method is being called on.</param> /// <param name="type">The type that fragment contains and the one that the ToString operation must be found on.</param> /// <returns>A methodOperation representing the ToString call. Throws an error if frag is null.</returns> public static MethodOperation ToStringMethod(CompiledMethod method, CompiledFragment frag, Type type) { if (type == null) { frag.Error("Unable to convert null to a string."); } MethodOperation mo = new MethodOperation(method, type.GetMethod("ToString", new Type[0])); mo.CalledOn = frag; frag.ParentFragment = mo; return(mo); }
public IfOperation(CompiledMethod method, BracketFragment condition, BracketFragment ifTrue, BracketFragment ifFalse) : base(method) { IfTrue = ifTrue; IfFalse = ifFalse; Conditions = CompilationServices.CompileParameters(condition, method); if (Conditions == null || Conditions.Length == 0) { Error("An if was defined but with nothing to check (e.g. if(this is empty!){..} )"); } }
public ConstructOperation(TypeFragment type,BracketFragment brackets,CompiledMethod method):base(method){ if(type==null){ Error("A constructor is missing the type to construct. E.g. new myClass();"); } ObjectType=type.FindType(method.Script); if(ObjectType==null){ Error("Couldn't find type '"+type+"'."); } // Compile the brackets - what types to they have? Parameters=CompilationServices.CompileParameters(brackets,method); SetConstructor(); }
public IndexOperation(CompiledMethod method, CompiledFragment appliedTo, CompiledFragment[] indices) : base(method) { AppliedTo = appliedTo; if (indices.Length == 0) { Error("No index value given. must be e.g. array[1]."); } else if (indices.Length > 1) { Error("Multidimension arrays are not currently supported."); } Index = indices[0]; }
/// <summary>Gets the OnScriptReady method. May create it if it's not available.</summary> /// <returns>The start method. All code outside of functions that isn't a variable goes into this.</returns> private CompiledMethod GetStartMethod() { MethodOverloads set = MakeOrFind("OnScriptReady", null); if (set.Methods.Count == 0) { set.AddMethod(new CompiledMethod(this, "OnScriptReady", null, new BracketFragment(), null, true)); } CompiledMethod method = set.Methods[0]; method.GloballyScoped = true; return(method); }
/// <summary>Makes sure that two overloads don't have the same parameter set. Throws an error if </summary> /// <param name="method">The method to check for matches against existing methods in this set.</param> public void ParametersOk(CompiledMethod method) { foreach (CompiledMethod Method in Methods) { if (Method == method || !Method.ParametersLoaded) { continue; } if (Types.TypeSetsMatchExactly(method.ParameterTypes, Method.ParameterTypes)) { method.Error("Unable to add method " + method.Name + " - two overloads exist with the same parameters."); } } }
public ConstructOperation(TypeFragment type, BracketFragment brackets, CompiledMethod method) : base(method) { if (type == null) { Error("A constructor is missing the type to construct. E.g. new myClass();"); } ObjectType = type.FindType(method.Script); if (ObjectType == null) { Error("Couldn't find type '" + type + "'."); } // Compile the brackets - what types to they have? Parameters = CompilationServices.CompileParameters(brackets, method); SetConstructor(); }
/// <summary>Converts the the given fragments into a compiled operation by first checking the fragments are ok for this operator.</summary> /// <param name="left">The fragment to the left of the operator.</param> /// <param name="right">The fragment to the right of the operation.</param> /// <param name="method">The method the operation will be compiled into.</param> public Operation ToOperation(CompiledFragment left,CompiledFragment right,CompiledMethod method){ bool leftNull=(left==null); bool rightNull=(right==null); if(leftNull&&rightNull){ return null; } if(leftNull&&!rightNull&&!RightOnly){ return null; } if(!leftNull&&rightNull&&!LeftOnly){ return null; } if(!leftNull&&!rightNull&&!LeftAndRight){ return null; } return Compile(left,right,method); }
/// <summary>Attempts to generate a cast operation for the given fragment to the given type.</summary> /// <param name="method">The method this operation is occuring in.</param> /// <param name="frag">The fragment containing the object to cast.</param> /// <param name="to">The type to cast it to if possible.</param> /// <param name="isExplicit">True if the casting is explicit. False if it is implicit.</param> /// <returns>A cast operation if it is possible; throws an error otherwise.</returns> public static CompiledFragment TryCast(CompiledMethod method, CompiledFragment frag, Type to, out bool isExplicit) { isExplicit = false; Type from = frag.OutputType(out frag); if (from == null) { if (to.IsValueType) { return(null); } else { return(frag); } } if (to == typeof(object) && from.IsValueType) { return(new BoxOperation(method, frag)); } if (from == to || to.IsAssignableFrom(from)) { return(frag); } // IsAssignableFrom is true if TO inherits FROM: if (from.IsAssignableFrom(to)) { return(new CastOperation(method, frag, to)); } MethodInfo cast = IsCastableTo(from, to, out isExplicit); if (cast == null) { return(null); } else { return(new MethodOperation(method, cast, frag)); } }
public override CompiledFragment Compile(CompiledMethod method) { if (!IsParent) { return(null); } CodeFragment child = FirstChild; while (child != null) { CodeFragment next = child.NextChild; CompiledFragment cfrag = child.Compile(method); if (cfrag != null) { cfrag.AddAfter(child); } child.Remove(); child = next; } if (GivenType != null) { Type toType = GivenType.FindType(method.Script); if (toType == null) { Error("Type not found: " + GivenType.ToString() + "."); } CompiledFragment compiledKid = (CompiledFragment)FirstChild; CompiledFragment result = Types.TryCast(method, compiledKid, toType); if (result == null) { Error("Cannot cast " + compiledKid.OutputType() + " to " + toType + "."); } return(result); } return((CompiledFragment)FirstChild); }
public override CompiledFragment Compile(CompiledMethod method) { if (!IsParent) { return(null); } CodeFragment child = FirstChild; while (child != null) { CodeFragment next = child.NextChild; CompiledFragment cfrag = child.Compile(method); if (cfrag != null) { cfrag.AddAfter(child); } child.Remove(); child = next; } // Is this a cast? if (GivenType != null) { // Get the type being cast to: Type toType = GivenType.FindType(method.Script); if (toType == null) { Error("Type to cast to was not found: " + GivenType.ToString() + "."); } // Get the object being cast: CompiledFragment compiledKid = (CompiledFragment)FirstChild; // Create a cast operation with it: return(new CastOperation(method, compiledKid, toType)); } return((CompiledFragment)FirstChild); }
/// <summary>Converts the the given fragments into a compiled operation by first checking the fragments are ok for this operator.</summary> /// <param name="left">The fragment to the left of the operator.</param> /// <param name="right">The fragment to the right of the operation.</param> /// <param name="method">The method the operation will be compiled into.</param> public Operation ToOperation(CompiledFragment left, CompiledFragment right, CompiledMethod method) { bool leftNull = (left == null); bool rightNull = (right == null); if (leftNull && rightNull) { return(null); } if (leftNull && !rightNull && !RightOnly) { return(null); } if (!leftNull && rightNull && !LeftOnly) { return(null); } if (!leftNull && !rightNull && !LeftAndRight) { return(null); } return(Compile(left, right, method)); }
public SwitchOperation(CompiledMethod method, BracketFragment switching, BracketFragment body) : base(method) { Body = body; if (switching.ChildCount() != 1) { switching.Error("Too many entries inside this switches brackets. Should be e.g. switch(name){ .. }"); } // Compile the switching frag: CompiledFragment variableFrag = switching.FirstChild.Compile(method); // Get the active value - this should be a variable object: object activeValue = variableFrag.ActiveValue(); // Try and apply it: Switching = activeValue as Variable; if (Switching == null) { switching.Error("Can only switch variables."); } }
public override CompiledFragment Compile(CompiledMethod parent) { return(new ArrayOperation(parent, ArrayType.FindType(parent.Script), null, CompilationServices.CompileParameters(Defaults, parent))); }
/// <summary>Adds a method that was found into this classes set of methods to compile.</summary> /// <param name="fragment">The first fragment of the method, used for generating errors. This gives a valid line number.</param> /// <param name="body">The block of code for this method.</param> /// <param name="name">The name of the method. Null if anonymous is true.</param> /// <param name="anonymous">True if this method is an anonymous one and requires a name.</param> /// <param name="parameters">The set of parameters for this method.</param> /// <param name="returnType">The type that this method returns.</param> /// <param name="isPublic">True if this is a public method; false for private.</param> /// <returns>The first fragment following the method, if there is one.</returns> protected virtual CodeFragment AddFoundMethod(CodeFragment fragment,CodeFragment body,string name,bool anonymous,BracketFragment parameters,TypeFragment returnType,bool isPublic){ if(body==null){ fragment.Error("Invalid function definition ("+name+"). The content block {} is missing or isnt valid."); } if(anonymous){ name="Compiler-Generated-$"+AnonymousCount; AnonymousCount++; } // The following is the explicit code block for this function: BracketFragment codeBlock=(BracketFragment)body; CompiledMethod cMethod=new CompiledMethod(this,name,parameters,codeBlock,returnType,isPublic); MethodOverloads set=MakeOrFind(name,cMethod.Builder.ReturnType); CodeFragment next=body.NextChild; if(anonymous){ CodeFragment newChild=DynamicMethodCompiler.Compile(cMethod,name,set.ReturnType,new ThisOperation(cMethod)); newChild.AddAfter(body); } body.Remove(); set.AddMethod(cMethod); FindMethods(codeBlock); return next; }
public override CompiledFragment Compile(CompiledMethod parent) { return(new CompiledFragment(Value)); }
public SetOperation(CompiledMethod method,CompiledFragment input0,CompiledFragment input1):base(method){ Input0=input0; Input1=input1; }
public ArrayOperation(CompiledMethod method,Type elementType,CompiledFragment[] defaultValues):base(method){ SetDefaults(defaultValues); ArrayType=elementType.MakeArrayType(); }
public SubtractOperation(CompiledMethod method, CompiledFragment input0, CompiledFragment input1) : base(method) { Input0 = input0; Input1 = input1; }
public ArrayOperation(CompiledMethod method,Type arrayType,CompiledFragment size,CompiledFragment[] defaultValues):base(method){ Size=size; SetDefaults(defaultValues); ArrayType=arrayType; }
/// <summary>Attempts to generate a cast operation for the given fragment to the given type.</summary> /// <param name="method">The method this operation is occuring in.</param> /// <param name="frag">The fragment containing the object to cast.</param> /// <param name="to">The type to cast it to if possible.</param> /// <param name="isExplicit">True if the casting is explicit. False if it is implicit.</param> /// <returns>A cast operation if it is possible; throws an error otherwise.</returns> public static CompiledFragment TryCast(CompiledMethod method,CompiledFragment frag,Type to,out bool isExplicit){ isExplicit=false; Type from=frag.OutputType(out frag); if(from==null){ if(to.IsValueType){ return null; }else{ return frag; } } if(to==typeof(object) && from.IsValueType){ return new BoxOperation(method,frag); } if(from==to||to.IsAssignableFrom(from)){ return frag; } // IsAssignableFrom is true if TO inherits FROM: if(from.IsAssignableFrom(to)){ return new CastOperation(method,frag,to); } MethodInfo cast=IsCastableTo(from,to,out isExplicit); if(cast==null){ return null; }else{ return new MethodOperation(method,cast,frag); } }
public override CompiledFragment Compile(CompiledMethod method){ return new IfOperation(method,Condition,IfTrue,IfFalse); }
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ return new SetOperation(method,left,new SubtractOperation(method,left,right)); }
/// <summary>Compiles a dynamic method call in code into an actual dynamic method call.</summary> /// <param name="function">The function this call is being compiled within.</param> /// <param name="methodName">The name of the method to call.</param> /// <param name="methodReturnType">The return type of the method that will be called.</param> /// <param name="target">The object that the method will be run on.</param> /// <returns>A compiled dynamic method object.</returns> public static CompiledFragment Compile(CompiledMethod function, string methodName, Type methodReturnType, CompiledFragment target) { return(new ConstructOperation(function, TypeFor(methodReturnType), new CompiledFragment(methodName), target)); }
protected override Operation Compile(CompiledFragment left, CompiledFragment right, CompiledMethod method) { CompiledFragment frag = left; if (left == null) { frag = right; } return(new SetOperation(method, frag, new AddOperation(method, frag, new CompiledFragment(1)))); }
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ return new BitwiseXOrOperation(method,left,right); }
public ThisOperation(CompiledMethod method) : base(method) { }
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ return new EqualsOperation(method,new CompiledFragment(0),right); }
/// <summary>Adds a method to this overload set.</summary> /// <param name="method">The method to add.</param> public void AddMethod(CompiledMethod method){ Methods.Add(method); }
protected override Operation Compile(CompiledFragment left, CompiledFragment right, CompiledMethod method) { return(new GreaterThanOrEqualOperation(method, left, right)); }
public TypeofOperation(CompiledMethod method):base(method){}
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ return new GreaterThanOrEqualOperation(method,left,right); }
/// <summary>Attempts to generate a cast operation for the given fragment to the given type.</summary> /// <param name="method">The method this operation is occuring in.</param> /// <param name="frag">The fragment containing the object to cast.</param> /// <param name="to">The type to cast it to if possible.</param> /// <returns>A cast operation if it is possible; throws an error otherwise.</returns> public static CompiledFragment TryCast(CompiledMethod method, CompiledFragment frag, Type to) { bool isExplicit; return(TryCast(method, frag, to, out isExplicit)); }
public override CompiledFragment Compile(CompiledMethod parent){ return new ArrayOperation(parent,ArrayType.FindType(parent.Script),null,CompilationServices.CompileParameters(Defaults,parent)); }
public GreaterThanOperation(CompiledMethod method, CompiledFragment input0, CompiledFragment input1) : base(method) { Input0 = input0; Input1 = input1; }
public override CompiledFragment Compile(CompiledMethod parentBlock){ return new IndexOperation(parentBlock,Variable.Compile(parentBlock),CompilationServices.CompileParameters(Brackets,parentBlock)); }
protected override Operation Compile(CompiledFragment left, CompiledFragment right, CompiledMethod method) { return(new SetOperation(method, left, new DivideOperation(method, left, right))); }
public override CompiledFragment Compile(CompiledMethod method){ if(!IsParent){ return null; } CodeFragment child=FirstChild; while(child!=null){ CodeFragment next=child.NextChild; CompiledFragment cfrag=child.Compile(method); if(cfrag!=null){ cfrag.AddAfter(child); } child.Remove(); child=next; } if(GivenType!=null){ Type toType=GivenType.FindType(method.Script); if(toType==null){ Error("Type not found: "+GivenType.ToString()+"."); } CompiledFragment compiledKid=(CompiledFragment)FirstChild; CompiledFragment result=Types.TryCast(method,compiledKid,toType); if(result==null){ Error("Cannot cast "+compiledKid.OutputType()+" to "+toType+"."); } return result; } return (CompiledFragment)FirstChild; }
public override CompiledFragment Compile(CompiledMethod method){ return new ForOperation(method,Parameters,Body); }
/// <summary>Attempts to compile this bracket to IL, assuming it is the body of a method.</summary> /// <param name="method">The method that is being compiled.</param> /// <returns>True if the method returns something.</returns> public bool CompileBody(CompiledMethod method){ Compile(method); return CompilationServices.CompileOperations(this,method); }
protected override Operation Compile(CompiledFragment left, CompiledFragment right, CompiledMethod method) { return(new MultiplyOperation(method, left, right)); }
/// <summary>Outputs the given argument set into the given IL stream.</summary> /// <param name="args">The compiled set of arguments to be outputted.</param> /// <param name="method">The method that they are being used in.</param> /// <param name="into">The IL stream to output the arguments into.</param> /// <param name="parameters">The parameter info used to correctly match the location of the parameters.</param> public static void OutputParameters(CompiledFragment[] args,CompiledMethod method,NitroIL into,ParameterInfo[] parameters){ int argID=0; int argCount=0; if(args!=null){ argCount=args.Length; } for(int paramID=0;paramID<parameters.Length;paramID++){ ParameterInfo param=parameters[paramID]; Type paramType=param.ParameterType; if(IsParams(param)){ // The rest are going into an array Operation. // Get the type we want to cast them all to (because paramType at this stage must be an array): paramType=paramType.GetElementType(); CompiledFragment[] ops=new CompiledFragment[argCount-argID]; int Index=0; for(int i=argID;i<argCount;i++){ CompiledFragment frag=args[i]; Type fragType=frag.OutputType(out frag); if(fragType!=paramType){ frag=TryCast(method,frag,paramType); if(frag==null){ args[i].Error("Unable to box or cast "+fragType+" to "+paramType+" at parameter "+argID+". Note that you can't null a value type."); } } ops[Index++]=frag; } CompiledFragment arrayOp=new ArrayOperation(method,paramType,ops); arrayOp.OutputType(out arrayOp); arrayOp.OutputIL(into); return; } CompiledFragment argFrag=args[argID++]; Type argType=argFrag.OutputType(out argFrag); if(argType!=paramType){ CompiledFragment originalFragment=argFrag; argFrag=TryCast(method,argFrag,paramType); if(argFrag==null){ originalFragment.Error("Unable to box or cast "+argType+" to "+paramType+" at parameter "+argID+" of method call "+param.Member.Name+". Note that you can't null a value type."); } } argFrag.OutputIL(into); } }
protected override Operation Compile(CompiledFragment left,CompiledFragment right,CompiledMethod method){ return new MultiplyOperation(method,left,right); }
/// <summary>Gets the ToString method of the given type, being called on the given fragment.</summary> /// <param name="method">The function this operation is occuring in.</param> /// <param name="frag">The object that the ToString method is being called on.</param> /// <param name="type">The type that fragment contains and the one that the ToString operation must be found on.</param> /// <returns>A methodOperation representing the ToString call. Throws an error if frag is null.</returns> public static MethodOperation ToStringMethod(CompiledMethod method,CompiledFragment frag,Type type){ if(type==null){ frag.Error("Unable to convert null to a string."); } MethodOperation mo=new MethodOperation(method,type.GetMethod("ToString",new Type[0])); mo.CalledOn=frag; frag.ParentFragment=mo; return mo; }
public override CompiledFragment Compile(CompiledMethod parent) { return(new ConstructOperation(NewType, Brackets, parent)); }
/// <summary>Attempts to generate a cast operation for the given fragment to the given type.</summary> /// <param name="method">The method this operation is occuring in.</param> /// <param name="frag">The fragment containing the object to cast.</param> /// <param name="to">The type to cast it to if possible.</param> /// <returns>A cast operation if it is possible; throws an error otherwise.</returns> public static CompiledFragment TryCast(CompiledMethod method,CompiledFragment frag,Type to){ bool isExplicit; return TryCast(method,frag,to,out isExplicit); }