public InvokeStatic(Object ID, MethodInfo mi) { _methodInfo = mi; _implictExecutive = false; ParameterInfo[] parameter_info = _methodInfo.GetParameters(); List<Executive.Parameter> parameters = new List<Executive.Parameter>(); foreach (ParameterInfo pi in parameter_info) { if (pi.IsByRefParameter()) throw new ArgumentException("ByRef parameter is not allowed"); Executive.Parameter p = new Executive.Parameter(); p.Type = pi.ParameterType; if (pi.Position == 0 && pi.ParameterType == typeof(Executive)) { object[] attrs = pi.GetCustomAttributes(true); foreach (object atr in attrs) if (atr is ImplictAttribute) { _implictExecutive = true; break; } if (_implictExecutive) continue; } else if (pi.ParameterType.IsArray && pi.Position == parameter_info.Length - 1) { object[] attrs = pi.GetCustomAttributes(true); foreach (object atr in attrs) if (atr is System.ParamArrayAttribute) { p.VariableParam = true; p.Type = pi.ParameterType.GetElementType(); break; } } parameters.Add(p); } Name = new FuncName(ID, parameters.ToArray()); }
public void Register(object id, MethodInfo method) { bool context = false; XQueryFunctionRecord rec = new XQueryFunctionRecord(); rec.id = id; object[] attrs = method.GetCustomAttributes(typeof(XQuerySignatureAttribute), false); XQuerySignatureAttribute sig = null; if (attrs.Length > 0) sig = (XQuerySignatureAttribute)attrs[0]; ParameterInfo[] parameter_info = method.GetParameters(); List<XQuerySequenceType> type_list = new List<XQuerySequenceType>(); int implict = -1; foreach (ParameterInfo pi in parameter_info) { if (pi.ParameterType == typeof(IContextProvider)) { if (context) throw new ArgumentException(pi.Name); context = true; continue; } bool customized = false; bool variableParam = false; object[] pi_attrs = pi.GetCustomAttributes(false); foreach (object pi_atr in pi_attrs) { if (pi_atr is System.ParamArrayAttribute) variableParam = true; else if (pi_atr is ImplictAttribute) { customized = true; if (implict != -1) throw new ArgumentException(pi.Name); implict = pi.Position; } else { XQueryParameterAttribute xattr = pi_atr as XQueryParameterAttribute; if (xattr != null) { type_list.Add(new XQuerySequenceType(xattr.TypeCode, xattr.Cardinality, variableParam ? pi.ParameterType.GetElementType() : pi.ParameterType)); customized = true; break; } } } if (!customized) { if (pi.ParameterType == typeof(XQueryNodeIterator)) type_list.Add(new XQuerySequenceType(XmlTypeCode.Item, XmlTypeCardinality.ZeroOrMore, pi.ParameterType)); else type_list.Add(new XQuerySequenceType(pi.ParameterType, XmlTypeCardinality.One)); } } if (sig != null && sig.Return != XmlTypeCode.None) rec.returnType = new XQuerySequenceType(sig.Return, sig.Cardinality, method.ReturnType); else { if (method.ReturnType == typeof(XQueryNodeIterator)) rec.returnType = new XQuerySequenceType(XmlTypeCode.Item, XmlTypeCardinality.ZeroOrMore, method.ReturnType); else rec.returnType = new XQuerySequenceType(method.ReturnType, XmlTypeCardinality.One); } if (sig != null) { rec.variableParams = sig.VariableParams; rec.validationReader = sig.ValidationReaderDemanded; } rec.parameters = type_list.ToArray(); FunctionSocket sock = new FunctionSocket(rec); FunctionSocket next; if (m_table.TryGetValue(rec.id, out next)) { FunctionSocket curr = next; while (curr != null) { if (curr.rec.parameters.Length == rec.parameters.Length && curr.rec.variableParams == rec.variableParams) throw new InvalidOperationException(method.ToString()); curr = curr.next; } sock.next = next; } m_table[rec.id] = sock; GlobalSymbols.DefineStaticOperator(rec.id, method); if (context) { object[] body; Executive.Parameter[] parameters; if (implict == -1) { parameters = new Executive.Parameter[parameter_info.Length - 1]; body = new object[parameter_info.Length + 2]; } else { parameters = new Executive.Parameter[parameter_info.Length - 2]; body = new object[parameter_info.Length + 1]; } int k = 0; int i = 2; body[0] = Funcs.List; body[1] = Lisp.List(Lisp.QUOTE, rec.id); foreach (ParameterInfo pi in parameter_info) { if (pi.Position != implict) { if (pi.ParameterType != typeof(IContextProvider)) { parameters[k] = new Executive.Parameter(); parameters[k].ID = ATOM.Create(String.Format("p{0}", k + 1)); parameters[k].Type = typeof(System.Object); parameters[k].VariableParam = false; body[i++] = parameters[k].ID; k++; } else body[i++] = Lisp.List(Lisp.QUOTE, ID.Context); } } GlobalSymbols.Defmacro(rec.id, parameters, Lisp.List(body)); } }
private void ProcessFuncDecl(Notation notation, Notation.Record rec) { int stack_pos = _varTable.BeginFrame(); FunctionDecl decl = _fdecl[rec.sym]; Executive.Parameter[] executiveParameters = new Executive.Parameter[decl.parameters.Length]; for (int k = 0; k < decl.parameters.Length; k++) { FunctionParameter p = decl.parameters[k]; executiveParameters[k].ID = p.id; executiveParameters[k].Type = p.type.ValueType; executiveParameters[k].VariableParam = false; _varTable.PushVar(p.id, p.type); } if (rec.args.Length > 3) { if (rec.args[3] == null) // external throw new NotImplementedException(); else { XQueryExprBase expr = (XQueryExprBase)ProcessExpr(notation, rec.args[3]); object body = expr.ToLispFunction(); if (decl.returnType != XQuerySequenceType.Item) { XQuerySequenceType type = EvalExprType(body); if (!decl.returnType.Equals(type)) body = Lisp.List(ID.CastArg, body, decl.returnType); } LambdaExpr lambdaExpr = new LambdaExpr(decl.f, executiveParameters, typeof(System.Object), body); _context.Engine.Defun(lambdaExpr); } } else { if (rec.args[2] == null) // external throw new NotImplementedException(); else { XQueryExprBase expr = (XQueryExprBase)ProcessExpr(notation, rec.args[2]); LambdaExpr lambdaExpr = new LambdaExpr(decl.f, executiveParameters, typeof(System.Object), expr.ToLispFunction()); _context.Engine.Defun(lambdaExpr); } } _varTable.EndFrame(stack_pos); }
public static bool ForAny([Implict] Executive engine, Resultset rs, object param, object body) { FunctionLink compiledBody = new FunctionLink(); Executive.Parameter[] parameters = new Executive.Parameter[1]; parameters[0].ID = param; parameters[0].Type = typeof(System.Object); object[] args = new object[1]; while (rs.Begin != null) { Row row = rs.Dequeue(); if (!row.HasNullValues) { if (row.Length == 1) args[0] = row.ItemArray[0]; else args[0] = Lisp.List(row.ItemArray); object res = engine.Apply(null, parameters, body, args, compiledBody, engine.DefaultPool); if (res != null && res != Undefined.Value) { rs.Cancel(); return true; } } } return false; }