private string wrapStartProductions(string startSymbol, Dictionary <string, List <ProductionInfo> > productionsDict) { string new_start = grammar.RegisterNewSymbol("__start_" + startSymbol, grammar.GetTypeNameOfSymbol(startSymbol)); var prod = new ProductionInfo(SymbolPosition.None, new_start, RecursiveEnum.No, new[] { new RhsSymbol(SymbolPosition.None, null, startSymbol) }, null); var param = FuncParameter.Create(startSymbol, grammar.TreeNodeName, dummy: false); // this code is really an identity call prod.ActionCode = CodeLambda.CreateProxy(new_start, // parameters new FuncParameter[] { param }, grammar.TreeNodeName, functionsRegistry.Add(FunctionRegistry.IdentityFunction(new_start)), // its arguments new [] { param.NameAsCode() }); productionsDict.Add(new_start, new List <ProductionInfo> { prod }); return(new_start); }
public IList <FuncParameter> LoadFuncParameter(string catalogs) { string sql = @"SELECT f.funcname,p.pindex,p.pname,p.displayname,p.datatype,p.droplistId,p.edittype,d.code FROM rpt_func_param p,rpt_func f,rpt_droplist d WHERE p.funcphid = f.phid AND d.phid = p.droplistid AND f.catalogid IN ({0}) ORDER BY f.catalogid,f.funcname,p.pindex "; sql = string.Format(sql, catalogs); var datas = this.QueryForDataTable(sql); if (datas == null) { throw new FuncException("无法从数据库加载公式参数信息"); } IList <FuncParameter> funcParamList = new List <FuncParameter>(); foreach (DataRow dr in datas.Rows) { FuncParameter paramInfo = new FuncParameter(); paramInfo.FuncName = dr["funcname"].TryGetString(); paramInfo.Name = dr["pname"].TryGetString(); paramInfo.Index = dr["pindex"].TryGetInt(); paramInfo.DisplayProperty = dr["displayname"].TryGetString(); paramInfo.ParamType = dr["datatype"].TryGetString(); paramInfo.DroplistCode = dr["code"].TryGetString(); //下拉名称 paramInfo.EditType = dr["edittype"].TryGetString(); //下拉类型 funcParamList.Add(paramInfo); } return(funcParamList); }
private void FunctionParameter_Load(object sender, EventArgs e) { cmbTipo.DataSource = Enum.GetValues(typeof(DataTypes)); cmbMecanism.DataSource = Enum.GetValues(typeof(MechanismFunctionParameter)); Parametro = new FuncParameter(); cmbMecanism.Enabled = false; numericUpDown1.Enabled = false; if (Padre.Funcion.Parametros.Find(x => x.IsReturn) == null) { chkIsReturn.Enabled = true; } else { chkIsReturn.Enabled = false; } }
public static IList <FuncInfo> GetFuncs(string xml) { IList <FuncInfo> funcInfos = new List <FuncInfo>(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); var xmlFuncs = xmlDoc.SelectNodes("/root/Functions/Function"); foreach (XmlNode node in xmlFuncs) { XmlElement xmlFunc = node as XmlElement; FuncInfo funcInfo = new FuncInfo(); string funcName = xmlFunc.GetAttribute("name");//函数名称 funcInfo.Name = funcName; //函数参数 var xmlFuncParams = xmlFunc.ChildNodes; int index = 0; IList <FuncParameter> paramList = new List <FuncParameter>(); foreach (var p in xmlFuncParams) { XmlElement xmlParam = p as XmlElement; FuncParameter funcParam = new FuncParameter(); funcParam.Value = xmlParam.InnerText; funcParam.ParamType = xmlParam.GetAttribute("dataType"); funcParam.FuncName = funcName; funcParam.Index = index; paramList.Add(funcParam); index++; } funcInfo.Paras = paramList; funcInfos.Add(funcInfo); } return(funcInfos); }
private string registerLambda(string lhsSymbol, IEnumerable <string> inputTypeNames, string outputTypeName, // each pair holds real name (like "expr") and (as backup) dummy name, like "_2" IEnumerable <Tuple <string, string> > arguments, CodeBody body) { if (inputTypeNames.Count() != arguments.Count()) { throw new ArgumentException("Creating a function -- types count vs. arguments count mismatch."); } CodeLambda lambda = null; // identity function, i.e. f(x) = x, we check only real name, if it was a dummy name, it would be if (arguments.Count() == 1) { if (arguments.Single().Item1 == body.Make().Trim()) { lambda = FunctionRegistry.IdentityFunction(lhsSymbol); } else if (arguments.Single().Item2 == body.Make().Trim()) { throw new InvalidOperationException("Somehow dummy name which should not exist was referenced."); } } if (lambda == null) { lambda = new CodeLambda(lhsSymbol, arguments.SyncZip(inputTypeNames) .Select(it => FuncParameter.Create(it.Item1.Item1, it.Item1.Item2, it.Item2)), outputTypeName, body); } return(functionsRegistry.Add(lambda)); }
/// <summary> /// Extracts data for a binary expression /// </summary> /// <param name="myComplexValue">The complex part of the binary expression.</param> /// <param name="mySimpleValue">The simple/atomic part of the expression.</param> /// <param name="errors">The list of errors.</param> /// <param name="typeOfBinExpr">The kind of the binary expression</param> /// <returns>A data tuple.</returns> private static DataContainer ExtractData(AExpressionDefinition myComplexValue, AExpressionDefinition mySimpleValue, ref TypesOfBinaryExpression typeOfBinExpr, GQLPluginManager myPluginManager, IGraphDB myGraphDB, SecurityToken mySecurityToken, Int64 myTransactionToken, Boolean aggregateAllowed) { #region data //the complex IDNode (sth. like U.Age or Count(U.Friends)) IDChainDefinition complexIDNode = null; //the value that is on the opposite of the complex IDNode AExpressionDefinition simpleValue = null; //a complex IDNode may result in a complexValue (i.e. Count(U.Friends) --> 3) AExpressionDefinition complexValue = null; //reference to former myComplexValue AExpressionDefinition extraordinaryValue = null; #endregion #region extraction if (myComplexValue is IDChainDefinition) { #region IDNode #region Data complexIDNode = (IDChainDefinition)myComplexValue; complexIDNode.Validate(myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, false); if (complexIDNode.Any(id => id is ChainPartFuncDefinition)) { if (complexIDNode.Edges == null || complexIDNode.Edges.Count == 0) { #region parameterless function var fcn = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); // somes functions (aggregates) like SUM are not valid for where expressions, though they are not resolved if (fcn.Function == null) { throw new FunctionDoesNotExistException(fcn.FuncName); } FuncParameter pResult = fcn.Function.ExecFunc(null, null, null, myGraphDB, mySecurityToken, myTransactionToken); //simpleValue = new AtomValue(fcn.Function.TypeOfResult, ((FuncParameter)pResult.Value).Value); //the new simple value extraced from the function simpleValue = new ValueDefinition(((FuncParameter)pResult).Value); typeOfBinExpr = TypesOfBinaryExpression.Unknown; //we do not know if we are left or right associated complexIDNode = null; //we resolved it... so it's null #endregion } else { //extraordinaryValue = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); extraordinaryValue = complexIDNode; if (mySimpleValue is ValueDefinition) { simpleValue = mySimpleValue; } } } else { if (mySimpleValue is ValueDefinition) { try { if (complexIDNode.IsUndefinedAttribute) { throw new VertexAttributeIsNotDefinedException(complexIDNode.UndefinedAttribute); } simpleValue = GetCorrectValueDefinition(complexIDNode.LastAttribute, complexIDNode.LastType, ((ValueDefinition)mySimpleValue)); } catch (FormatException) { throw new DataTypeDoesNotMatchException(((IPropertyDefinition)complexIDNode.LastAttribute).BaseType.Name, ((ValueDefinition)mySimpleValue).Value.GetType().Name); } } else { if (mySimpleValue is TupleDefinition) { ((TupleDefinition)mySimpleValue).ConvertToAttributeType(myPluginManager, complexIDNode.LastAttribute, myGraphDB, mySecurityToken, myTransactionToken); simpleValue = mySimpleValue; } } } #endregion #endregion } else if (myComplexValue is TupleDefinition) { #region TupleSetNode complexValue = ((TupleDefinition)myComplexValue); simpleValue = mySimpleValue; typeOfBinExpr = TypesOfBinaryExpression.Atom; #endregion } else if (myComplexValue is AggregateDefinition) { #region AggregateNode if (aggregateAllowed) { if (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters.Count != 1) { throw new GQLAggregateArgumentException("An aggregate must have exactly one expression."); } if (!(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] is IDChainDefinition)) { throw new GQLAggregateArgumentException("An aggregate must have exactly one IDNode."); } #region Data complexIDNode = (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] as IDChainDefinition); if (complexIDNode == null) { throw new InvalidIDNodeException("Only single IDNodes are currently allowed in aggregates!"); } #endregion #region values simpleValue = mySimpleValue; extraordinaryValue = myComplexValue; #endregion } else { throw new AggregateNotAllowedException(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Aggregate.PluginShortName); } #endregion } else { throw new NotImplementedQLException(""); } #endregion return(new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(complexIDNode, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(simpleValue, complexValue), new Tuple <AExpressionDefinition, AExpressionDefinition>(extraordinaryValue, null))); }
public FuncParameter(FuncParameter old, string value) { this.Name = old.Name; this.Value = value; }
public static CodeLambda IdentityFunction(string lhs) { // we are creating effectivelly singleton identity function, not 100% though, because // in case of struct instances it would lead to boxing/unboxing, BUT... TREE_NODE in NLT has to be "class" return(new CodeLambda(lhs, new[] { FuncParameter.Create("x", "object", dummy: false) }, "object", new CodeBody().AddIdentifier("x"))); }
private void substituteProductions(Dictionary <string, List <ProductionInfo> > productionsDict, ProductionInfo[] substitutes, // same LHS bool mixWithSource) { // this function is part of optimization of given production rules // we could have case, that sub production is marked and the one where there is replacement as well // in such case which marking to choose? so we don't allow substitutes to have markings if (substitutes.Any(it => it.IsMarked)) { throw new ArgumentException(); } string sub_lhs = substitutes.Select(it => it.LhsSymbol).Distinct().Single(); // making sure LHS symbol is the same Console.WriteLine("Substituting " + sub_lhs); foreach (string lhs in productionsDict.Keys.ToArray()) { var replacements = new List <ProductionInfo>(); foreach (ProductionInfo prod in productionsDict[lhs]) { // nothing to replace if (!prod.RhsSymbols.Any(it => it.SymbolName.Equals(sub_lhs))) { replacements.Add(prod); } else { // -1 -- use original symbol, >=0 -- substitute (the value is the index of substitution) IEnumerable <CycleCounter> counters = prod.RhsSymbols.ZipWithIndex() .Select(it => { bool hit = it.Item1.SymbolName.Equals(sub_lhs); return(new CycleCounter(((!hit || mixWithSource) ? -1 : 0), (hit ? substitutes.Length : 0), it.Item2)); }).ToArray(); // we have initial run only in case if we mix substitutions with original production, otherwise it pure substitution bool pass_first_as_source = mixWithSource; do { if (pass_first_as_source) { pass_first_as_source = false; if (!counters.All(it => it.Value == -1)) { throw new Exception("Oops, something wrong."); } // it is simply better to add original production instead of re-creating it from symbols // after all, for every rhs symbol we would have -1 value, meaning "use original" replacements.Add(prod); continue; } var p = new ProductionInfo(prod.Position, prod.LhsSymbol, prod.Recursive, counters.SyncZip(prod.RhsSymbols) .Select(it => it.Item1.Value == -1 ? new[] { it.Item2 } : substitutes[it.Item1.Value].RhsSymbols).Flatten(), prod.PassedMarkedWith); // if there was no action code, no point of building proxy for it if (prod.ActionCode != null) { FuncCallCode func_call = (FuncCallCode)(prod.ActionCode.Body); // do not rename those parameters which have counter == -1 IEnumerable <Tuple <FuncParameter, int>[]> parameters = null; parameters = counters.SyncZip(prod.ActionCode.Parameters) .Select(cit => cit.Item1.Value == -1 ? new[] { Tuple.Create(cit.Item2, cit.Item1.Index) } : substitutes[cit.Item1.Value].ActionCode.Parameters.Select(x => Tuple.Create(x, cit.Item1.Index)).ToArray()) .ToArray(); // only subsituted parameters are renamed Dictionary <Tuple <FuncParameter, int>, FuncParameter> param_map = FuncParameter.BuildParamMapping(parameters.Flatten()); p.ActionCode = CodeLambda.CreateProxy(lhs + "_sub__", // parameters parameters.Flatten().Select(it => param_map[it]), prod.ActionCode.ResultTypeName, functionsRegistry.Add(prod.ActionCode), // arguments counters.SyncZip(parameters) .Select(cit => cit.Item1.Value == -1 ? param_map[cit.Item2.Single()].NameAsCode() : new FuncCallCode(functionsRegistry.Add(substitutes[cit.Item1.Value].ActionCode), cit.Item2.Select(x => param_map[x].NameAsCode()))) ); } replacements.Add(p); }while (counters.Iterate()); } } productionsDict[lhs] = replacements; } }
private ProductionInfo makeBuilderCall(string lhsSymbol, RecursiveEnum recursive, AltRule alt, IEnumerable <SymbolMarked> symbolsMarked, string treeNodeName) { // add production with no code var prod_info = new ProductionInfo(alt.Position, lhsSymbol, recursive, symbolsMarked.Where(it => it.IsEnabled).Select(it => it.Symbol), alt.MarkWith); CodeBody code_body = null; if (alt.Code != null) { code_body = (alt.Code as CodeMix).BuildBody(symbolsMarked.Where(sym => sym.Symbol.ObjName != null) .Select(sym => sym.Symbol.GetCodeArgumentNames().Select(it => Tuple.Create(it, sym.IsEnabled))).Flatten()) .Trim(); string identity_function_on = null; // are we just passing one of the parameters? if (code_body.IsIdentity) { identity_function_on = code_body.IdentityIdentifier; } foreach (string var_name in code_body.GetVariables()) { SymbolMarked sym = symbolsMarked .Where(sm => sm.Symbol.GetCodeArgumentNames().Contains(var_name)) // there could be duplicates so we "prefer" enabled element .OrderBy(it => it.IsEnabled ? 0 : 1) .FirstOrDefault(); if (sym != null) { sym.IsParamUsed = true; } } var anon_args = new Dictionary <SymbolMarked, string>(); foreach (Tuple <SymbolMarked, int> sym_pair in symbolsMarked.ZipWithIndex()) { if (sym_pair.Item1.Symbol.ObjName == null) { anon_args.Add(sym_pair.Item1, code_body.RegisterNewIdentifier("_" + sym_pair.Item2)); } } IEnumerable <SymbolMarked> arg_symbols = symbolsMarked.Where(it => it.IsEnabled || it.IsParamUsed).ToList(); // build external function to run the user code string func_ref = registerLambda(lhsSymbol, arg_symbols.Select(sym => sym.Symbol.GetCodeArgumentTypes(grammar)).Flatten(), grammar.TreeNodeName, arg_symbols.Select(sym => sym.Symbol.GetCodeArgumentNames() .Select(it => Tuple.Create(it, anon_args.GetOrNull(sym)))).Flatten(), code_body); // build a lambda with call to a just built function // note that our lambda can have fewer arguments than the actual fuction // in such case we pass "nulls" for disabled arguments // we add nulls to params in order to keep track which arguments comes from which parameters IEnumerable <FuncParameter> lambda_params = arg_symbols.Where(it => it.IsEnabled) .Select(it => FuncParameter.Create(it.Symbol.ObjName, anon_args.GetOrNull(it), grammar.GetTypeNameOfSymbol(it.Symbol))).ToArray(); // if the code indicates that this is identity function, then just find out which parameter is passed along if (identity_function_on != null) { // we can fail for two reasons here: // (1) ok -- single variable we found in the code body is not a parameter, but global variable // (2) BAD -- we have case of unpacking the data, and that case so far we cannot handle // ad.2) consider such rule as // x -> (a b)+ { b }; // "a" and "b" will be handled as tuple of lists // so in entry function we will get a tuple, and then we will call actuall user action code // some "__function_13__(a,b)" which returns the "b" // so we could compute index for inner parameter (for "b" it is 1) // but we cannot compute index for outer function, because there is no index for "b" at all // there is only one parameter -- tuple -- holding "a" (in Item1) and "b" (in Item2) at the same time // so if anything we would have to introduce some combo index: // outer index --> optional unpacking index --> inner index // too much trouble for now Option <int> index = lambda_params.Select(it => it.Name) .ZipWithIndex().Where(it => it.Item1 == identity_function_on).Select(it => it.Item2).OptSingle(); if (index.HasValue) { prod_info.IdentityOuterFunctionParamIndex = index.Value; } } prod_info.ActionCode = CodeLambda.CreateProxy( lhsSymbol, // lambda arguments lambda_params, treeNodeName, func_ref, arg_symbols.Select(arg => arg.Symbol.CombinedSymbols == null // regular symbols ? new[] { new CodeBody().AddIdentifier(arg.IsEnabled ? (arg.Symbol.ObjName ?? anon_args[arg]) : CodeWords.Null) } // compound symbols, we have to use embedded atomic symbols instead now : arg.Symbol.UnpackTuple(arg.IsEnabled) ) .Flatten()); prod_info.CodeComment = alt.Code.Comment; } return(prod_info); }
public void RefrescarParametros(FuncParameter parametro) { _parametrosBindingList.Add(parametro); }