예제 #1
0
		public EvaluationCallback Create(Node node)
		{
			foreach (Node n in EnumerateNodes(node))
			{
				if (n.Token.AsOperator == Operator.Assignment) return NestedFunctionBuild(node);

				if (n.Token.Data is Tokenizing.CustomFunctionData) return NestedFunctionBuild(node);
			}

			return SingleFunctionBuild(node);
		}
예제 #2
0
		Node ParseNode(List<Token> tokens, ref Int32 tokenindex)
		{
			if (tokens == null) throw new ArgumentNullException("tokens");
			if (tokenindex < 0 || tokenindex >= tokens.Count) throw new ArgumentOutOfRangeException("tokenindex");

			Node lhs = ParseEndNode(tokens, ref tokenindex);
			if (lhs == null) return null;

			for (Token token = GetToken(tokens, tokenindex); token != null; token = GetToken(tokens, tokenindex))
			{
				if ((token.Data is Tokenizing.BinaryOperatorData) == false) break;

				if (lhs.Token.Data is Tokenizing.RangeData && lhs.PrecedenceOverride == false) return null;

				Node operatornode = new Node(token);
				++tokenindex;

				Operator @operator = (token.Data as Tokenizing.BinaryOperatorData).Operator;

				if (@operator == Operator.Equals || @operator == Operator.NotEquals)
				{
					Node range = ParseRangeNode(tokens, ref tokenindex);
					if (range != null)
					{
						range.Children[0] = lhs;
						range.Arguments[0] = @operator;

						lhs = range;
						continue;
					}
				}

				Node rhs = ParseNode(tokens, ref tokenindex);
				if (rhs == null) return null;

				if(SwitchOrder(operatornode, rhs) == true)
				{
					lhs = BreakTree(lhs, operatornode, rhs);
				}
				else
				{
					operatornode.Children.Add(lhs);
					operatornode.Children.Add(rhs);

					lhs = operatornode;
				}
			}

			return lhs;
		}
예제 #3
0
		public EvaluationCallback Create(Node node)
		{
			DynamicMethod method = new DynamicMethod(String.Empty, typeof(Number), new Type[] { typeof(Object) }, typeof(Compiler), true);

			CompilerState compilerstate = new CompilerState();
			compilerstate.Generator = method.GetILGenerator();
			compilerstate.FunctionState = compilerstate.Generator.DeclareLocal(typeof(Object));
			compilerstate.ErrorLabel = compilerstate.Generator.DefineLabel();
			compilerstate.ErrorVariable = compilerstate.Generator.DeclareLocal(typeof(Boolean));

			compilerstate.Generator.Emit(OpCodes.Ldarg, 0);
			StoreLocalVariable(compilerstate, compilerstate.FunctionState);

			LocalVariableInfo result = Emit(compilerstate, node);

			if (result.LocalType == typeof(Int32))
			{
				LoadLocalVariable(compilerstate, result);
				compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Int32) }));
			}
			else if (result.LocalType == typeof(Single))
			{
				LoadLocalVariable(compilerstate, result);
				compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Single) }));
			}
			else
			{
				throw new Exception();
			}

			compilerstate.Generator.Emit(OpCodes.Ret);

			compilerstate.Generator.MarkLabel(compilerstate.ErrorLabel);
			LoadLocalVariable(compilerstate, compilerstate.Generator.DeclareLocal(typeof(Number)));
			compilerstate.Generator.Emit(OpCodes.Ret);

			EvaluationCallback callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback));
			return callback;
		}
예제 #4
0
		LocalVariableInfo EmitAssignmentOperator(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData;
			if (data == null || data.Operator != Operator.Assignment) throw new Exception();

			if (node.Children.Count != 2) throw new Exception();

			Evaluation.Tokenizing.CustomFunctionData vardata = node.Children[0].Token.Data as Evaluation.Tokenizing.CustomFunctionData;
			if (vardata == null) throw new Exception();

			if (node.Children[0].Children.Count != 1) throw new Exception();

			LocalVariableInfo index = Emit(state, node.Children[0].Children[0]);
			LocalVariableInfo value = Emit(state, node.Children[1]);

			List<LocalVariableInfo> args = new List<LocalVariableInfo>() { state.FunctionState, index, value };

			if (vardata.Type == typeof(Triggers.Var))
			{
				return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_Var"), args);
			}

			if (vardata.Type == typeof(Triggers.FVar))
			{
				return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_FVar"), args);
			}

			if (vardata.Type == typeof(Triggers.SysVar))
			{
				return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_SysVar"), args);
			}

			if (vardata.Type == typeof(Triggers.SysFVar))
			{
				return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_SysFVar"), args);
			}

			throw new Exception();
		}
