internal Tree.FuncNode GetFunctionNumber(int funcNumToMutate, ref int currentFuncNum) { if (this is Tree.FuncNode) { FuncNode thisFunc = this as FuncNode; if (currentFuncNum == funcNumToMutate) { return(thisFunc); } currentFuncNum++; foreach (Node n in thisFunc.Children) { Tree.FuncNode posNode = n.GetFunctionNumber(funcNumToMutate, ref currentFuncNum); if (posNode != null) { return(posNode); } } } return(null); }
private void GenerateStatement(Tree.Node node) { if (node is Tree.ValueNode) { Tree.ValueNode valueNode = node as Tree.ValueNode; if (valueNode.Value == 0) { il.Emit(OpCodes.Ldc_I4_0); } else if (valueNode.Value == 1) { il.Emit(OpCodes.Ldc_I4_1); } else if (valueNode.Value == 2) { il.Emit(OpCodes.Ldc_I4_2); } else if (valueNode.Value == 3) { il.Emit(OpCodes.Ldc_I4_3); } else if (valueNode.Value == 4) { il.Emit(OpCodes.Ldc_I4_4); } else { il.Emit(OpCodes.Ldc_I4, valueNode.Value); } } else if (node is Tree.VariableNode) { Tree.VariableNode variableNode = node as Tree.VariableNode; if (m_ArgTable[variableNode.Variable.Name] == 0) { il.Emit(OpCodes.Ldarg_0); } else if (m_ArgTable[variableNode.Variable.Name] == 1) { il.Emit(OpCodes.Ldarg_1); } else if (m_ArgTable[variableNode.Variable.Name] == 2) { il.Emit(OpCodes.Ldarg_2); } else if (m_ArgTable[variableNode.Variable.Name] == 3) { il.Emit(OpCodes.Ldarg_3); } else if (m_ArgTable[variableNode.Variable.Name] == 4) { il.Emit(OpCodes.Ldc_I4_4); il.Emit(OpCodes.Ldarg_S); } else { throw new ApplicationException("Unknown argument"); } } else if (node is Tree.FuncNode) { Tree.FuncNode funcNode = node as Tree.FuncNode; Tree.Func func = funcNode.Function; // For these simple maths functions, first emit the arguments if (func is Tree.FuncAdd || func is Tree.FuncSubtract || func is Tree.FuncMultiply || func is Tree.FuncModulo) { GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); } if (func is Tree.FuncAdd) { il.Emit(OpCodes.Add); } else if (func is Tree.FuncMultiply) { il.Emit(OpCodes.Mul); } else if (func is Tree.FuncSubtract) { il.Emit(OpCodes.Sub); } else if (func is Tree.FuncModulo) { il.Emit(OpCodes.Rem); } else if (func is Tree.FuncIf) { Tree.FuncIf funcIf = func as Tree.FuncIf; // Output the first two statements - which we will be comparing GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); Label equalLabel = il.DefineLabel(); Label afterLabel = il.DefineLabel(); OpCode conditionOpcode = OpCodes.Beq_S; if (funcIf.Comparator == Tree.Comparator.Equal) { conditionOpcode = OpCodes.Beq_S; } else if (funcIf.Comparator == Tree.Comparator.GreaterThanOrEqual) { conditionOpcode = OpCodes.Bge_S; } else if (funcIf.Comparator == Tree.Comparator.GreaterThan) { conditionOpcode = OpCodes.Bgt_S; } else { throw new ApplicationException(); } // If [condition], go to next bit. Otherwise do instruction 3, then go to end il.Emit(conditionOpcode, equalLabel); GenerateStatement(funcNode.Children[3]); il.Emit(OpCodes.Br_S, afterLabel); il.MarkLabel(equalLabel); GenerateStatement(funcNode.Children[2]); il.MarkLabel(afterLabel); //LocalBuilder aLocal = il.DeclareLocal(typeof(Int32)); //il.Emit(OpCodes.Stloc, aLocal); //il.Emit(OpCodes.Ldloc, aLocal); } else if (func is Tree.FuncOr) { Tree.FuncOr funcOr = func as Tree.FuncOr; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.Or); } else if (func is Tree.FuncAnd) { Tree.FuncAnd funcAnd = func as Tree.FuncAnd; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.And); } else if (func is Tree.FuncMax) { Tree.FuncMax funcMax = func as Tree.FuncMax; // Output the statements, which should leave their values on the stack GenerateStatement(funcNode.Children[0]); GenerateStatement(funcNode.Children[1]); il.Emit(OpCodes.Call, typeof(Math).GetMethod("Max", new Type[] { typeof(int), typeof(int) })); } else { throw new ApplicationException("Unknown function"); } } else { throw new ApplicationException("Unknown node"); } }