/// <summary> /// Expand the results of a template with given name and scope. /// </summary> /// <param name="templateName">Given template name.</param> /// <param name="scope">Given scope.</param> /// <returns>All possiable results.</returns> public List <string> ExpandTemplate(string templateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(SimpleObjectMemory.Wrap(scope)); } if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{LGErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } // Using a stack to track the evaluation trace evaluationTargetStack.Push(new EvaluationTarget(templateName, scope)); var result = Visit(TemplateMap[templateName].ParseTree); evaluationTargetStack.Pop(); return(result); }
/// <summary> /// Expand the results of a template with given name and scope. /// </summary> /// <param name="templateName">Given template name.</param> /// <param name="scope">Given scope.</param> /// <returns>All possiable results.</returns> public List <object> ExpandTemplate(string templateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(scope); } if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(TemplateErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{TemplateErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } // Using a stack to track the evaluation trace evaluationTargetStack.Push(new EvaluationTarget(templateName, scope)); var expanderResult = Visit(TemplateMap[templateName].TemplateBodyParseTree); evaluationTargetStack.Pop(); var result = new List <object>(); expanderResult.ForEach(u => { result.Add(u); }); return(result); }
/// <summary> /// Evaluate a template with given name and scope. /// </summary> /// <param name="inputTemplateName">Template name.</param> /// <param name="scope">Scope.</param> /// <returns>Evaluate result.</returns> public object EvaluateTemplate(string inputTemplateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(scope); } (var reExecute, var templateName) = ParseTemplateName(inputTemplateName); if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(TemplateErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{TemplateErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } var templateTarget = new EvaluationTarget(templateName, scope); var currentEvaluateId = templateTarget.GetId(); EvaluationTarget previousEvaluateTarget = null; if (evaluationTargetStack.Count != 0) { previousEvaluateTarget = evaluationTargetStack.Peek(); if (!reExecute && previousEvaluateTarget.EvaluatedChildren.ContainsKey(currentEvaluateId)) { return(previousEvaluateTarget.EvaluatedChildren[currentEvaluateId]); } } // Using a stack to track the evaluation trace evaluationTargetStack.Push(templateTarget); var result = Visit(TemplateMap[templateName].TemplateBodyParseTree); if (previousEvaluateTarget != null) { previousEvaluateTarget.EvaluatedChildren[currentEvaluateId] = result; } evaluationTargetStack.Pop(); if (lgOptions.LineBreakStyle == LGLineBreakStyle.Markdown && result is string str) { result = NewLineRegex.Replace(str, "$1$1"); } return(result); }
private Templates InjectToExpressionFunction() { var totalTempaltes = new List <Templates> { this }.Union(References); foreach (var curTemplates in totalTempaltes) { var globalFuncs = curTemplates.GetGlobalFunctionTable(curTemplates.Options); foreach (var templateName in globalFuncs) { if (curTemplates.Any(u => u.Name == templateName)) { var prefix = string.IsNullOrWhiteSpace(curTemplates.Namespace) ? string.Empty : curTemplates.Namespace + "."; var newGlobalName = prefix + templateName; Expression.Functions.Add(newGlobalName, new ExpressionEvaluator( newGlobalName, (expression, state, options) => { object result = null; var evaluator = new Evaluator(this, LgOptions); var(args, error) = FunctionUtils.EvaluateChildren(expression, state, options); if (error == null) { var parameters = evaluator.TemplateMap[templateName].Parameters; var newScope = parameters.Zip(args, (k, v) => new { k, v }) .ToDictionary(x => x.k, x => x.v); var scope = new CustomizedMemory(state, new SimpleObjectMemory(newScope)); try { result = evaluator.EvaluateTemplate(templateName, scope); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception err) #pragma warning restore CA1031 // Do not catch general exception types { error = err.Message; } } return(result, error); }, ReturnType.Object)); } } } return(this); }
/// <summary> /// Evaluate a template with given name and scope. /// </summary> /// <param name="inputTemplateName">template name.</param> /// <param name="scope">scope.</param> /// <returns>Evaluate result.</returns> public object EvaluateTemplate(string inputTemplateName, object scope) { if (!(scope is CustomizedMemory)) { scope = new CustomizedMemory(SimpleObjectMemory.Wrap(scope)); } (var reExecute, var templateName) = ParseTemplateName(inputTemplateName); if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(LGErrors.TemplateNotExist(templateName)); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"{LGErrors.LoopDetected} {string.Join(" => ", evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } var templateTarget = new EvaluationTarget(templateName, scope); var currentEvaluateId = templateTarget.GetId(); EvaluationTarget previousEvaluateTarget = null; if (evaluationTargetStack.Count != 0) { previousEvaluateTarget = evaluationTargetStack.Peek(); if (!reExecute && previousEvaluateTarget.EvaluatedChildren.ContainsKey(currentEvaluateId)) { return(previousEvaluateTarget.EvaluatedChildren[currentEvaluateId]); } } // Using a stack to track the evaluation trace evaluationTargetStack.Push(templateTarget); var result = Visit(TemplateMap[templateName].ParseTree); if (previousEvaluateTarget != null) { previousEvaluateTarget.EvaluatedChildren[currentEvaluateId] = result; } evaluationTargetStack.Pop(); return(result); }