예제 #5
0
		LocalVariableInfo EmitOperator(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData;
			if (data == null) throw new Exception();

			if (node.Children.Count == 1) return EmitUnaryOperator(state, node);

			if (node.Children.Count != 2) throw new Exception();

			if (data.Operator == Operator.Assignment) return EmitAssignmentOperator(state, node);

			LocalVariableInfo lhs = Emit(state, node.Children[0]);
			LocalVariableInfo rhs = Emit(state, node.Children[1]);

			switch (data.Operator)
			{
				case Operator.Plus:
					return EmitArithmeticOperator(state, OpCodes.Add, lhs, rhs);

				case Operator.Minus:
					return EmitArithmeticOperator(state, OpCodes.Sub, lhs, rhs);

				case Operator.Divide:
					return EmitArithmeticOperator(state, OpCodes.Div, lhs, rhs);

				case Operator.Multiply:
					return EmitArithmeticOperator(state, OpCodes.Mul, lhs, rhs);

				case Operator.Modulus:
					return EmitArithmeticOperator(state, OpCodes.Rem, lhs, rhs);

				case Operator.Equals:
				case Operator.NotEquals:
				case Operator.Greater:
				case Operator.GreaterEquals:
				case Operator.Lesser:
				case Operator.LesserEquals:
					return EmitComparsionOperator(state, data.Operator, lhs, rhs);

				case Operator.LogicalAnd:
				case Operator.LogicalOr:
				case Operator.LogicalXor:
					return EmitLogicalOperator(state, data.Operator, lhs, rhs);

				case Operator.Exponent:
					return EmitMethod(state, typeof(Math).GetMethod("Pow"), new List<LocalVariableInfo>() { lhs, rhs });

				default:
					throw new Exception();
			}
		}
예제 #6
0
		LocalVariableInfo EmitFunction(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.CustomFunctionData data = node.Token.Data as Evaluation.Tokenizing.CustomFunctionData;
			if (data == null) throw new Exception();

			if (data.Type == typeof(Triggers.Const) || data.Type == typeof(Triggers.GetHitVar))
			{
				return EmitSpecialFunction(state, data.Type, (String)node.Arguments[0]);
			}

			List<LocalVariableInfo> functionargs = EmitDescendants(state, node);
			MethodInfo method = FindCorrectMethod(data.Type, functionargs);
			ParameterInfo[] parameters = method.GetParameters();

			LoadLocalVariable(state, state.FunctionState);
			state.Generator.Emit(OpCodes.Ldloca, state.ErrorVariable.LocalIndex);

			for (Int32 i = 0; i != functionargs.Count; ++i)
			{
				LocalVariableInfo arg = functionargs[i];
				ParameterInfo parameter = parameters[i + 2];

				LoadLocalVariable(state, arg);

				//if (parameter.ParameterType == typeof(Int32) && arg.LocalType == typeof(Single)) state.Generator.Emit(OpCodes.Conv_I4);
				//if (parameter.ParameterType == typeof(Single) && arg.LocalType == typeof(Int32)) state.Generator.Emit(OpCodes.Conv_R4);
			}

			state.Generator.Emit(OpCodes.Call, method);

			Type returntype = method.ReturnType;
			if (returntype == typeof(Boolean)) returntype = typeof(Int32);

			LocalVariableInfo result = state.Generator.DeclareLocal(returntype);
			StoreLocalVariable(state, result);

			LoadLocalVariable(state, state.ErrorVariable);
			state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel);

			return result;
		}
