/// <summary> /// Expand the results of a template with given name and scope. /// Throws errors if certain errors detected <see cref="TemplateErrors"/>. /// </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) { var memory = scope is CustomizedMemory scopeMemory ? scopeMemory : new CustomizedMemory(scope); if (!TemplateMap.ContainsKey(templateName)) { throw new ArgumentException(TemplateErrors.TemplateNotExist(templateName)); } var templateTarget = new EvaluationTarget(templateName, memory); var currentEvaluateId = templateTarget.GetId(); if (_evaluationTargetStack.Any(e => e.GetId() == currentEvaluateId)) { throw new InvalidOperationException($"{TemplateErrors.LoopDetected} {string.Join(" => ", _evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } // Using a stack to track the evaluation trace _evaluationTargetStack.Push(templateTarget); 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); }
/// <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); }
/// <summary> /// Evaluate a template with given name and scope. /// Throws errors if certain errors detected <see cref="TemplateErrors"/>. /// </summary> /// <param name="inputTemplateName">Template name.</param> /// <param name="scope">Scope.</param> /// <returns>Evaluate result.</returns> public object EvaluateTemplate(string inputTemplateName, object scope) { var memory = scope is CustomizedMemory scopeMemory ? scopeMemory : new CustomizedMemory(scope); (var reExecute, var templateName) = ParseTemplateName(inputTemplateName); if (!TemplateMap.ContainsKey(templateName)) { throw new Exception(TemplateErrors.TemplateNotExist(templateName)); } var templateTarget = new EvaluationTarget(templateName, memory); var currentEvaluateId = templateTarget.GetId(); if (_evaluationTargetStack.Any(e => e.GetId() == currentEvaluateId)) { throw new Exception($"{TemplateErrors.LoopDetected} {string.Join(" => ", _evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } 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(); return(result); }
public object EvaluateTemplate(string templateName, object scope) { if (!TemplateMap.ContainsKey(templateName)) { throw new Exception($"[{templateName}] not found"); } if (evaluationTargetStack.Any(e => e.TemplateName == templateName)) { throw new Exception($"Loop detected: {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 (previousEvaluateTarget.EvaluatedChildren.ContainsKey(currentEvaluateId)) { return(previousEvaluateTarget.EvaluatedChildren[currentEvaluateId]); } } // Using a stack to track the evalution trace evaluationTargetStack.Push(templateTarget); var result = Visit(TemplateMap[templateName].ParseTree); if (previousEvaluateTarget != null) { previousEvaluateTarget.EvaluatedChildren.Add(currentEvaluateId, result); } evaluationTargetStack.Pop(); return(result); }
/// <summary> /// Evaluate a template with given name and scope. /// Throws errors if certain errors detected <see cref="TemplateErrors"/>. /// </summary> /// <param name="inputTemplateName">Template name.</param> /// <param name="scope">Scope.</param> /// <returns>Evaluate result.</returns> public object EvaluateTemplate(string inputTemplateName, object scope) { var memory = scope is CustomizedMemory scopeMemory ? scopeMemory : new CustomizedMemory(scope); (var reExecute, var templateName) = ParseTemplateName(inputTemplateName); if (!TemplateMap.ContainsKey(templateName)) { throw new ArgumentException(TemplateErrors.TemplateNotExist(templateName)); } var templateTarget = new EvaluationTarget(templateName, memory); var currentEvaluateId = templateTarget.GetId(); if (_evaluationTargetStack.Any(e => e.GetId() == currentEvaluateId)) { throw new InvalidOperationException($"{TemplateErrors.LoopDetected} {string.Join(" => ", _evaluationTargetStack.Reverse().Select(e => e.TemplateName))} => {templateName}"); } object result = null; var hasResult = false; if (!reExecute) { if (_lgOptions.CacheScope == LGCacheScope.Global) { if (_cachedResult.ContainsKey(currentEvaluateId)) { result = _cachedResult[currentEvaluateId]; hasResult = true; } } else if (_lgOptions.CacheScope == null || _lgOptions.CacheScope == LGCacheScope.Local) { EvaluationTarget previousEvaluateTarget = null; if (CurrentTemplate() != null) { previousEvaluateTarget = CurrentTarget(); if (previousEvaluateTarget.CachedEvaluatedChildren.ContainsKey(currentEvaluateId)) { result = previousEvaluateTarget.CachedEvaluatedChildren[currentEvaluateId]; hasResult = true; } } } } if (!hasResult) { _evaluationTargetStack.Push(templateTarget); var currentTemplate = CurrentTemplate(); _lgOptions.OnEvent?.Invoke(currentTemplate, new BeginTemplateEvaluationArgs { Source = currentTemplate.SourceRange.Source, TemplateName = templateName }); result = Visit(TemplateMap[templateName].TemplateBodyParseTree); if (_lgOptions.OnEvent != null) { var text = $"Evaluate template [{templateName}] get result: {result}"; _lgOptions.OnEvent(currentTemplate, new MessageArgs { Source = currentTemplate.SourceRange.Source, Text = text }); } _evaluationTargetStack.Pop(); if (!reExecute) { if (_lgOptions.CacheScope == LGCacheScope.Global) { _cachedResult[currentEvaluateId] = result; } else if (_lgOptions.CacheScope == null || _lgOptions.CacheScope == LGCacheScope.Local) { if (_evaluationTargetStack.Count > 0) { _evaluationTargetStack.Peek().CachedEvaluatedChildren[currentEvaluateId] = result; } } } } return(result); }