private Type GetBytes(ExpressionPath path, Type parentType) { if (path.IsMethod) { return(GetMethod(path, parentType)); } if (path.IsAssignment) { PropertyInfo pi = ReflectionCache.Instance.GetProperty(parentType, path.ID); if (pi == null) { throw new NullReferenceException(string.Format( "The property '{0}.{1}' could not be found", parentType.FullName, path.ID )); } ByteCode bc = ByteCode.Create(OpCodes.InvokeMethod, path.ID); bc.VirtualMethod = pi.GetSetMethod(); GetBytesFromArgs(path, bc, parentType); _bytes.Add(bc); return(null); } return(GetProperty(path, parentType)); }
/// <summary> /// Creates a new instance /// </summary> public ExecAssignAction(Rule rule, ExpressionPath path, ExpressionNode rhs, Engine engine) : base(rule) { _engine = engine; _expr = new Expression(rule); // Get the setter property (since it must be the last thing pushed to the stack) // ExpressionPath last = path.Paths.Last.Value; last.IsAssignment = true; last.Args.Add(rhs); ExpressionNode node = new ExpressionNode(); node.Value = path; _expr.Compile(node, _engine); }
private Type GetMethod(ExpressionPath path, Type parentType) { ByteCode bc = ByteCode.Create(OpCodes.InvokeMethod, path.ID); bc.VirtualMethod = ReflectionCache.Instance.GetMethod(parentType, path.ID); if (bc.VirtualMethod == null) { throw new NullReferenceException(string.Format( "The method '{0}.{1}()' could not be found", parentType.FullName, path.ID )); } GetBytesFromArgs(path, bc, parentType); _bytes.Add(bc); return(bc.VirtualMethod.ReturnType); }
private Type GetProperty(ExpressionPath path, Type parentType) { if (string.Compare(path.ID, "this") == 0) { ByteCode bc = ByteCode.Create(OpCodes.LoadObject, "Engine"); bc.VirtualObject = ReflectionCache.Instance.GetThis(); _bytes.Add(bc); return(_engine.GetType()); } ByteCode bcprop = ByteCode.Create(OpCodes.InvokeProperty, path.ID); bcprop.VirtualProperty = ReflectionCache.Instance.GetProperty(parentType, path.ID); if (bcprop.VirtualProperty == null) { FieldInfo fi = ReflectionCache.Instance.GetField(parentType, path.ID); if (fi != null) { throw new NotSupportedException(string.Format( "Fields (or public member variables) are NOT supported. '{0}.{1}' must be wrapped by a property.", parentType.FullName, path.ID )); } throw new NullReferenceException(string.Format( "The property '{0}.{1}' could not be found", parentType.FullName, path.ID )); } _bytes.Add(bcprop); bcprop.VirtualMethod = bcprop.VirtualProperty.GetGetMethod(); return(bcprop.VirtualMethod.ReturnType); }
private void GetBytesFromArgs(ExpressionPath path, ByteCode bc, Type parentType) { if (path.Args.Count > 0) { if (path.Args.Count != bc.VirtualMethodParemterCount) { throw new Exception(string.Format( "Invalid number of arguments for '{0}.{1}()', expected {2} found {3}.", parentType.FullName, path.ID, bc.VirtualMethodParemterCount, path.Args.Count )); } path.Args.Reverse(); foreach (ExpressionNode node in path.Args) { GetBytes(node); } } }
private void GetBytes(ExpressionNode node) { if (node.Left != null) { GetBytes(node.Left); } if (node.Right.Count > 0) { foreach (ExpressionNode en in node.Right) { GetBytes(en); switch (node.Opr) { case ExpressionOperators.None: break; case ExpressionOperators.Or: _bytes.Add(ByteCode.Create(OpCodes.Or)); break; case ExpressionOperators.And: _bytes.Add(ByteCode.Create(OpCodes.And)); break; case ExpressionOperators.Xor: _bytes.Add(ByteCode.Create(OpCodes.Xor)); break; case ExpressionOperators.Eq: _bytes.Add(ByteCode.Create(OpCodes.Eq)); break; case ExpressionOperators.Ne: _bytes.Add(ByteCode.Create(OpCodes.Ne)); break; case ExpressionOperators.Lt: _bytes.Add(ByteCode.Create(OpCodes.Lt)); break; case ExpressionOperators.Gt: _bytes.Add(ByteCode.Create(OpCodes.Gt)); break; case ExpressionOperators.Le: _bytes.Add(ByteCode.Create(OpCodes.Le)); break; case ExpressionOperators.Ge: _bytes.Add(ByteCode.Create(OpCodes.Ge)); break; case ExpressionOperators.Str: _bytes.Add(ByteCode.Create(OpCodes.Str)); break; case ExpressionOperators.Add: _bytes.Add(ByteCode.Create(OpCodes.Add)); break; case ExpressionOperators.Sub: _bytes.Add(ByteCode.Create(OpCodes.Sub)); break; case ExpressionOperators.Mul: _bytes.Add(ByteCode.Create(OpCodes.Mul)); break; case ExpressionOperators.Div: _bytes.Add(ByteCode.Create(OpCodes.Div)); break; case ExpressionOperators.Mod: _bytes.Add(ByteCode.Create(OpCodes.Mod)); break; case ExpressionOperators.Neg: _bytes.Add(ByteCode.Create(OpCodes.Neg)); break; case ExpressionOperators.Not: _bytes.Add(ByteCode.Create(OpCodes.Not)); break; case ExpressionOperators.IsNull: _bytes.Add(ByteCode.Create(OpCodes.IsNull)); break; default: throw new Exception(string.Format( "'{0}' Expression Operator has not been accounted for.", node.Opr )); } } } if (node.Value != null) { if (node.Value is Variable) { _bytes.Add(ByteCode.Create(OpCodes.LoadVariable, (node.Value as Variable).ID)); } else if (node.Value is ExpressionPath) { ExpressionPath path = node.Value as ExpressionPath; Type parent = GetBytes(path, null); LinkedListNode <ExpressionPath> pathnode = path.Paths.First; while (pathnode != null) { parent = GetBytes(pathnode.Value, parent); pathnode = pathnode.Next; } } else if (node.Value is string) { _bytes.Add(ByteCode.Create(OpCodes.PushStr, node.Value)); } else if (node.Value is float || node.Value is int) { _bytes.Add(ByteCode.Create(OpCodes.PushNbr, node.Value)); } else if (node.Value is bool) { _bytes.Add(ByteCode.Create(OpCodes.PushBool, node.Value)); } else { _bytes.Add(ByteCode.Create(OpCodes.Push, node.Value)); } } }