예제 #7
0
		LocalVariableInfo EmitStateRedirection(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.StateRedirectionData data = node.Token.Data as Evaluation.Tokenizing.StateRedirectionData;
			if (data == null) throw new Exception();

			if (node.Children.Count < 1) throw new Exception();

			List<LocalVariableInfo> functionargs = EmitRedirectionDescendants(state, node);
			MethodInfo method = FindCorrectRedirectionMethod(data.Type, functionargs);
			ParameterInfo[] parameters = method.GetParameters();

			LoadLocalVariable(state, state.FunctionState);
			state.Generator.Emit(OpCodes.Ldloca, state.ErrorVariable.LocalIndex);

			for (Int32 i = 0; i != functionargs.Count; ++i)
			{
				LocalVariableInfo arg = functionargs[i];
				ParameterInfo parameter = parameters[i + 2];

				LoadLocalVariable(state, arg);

				//if (parameter.ParameterType == typeof(Int32) && arg.LocalType == typeof(Single)) state.Generator.Emit(OpCodes.Conv_I4);
				//if (parameter.ParameterType == typeof(Single) && arg.LocalType == typeof(Int32)) state.Generator.Emit(OpCodes.Conv_R4);
			}

			state.Generator.Emit(OpCodes.Call, method);

			LocalVariableInfo oldstate = state.FunctionState;

			state.FunctionState = state.Generator.DeclareLocal(typeof(Object));
			StoreLocalVariable(state, state.FunctionState);

			LoadLocalVariable(state, state.ErrorVariable);
			state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel);

			LocalVariableInfo returnvalue = Emit(state, node.Children[node.Children.Count - 1]);

			state.FunctionState = oldstate;
			return returnvalue;
		}
예제 #8
0
		void SingleFunctionBuild(ILGenerator generator, Node node)
		{
			if (node.Token.Data is Evaluation.Tokenizing.NumberData)
			{
				Number number = (node.Token.Data as Evaluation.Tokenizing.NumberData).GetNumber(node.Token.ToString());

				switch (number.NumberType)
				{
					case NumberType.Int:
						generator.Emit(OpCodes.Ldc_I4, number.IntValue);
						generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Int32) }));
						break;

					case NumberType.Float:
						generator.Emit(OpCodes.Ldc_R4, number.FloatValue);
						generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Single) }));
						break;

					default:
						generator.Emit(OpCodes.Ldloc, generator.DeclareLocal(typeof(Number)).LocalIndex);
						break;
				}
			}
			else if (node.Token.Data is Evaluation.Tokenizing.OperatorData)
			{
				foreach (Node childnode in node.Children) SingleFunctionBuild(generator, childnode);

				if (node.Children.Count == 1 && node.Token.AsOperator == Operator.Minus)
				{
					generator.Emit(OpCodes.Call, typeof(Number).GetMethod("Negate", BindingFlags.Static | BindingFlags.Public));
				}
				else
				{
					String methodname = (node.Token.Data as Evaluation.Tokenizing.OperatorData).Name;
					generator.Emit(OpCodes.Call, typeof(Number).GetMethod(methodname, BindingFlags.Static | BindingFlags.Public));
				}
			}
			else if (node.Token.Data is Evaluation.Tokenizing.RangeData)
			{
				SingleFunctionSubBuild(generator, node);

				generator.Emit(OpCodes.Call, typeof(Number).GetMethod("Range", BindingFlags.Static | BindingFlags.Public));
			}
			else if (node.Token.Data is Evaluation.Tokenizing.CustomFunctionData)
			{
				SingleFunctionSubBuild(generator, node);

				generator.Emit(OpCodes.Call, (node.Token.Data as Evaluation.Tokenizing.CustomFunctionData).Type.GetMethod("Evaluate", BindingFlags.Static | BindingFlags.Public));
			}
			else
			{
			}
		}
예제 #9
0
		List<LocalVariableInfo> EmitRedirectionDescendants(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			List<LocalVariableInfo> output = new List<LocalVariableInfo>();

			for (Int32 i = 0; i < node.Children.Count - 1; ++i) output.Add(Emit(state, node.Children[i]));

			foreach (Object arg in node.Arguments)
			{
				if (arg is String)
				{
					LocalVariableInfo local = state.Generator.DeclareLocal(typeof(String));

					state.Generator.Emit(OpCodes.Ldstr, (String)arg);
					StoreLocalVariable(state, local);

					output.Add(local);
				}
				else if (arg.GetType().IsEnum == true)
				{
					LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType());

					state.Generator.Emit(OpCodes.Ldc_I4, (Int32)arg);
					StoreLocalVariable(state, local);

					output.Add(local);
				}
				else
				{
					throw new Exception();
				}
			}

			return output;
		}
