public override void OutputIL(NitroIL into) { // Ensure our conditions output type is computed: OutputType(); Label End = into.DefineLabel(); Label Else = into.DefineLabel(); Conditions[0].OutputIL(into); into.Emit(OpCodes.Brfalse, Else); AllRoutesReturn = IfTrue.CompileBody(Method); into.Emit(OpCodes.Br, End); into.MarkLabel(Else); if (IfFalse != null) { bool returns = IfFalse.CompileBody(Method); AllRoutesReturn = (AllRoutesReturn && returns); } else { AllRoutesReturn = false; } into.MarkLabel(End); }
public override void OutputIL(NitroIL into){ // Emit any set operations before the block itself (e.g. i=0): for(int i=0;i<Parameters.Length;i++){ CompiledFragment parameter=Parameters[i]; if(Types.IsTypeOf(parameter,typeof(SetOperation))){ // Make sure it isn't a self set - e.g. i++, i=i+10. SetOperation set=(SetOperation)parameter; if(!set.SelfReferencing()){ set.OutputIL(into); Parameters[i]=null; }else{ set.Output=false; } }else{ // Compute it's output type: // Note that this must NOT be done for the SET ops as it makes them think // We want to use their output, which isn't true! parameter.OutputType(out parameter); Parameters[i]=parameter; } } Label continuePoint=into.DefineLabel(); Label start=into.DefineLabel(); Label end=into.DefineLabel(); Method.AddBreakPoint(new BreakPoint(continuePoint,end)); into.MarkLabel(start); // Logical operations (e.g. i<10): for(int i=0;i<Parameters.Length;i++){ CompiledFragment parameter=Parameters[i]; if(parameter==null){ continue; } if(Types.IsTypeOf(parameter,typeof(SetOperation))){ // Just checking for a logical operation will make an incremental (i++) operation think // It's being daisy chained. That's because its output type is checked for boolean in IsLogical. continue; } if(parameter.IsLogical()){ parameter.OutputIL(into); into.Emit(OpCodes.Brfalse,end); Parameters[i]=null; } } Body.CompileBody(Method); into.MarkLabel(continuePoint); // Increment/decrement ops (e.g. i++): for(int i=0;i<Parameters.Length;i++){ CompiledFragment cfrag=Parameters[i]; if(cfrag==null){ continue; } cfrag.OutputIL(into); } into.Emit(OpCodes.Br,start); into.MarkLabel(end); Method.PopBreakPoint(); }
public override void OutputIL(NitroIL into){ // Ensure our conditions output type is computed: OutputType(); Label End=into.DefineLabel(); Label Else=into.DefineLabel(); Conditions[0].OutputIL(into); into.Emit(OpCodes.Brfalse,Else); AllRoutesReturn=IfTrue.CompileBody(Method); into.Emit(OpCodes.Br,End); into.MarkLabel(Else); if(IfFalse!=null){ bool returns=IfFalse.CompileBody(Method); AllRoutesReturn=(AllRoutesReturn&&returns); }else{ AllRoutesReturn=false; } into.MarkLabel(End); }
public CompiledMethod(CompiledClass parent, string name, BracketFragment parameterBlock, BracketFragment codeBlock, TypeFragment retType, bool isPublic) { Name = name; Parent = parent; CodeBlock = codeBlock; Script = Parent.Script; ParameterBlock = parameterBlock; Type returnType = null; if (retType != null) { returnType = retType.FindType(Script); if (returnType == null) { Error("Type '" + retType.Value + "' was not found."); } } string methodName = Name; MethodAttributes attrib = isPublic?MethodAttributes.Public:MethodAttributes.Private; if (methodName == "new") { methodName = ".ctor"; attrib |= MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; } // Does the parent base type define this method? // If so, use it's name. Type baseType = Parent.Builder.BaseType; // Parse the parameter set right away: ParseParameters(); MethodInfo mInfo = Types.GetOverload(baseType.GetMethods(), Name, ParameterTypes, true); if (mInfo != null) { methodName = mInfo.Name; attrib |= MethodAttributes.Virtual | MethodAttributes.HideBySig; //|MethodAttributes.NewSlot; } bool isVoid = Types.IsVoid(returnType); if (isVoid) { returnType = typeof(void); } Builder = Parent.Builder.DefineMethod( methodName, attrib, returnType, null ); ApplyParameters(); ILStream = new NitroIL(Builder.GetILGenerator()); EndOfMethod = ILStream.DefineLabel(); if (!isVoid) { ReturnBay = ILStream.DeclareLocal(returnType); } }
public override void OutputIL(NitroIL into) { // Emit any set operations before the block itself (e.g. i=0): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment parameter = Parameters[i]; if (Types.IsTypeOf(parameter, typeof(SetOperation))) { // Make sure it isn't a self set - e.g. i++, i=i+10. SetOperation set = (SetOperation)parameter; if (!set.SelfReferencing()) { set.OutputIL(into); Parameters[i] = null; } else { set.Output = false; } } else { // Compute it's output type: // Note that this must NOT be done for the SET ops as it makes them think // We want to use their output, which isn't true! parameter.OutputType(out parameter); Parameters[i] = parameter; } } Label continuePoint = into.DefineLabel(); Label start = into.DefineLabel(); Label end = into.DefineLabel(); Method.AddBreakPoint(new BreakPoint(continuePoint, end)); into.MarkLabel(start); // Logical operations (e.g. i<10): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment parameter = Parameters[i]; if (parameter == null) { continue; } if (Types.IsTypeOf(parameter, typeof(SetOperation))) { // Just checking for a logical operation will make an incremental (i++) operation think // It's being daisy chained. That's because its output type is checked for boolean in IsLogical. continue; } if (parameter.IsLogical()) { parameter.OutputIL(into); into.Emit(OpCodes.Brfalse, end); Parameters[i] = null; } } Body.CompileBody(Method); into.MarkLabel(continuePoint); // Increment/decrement ops (e.g. i++): for (int i = 0; i < Parameters.Length; i++) { CompiledFragment cfrag = Parameters[i]; if (cfrag == null) { continue; } cfrag.OutputIL(into); } into.Emit(OpCodes.Br, start); into.MarkLabel(end); Method.PopBreakPoint(); }
public CompiledMethod(CompiledClass parent,string name,BracketFragment parameterBlock,BracketFragment codeBlock,TypeFragment retType,bool isPublic){ Name=name; Parent=parent; CodeBlock=codeBlock; Script=Parent.Script; ParameterBlock=parameterBlock; Type returnType=null; if(retType!=null){ returnType=retType.FindType(Script); if(returnType==null){ Error("Type '"+retType.Value+"' was not found."); } } string methodName=Name; MethodAttributes attrib=isPublic?MethodAttributes.Public:MethodAttributes.Private; if(methodName=="new"){ methodName=".ctor"; attrib|=MethodAttributes.HideBySig|MethodAttributes.SpecialName|MethodAttributes.RTSpecialName; } // Does the parent base type define this method? // If so, use it's name. Type baseType=Parent.Builder.BaseType; // Parse the parameter set right away: ParseParameters(); MethodInfo mInfo=Types.GetOverload(baseType.GetMethods(),Name,ParameterTypes,true); if(mInfo!=null){ methodName=mInfo.Name; attrib|=MethodAttributes.Virtual|MethodAttributes.HideBySig;//|MethodAttributes.NewSlot; } bool isVoid=Types.IsVoid(returnType); if(isVoid){ returnType=typeof(void); } Builder=Parent.Builder.DefineMethod( methodName, attrib, returnType, null ); ApplyParameters(); ILStream=new NitroIL(Builder.GetILGenerator()); EndOfMethod=ILStream.DefineLabel(); if(!isVoid){ ReturnBay=ILStream.DeclareLocal(returnType); } }