Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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");
            }
        }