예제 #10
0
		LocalVariableInfo EmitNumber(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.NumberData data = node.Token.Data as Evaluation.Tokenizing.NumberData;
			if (data == null) throw new Exception();

			Number number = data.GetNumber(node.Token.ToString());

			if (number.NumberType == NumberType.Int)
			{
				LocalVariableInfo local = state.Generator.DeclareLocal(typeof(Int32));

				state.Generator.Emit(OpCodes.Ldc_I4, number.IntValue);
				StoreLocalVariable(state, local);
				return local;
			}

			if (number.NumberType == NumberType.Float)
			{
				LocalVariableInfo local = state.Generator.DeclareLocal(typeof(Single));

				state.Generator.Emit(OpCodes.Ldc_R4, number.FloatValue);
				StoreLocalVariable(state, local);
				return local;
			}

			throw new Exception();
		}
예제 #11
0
		static Node BreakTree(Node lhs, Node operatornode, Node rhs)
		{
			if (lhs == null) throw new ArgumentNullException("lhs");
			if (operatornode == null) throw new ArgumentNullException("operatornode");
			if (rhs == null) throw new ArgumentNullException("rhs");

			operatornode.Children.Add(lhs);

			Node newbase = rhs;
			while (newbase.Children.Count != 0 && newbase.Children[0].Children.Count != 0 && newbase.Children[0].PrecedenceOverride == false && SwitchOrder(operatornode, newbase.Children[0]) == true)
			{
				newbase = newbase.Children[0];
			}

			operatornode.Children.Add(newbase.Children[0]);
			newbase.Children[0] = operatornode;

			return rhs;
		}
예제 #12
0
		Node ParseRangeNode(List<Token> tokens, ref Int32 tokenindex)
		{
			if (tokens == null) throw new ArgumentNullException("tokens");
			if (tokenindex < 0 || tokenindex >= tokens.Count) throw new ArgumentOutOfRangeException("tokenindex");

			Int32 savedindex = tokenindex;

			Token token_pre = GetToken(tokens, tokenindex);
			if (token_pre == null || (token_pre.AsSymbol != Symbol.LeftBracket && token_pre.AsSymbol != Symbol.LeftParen)) goto EndOfMethod;
			++tokenindex;

			Node node_left = ParseNode(tokens, ref tokenindex);
			if (node_left == null) goto EndOfMethod;

			Token token_comma = GetToken(tokens, tokenindex);
			if (token_comma == null || token_comma.AsSymbol != Symbol.Comma) goto EndOfMethod;
			++tokenindex;

			Node node_right = ParseNode(tokens, ref tokenindex);
			if (node_right == null) goto EndOfMethod;

			Token token_post = GetToken(tokens, tokenindex);
			if (token_post == null || (token_post.AsSymbol != Symbol.RightBracket && token_post.AsSymbol != Symbol.RightParen)) goto EndOfMethod;
			++tokenindex;

			Node rangenode = new Node(new Token(String.Empty, new Tokenizing.RangeData()));
			rangenode.Children.Add(null);
			rangenode.Children.Add(node_left);
			rangenode.Children.Add(node_right);
			rangenode.Arguments.Add(null);
			rangenode.Arguments.Add(token_pre.AsSymbol);
			rangenode.Arguments.Add(token_post.AsSymbol);
			return rangenode;

		EndOfMethod:
			tokenindex = savedindex;
			return null;
		}
예제 #13
0
		Node ParseEndNode(List<Token> tokens, ref Int32 tokenindex)
		{
			if (tokens == null) throw new ArgumentNullException("tokens");
			if (tokenindex < 0 || tokenindex >= tokens.Count) throw new ArgumentOutOfRangeException("tokenindex");

			Token token = GetToken(tokens, tokenindex);
			if (token == null) return null;

			if (token.Data is Tokenizing.NumberData)
			{
				++tokenindex;

				Node node = new Node(token);
				return node;
			}

			if (token.Data is Tokenizing.UnaryOperatorData)
			{
				++tokenindex;

				Node node = new Node(token);

				Node child = ParseEndNode(tokens, ref tokenindex);
				if (child == null) return null;

				node.Children.Add(child);
				return node;
			}

			if (token.AsOperator == Operator.Minus || token.AsOperator == Operator.Plus)
			{
				++tokenindex;

				Node node = new Node(token);

				Node child = ParseEndNode(tokens, ref tokenindex);
				if (child == null) return null;

				node.Children.Add(child);
				return node;
			}

			if (token.AsSymbol == Symbol.LeftParen)
			{
				Int32 savedindex = tokenindex;

				++tokenindex;

				Node node = ParseNode(tokens, ref tokenindex);
				if (node != null)
				{
					Token endtoken = GetToken(tokens, tokenindex);
					if (endtoken != null && endtoken.AsSymbol == Symbol.RightParen)
					{
						++tokenindex;
						node.PrecedenceOverride = true;
						return node;
					}
				}

				tokenindex = savedindex;
			}

			if (token.Data is Tokenizing.CustomFunctionData)
			{
				Tokenizing.CustomFunctionData data = token.Data as Tokenizing.CustomFunctionData;

				Node node = new Node(token);
				++tokenindex;

				ParseState state = new ParseState(m_system, m_fullnodebuild, m_endnodebuild, m_rangenodebuild, node, tokens, tokenindex);

				Node parsednode = data.Parse(state);
				if (parsednode != null)
				{
					tokenindex = state.TokenIndex;
					return parsednode;
				}
				else
				{
					tokenindex = state.InitialTokenIndex - 1;
					return null;
				}
			}

			if (token.Data is Tokenizing.StateRedirectionData)
			{
				Tokenizing.StateRedirectionData data = token.Data as Tokenizing.StateRedirectionData;

				Node node = new Node(token);
				++tokenindex;

				ParseState state = new ParseState(m_system, m_fullnodebuild, m_endnodebuild, m_rangenodebuild, node, tokens, tokenindex);

				Node parsednode = data.Parse(state);
				if (parsednode != null)
				{
					tokenindex = state.TokenIndex;
					return parsednode;
				}
				else
				{
					tokenindex = state.InitialTokenIndex - 1;
					return null;
				}
			}

			return null;
		}
예제 #14
0
파일: Node.cs 프로젝트: lodossDev/xnamugen
		static Node()
		{
			s_emptynode = new Node(new Token("", new Tokenizing.IntData()));
			s_zeronode = new Node(new Token("0", new Tokenizing.IntData()));
			s_negativeonenode = new Node(new Token("-1", new Tokenizing.IntData()));
		}
예제 #15
0
		static IEnumerable<Node> EnumerateNodes(Node basenode)
		{
			foreach (Node node in basenode.Children)
			{
				foreach (Node child in EnumerateNodes(node)) yield return child;
			}

			yield return basenode;
		}
예제 #16
0
		void SingleFunctionSubBuild(ILGenerator generator, Node node)
		{
			foreach (Node childnode in node.Children)
			{
				SingleFunctionBuild(generator, childnode);
			}

			foreach (Object arg in node.Arguments)
			{
				if (arg is String)
				{
					generator.Emit(OpCodes.Ldstr, (String)arg);
				}
				else if (arg.GetType().IsEnum == true)
				{
					generator.Emit(OpCodes.Ldc_I4, (Int32)arg);
				}
				else
				{
				}
			}
		}
예제 #17
0
		static Boolean SwitchOrder(Node lhs, Node rhs)
		{
			if (lhs == null) throw new ArgumentNullException("lhs");
			if (rhs == null) throw new ArgumentNullException("rhs");

			if (rhs.PrecedenceOverride == true) return false;

			Tokenizing.BinaryOperatorData lhsdata = lhs.Token.Data as Tokenizing.BinaryOperatorData;
			Tokenizing.BinaryOperatorData rhsdata = rhs.Token.Data as Tokenizing.BinaryOperatorData;
			if (lhsdata == null || rhsdata == null) return false;

			return lhsdata.Precedence >= rhsdata.Precedence;
		}
예제 #18
0
		LocalVariableInfo EmitUnaryOperator(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData;
			if (data == null) throw new Exception();

			if (node.Children.Count != 1) throw new Exception();

			if (data.Operator == Operator.Minus)
			{
				LocalVariableInfo value = Emit(state, node.Children[0]);
				LocalVariableInfo result = state.Generator.DeclareLocal(value.LocalType);

				LoadLocalVariable(state, value);
				state.Generator.Emit(OpCodes.Neg);
				StoreLocalVariable(state, result);

				return result;
			}

			if (data.Operator == Operator.LogicalNot)
			{
				LocalVariableInfo value = Emit(state, node.Children[0]);
				LoadLocalVariable(state, value);

				LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32));
				Label l1 = state.Generator.DefineLabel();
				Label l2 = state.Generator.DefineLabel();

				state.Generator.Emit(OpCodes.Brtrue, l1);
				state.Generator.Emit(OpCodes.Ldc_I4_1);
				state.Generator.Emit(OpCodes.Br, l2);

				state.Generator.MarkLabel(l1);
				state.Generator.Emit(OpCodes.Ldc_I4_0);

				state.Generator.MarkLabel(l2);
				StoreLocalVariable(state, result);

				return result;
			}

			throw new Exception();
		}
예제 #19
0
		EvaluationCallback NestedFunctionBuild(Node node)
		{
			if (node.Token.Data is Evaluation.Tokenizing.NumberData)
			{
				Number number = (node.Token.Data as Evaluation.Tokenizing.NumberData).GetNumber(node.Token.ToString());
				return GetNumberCallback(number);
			}

			if (node.Token.Data is Evaluation.Tokenizing.RangeData)
			{
				Object[] args = new Object[node.Children.Count + node.Arguments.Count];

				for (Int32 i = 0; i != node.Children.Count; ++i) args[i] = NestedFunctionBuild(node.Children[i]);
				for (Int32 i = 0; i != node.Arguments.Count; ++i) args[i + node.Children.Count] = node.Arguments[i];

				Constructor constructor = GetRangeConstructor();
				IFunction function = (IFunction)constructor(args);

				return function.Evaluate;
			}

			if (node.Token.AsOperator == Operator.Assignment)
			{
				Object[] args = new Object[node.Children.Count + node.Arguments.Count];

				for (Int32 i = 0; i != node.Children.Count; ++i) args[i] = NestedFunctionBuild(node.Children[i]);
				for (Int32 i = 0; i != node.Arguments.Count; ++i) args[i + node.Children.Count] = node.Arguments[i];

				Constructor constructor = GetCustomFunctionConstructor("_Assignment", typeof(Evaluation.Triggers._Assignment), args);
				IFunction function = (IFunction)constructor(args);

				return function.Evaluate;
			}

			if (node.Token.AsOperator != Operator.None)
			{
				Constructor constructor = GetOperatorTypeConstructor(node.Token.Data as OperatorData);
				EvaluationCallback[] childcallbacks;

				if (node.Token.AsOperator == Operator.Minus && node.Children.Count == 1)
				{
					childcallbacks = new EvaluationCallback[2] { GetNumberCallback(new Number(0)), NestedFunctionBuild(node.Children[0]) };
				}
				else
				{
					childcallbacks = new EvaluationCallback[node.Children.Count];
					for (Int32 i = 0; i != node.Children.Count; ++i) childcallbacks[i] = NestedFunctionBuild(node.Children[i]);
				}

				IFunction function = (IFunction)constructor(childcallbacks);
				return function.Evaluate;
			}

			if (node.Token.Data is Evaluation.Tokenizing.CustomFunctionData)
			{
				Object[] args = new Object[node.Children.Count + node.Arguments.Count];

				for (Int32 i = 0; i != node.Children.Count; ++i) args[i] = NestedFunctionBuild(node.Children[i]);
				for (Int32 i = 0; i != node.Arguments.Count; ++i) args[i + node.Children.Count] = node.Arguments[i];

				CustomFunctionData data = node.Token.Data as CustomFunctionData;

				Constructor constructor = GetCustomFunctionConstructor(data.Name, data.Type, args);
				IFunction function = (IFunction)constructor(args);

				return function.Evaluate;
			}

			return null;
		}
예제 #20
0
		List<LocalVariableInfo> EmitDescendants(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			List<LocalVariableInfo> output = new List<LocalVariableInfo>();

			foreach (Node child in node.Children) output.Add(Emit(state, child));

			foreach (Object arg in node.Arguments)
			{
				if (arg is String)
				{
					LocalVariableInfo local = state.Generator.DeclareLocal(typeof(String));

					state.Generator.Emit(OpCodes.Ldstr, (String)arg);
					StoreLocalVariable(state, local);

					output.Add(local);
				}
				else if (arg.GetType().IsEnum == true)
				{
					LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType());

					state.Generator.Emit(OpCodes.Ldc_I4, (Int32)arg);
					StoreLocalVariable(state, local);

					output.Add(local);
				}
				else if (arg is Combat.HitType[])
				{
					LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType());
					Combat.HitType[] hitypes = (Combat.HitType[])arg;

					state.Generator.Emit(OpCodes.Ldc_I4, hitypes.Length);
					state.Generator.Emit(OpCodes.Newarr, typeof(Combat.HitType));

					StoreLocalVariable(state, local);

					for (Int32 i = 0; i != hitypes.Length; ++i)
					{
						LoadLocalVariable(state, local);

						state.Generator.Emit(OpCodes.Ldc_I4, i);

						state.Generator.Emit(OpCodes.Ldc_I4, (Int32)hitypes[i].Class);
						state.Generator.Emit(OpCodes.Ldc_I4, (Int32)hitypes[i].Power);
						state.Generator.Emit(OpCodes.Newobj, typeof(Combat.HitType).GetConstructor(new Type[] { typeof(AttackClass), typeof(AttackPower) }));

						state.Generator.Emit(OpCodes.Stelem, typeof(Combat.HitType));
					}

					output.Add(local);
				}
				else
				{
					throw new Exception();
				}
			}

			return output;
		}
예제 #21
0
		LocalVariableInfo EmitRange(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			Evaluation.Tokenizing.RangeData data = node.Token.Data as Evaluation.Tokenizing.RangeData;
			if (data == null) throw new Exception();

			if (node.Children.Count != 3) throw new Exception();
			if (node.Arguments.Count != 3) throw new Exception();

			List<LocalVariableInfo> args = EmitDescendants(state, node);

			Type[] argtypes = new Type[args.Count];
			for (Int32 i = 0; i != args.Count; ++i) argtypes[i] = args[i].LocalType;

			MethodInfo method = typeof(SpecialFunctions).GetMethod("Range", argtypes);

			return EmitMethod(state, method, args);
		}
예제 #22
0
		LocalVariableInfo Emit(CompilerState state, Node node)
		{
			if (state == null) throw new Exception();
			if (node == null) throw new Exception();

			if (node.Token.Data is Evaluation.Tokenizing.NumberData)
			{
				return EmitNumber(state, node);
			}

			if (node.Token.Data is Evaluation.Tokenizing.OperatorData)
			{
				return EmitOperator(state, node);
			}

			if (node.Token.Data is Evaluation.Tokenizing.StateRedirectionData)
			{
				return EmitStateRedirection(state, node);
			}

			if (node.Token.Data is Evaluation.Tokenizing.CustomFunctionData)
			{
				return EmitFunction(state, node);
			}

			if (node.Token.Data is Evaluation.Tokenizing.RangeData)
			{
				return EmitRange(state, node);
			}

			throw new Exception();
		}
예제 #23
0
		EvaluationCallback SingleFunctionBuild(Node node)
		{
			DynamicMethod method = new DynamicMethod(String.Empty, typeof(Number), new Type[] { typeof(Object) }, typeof(TreeCompiler));
			ILGenerator generator = method.GetILGenerator();

			foreach (Node n in EnumerateNodes(node))
			{
				if (n.Token.Data is Evaluation.Tokenizing.CustomFunctionData) generator.Emit(OpCodes.Ldarg, 0);
			}

			SingleFunctionBuild(generator, node);

			generator.Emit(OpCodes.Ret);

			EvaluationCallback callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback));

			return callback;
		}