From 2da7ea709289c6d1af074ea55eda9ba3289af480 Mon Sep 17 00:00:00 2001 From: homothetyhk <45406381+homothetyhk@users.noreply.github.com> Date: Sun, 5 Jun 2022 10:25:14 -0700 Subject: [PATCH] Add ReferenceToken. (#2) --- RandomizerCore/Logic/LogicManager.cs | 18 +++++++++++++++++- RandomizerCore/Logic/OptimizedLogicDef.cs | 5 +++++ RandomizerCore/StringLogic/DictPM.cs | 4 ++++ RandomizerCore/StringLogic/LogicProcessor.cs | 7 +++++++ RandomizerCore/StringLogic/LogicToken.cs | 8 ++++++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/RandomizerCore/Logic/LogicManager.cs b/RandomizerCore/Logic/LogicManager.cs index ac3c66c..35a2351 100644 --- a/RandomizerCore/Logic/LogicManager.cs +++ b/RandomizerCore/Logic/LogicManager.cs @@ -26,12 +26,15 @@ public class LogicManager : ILogicManager private readonly Dictionary _variableIndices; private readonly Dictionary _items; private readonly Dictionary _transitions; + private readonly LogicManagerBuilder _source; // set to null on exiting constructor + public VariableResolver VariableResolver { get; } public const int intVariableOffset = -100; public LogicManager(LogicManagerBuilder source) { + _source = source; LP = source.LP; VariableResolver = source.VariableResolver; @@ -76,6 +79,8 @@ public LogicManager(LogicManagerBuilder source) _items[kvp.Key] = kvp.Value; } ItemLookup = new(_items); + + _source = null; } public OptimizedLogicDef GetLogicDef(string name) @@ -219,7 +224,18 @@ private void ApplyToken(List logic, LogicToken lt) } else if (lt is MacroToken mt) { - foreach (var tt in mt.Value) ApplyToken(logic, tt); + foreach (LogicToken tt in mt.Value) ApplyToken(logic, tt); + } + else if (lt is ReferenceToken rt) + { + if (_logicDefs.TryGetValue(rt.Target, out OptimizedLogicDef o)) + { + OptimizedLogicDef.Concat(logic, o); + } + else if (_source != null && _source.LogicLookup.TryGetValue(rt.Target, out LogicClause lc)) + { + foreach (LogicToken tt in lc) ApplyToken(logic, tt); + } } else if (lt is SimpleToken st) { diff --git a/RandomizerCore/Logic/OptimizedLogicDef.cs b/RandomizerCore/Logic/OptimizedLogicDef.cs index 79a8270..427edb0 100644 --- a/RandomizerCore/Logic/OptimizedLogicDef.cs +++ b/RandomizerCore/Logic/OptimizedLogicDef.cs @@ -183,6 +183,11 @@ private void GetComparisonStrings(ref int i, out string left, out string right) right = logic[i] >= 0 ? lm.GetTerm(logic[i]).Name : lm.GetVariable(logic[i]).Name; } + internal static void Concat(List ts, OptimizedLogicDef o) + { + ts.AddRange(o.logic); + } + // cursed hacks below to make polymorphic deserialization work [JsonConstructor] private OptimizedLogicDef(string Name, string Logic) : this(Json.LogicDefConverter.Instance.LM.FromString(new(Name, Logic))) diff --git a/RandomizerCore/StringLogic/DictPM.cs b/RandomizerCore/StringLogic/DictPM.cs index aba471e..18aba5c 100644 --- a/RandomizerCore/StringLogic/DictPM.cs +++ b/RandomizerCore/StringLogic/DictPM.cs @@ -63,6 +63,10 @@ public override bool Evaluate(TermToken token) { return Evaluate(mt.Value); } + else if (token is ReferenceToken rt) + { + throw new NotSupportedException($"Unable to evaluate token: {rt}. DictPM does not store named logic references."); + } throw new ArgumentException($"Unable to evaluate TermToken: {token}"); } } diff --git a/RandomizerCore/StringLogic/LogicProcessor.cs b/RandomizerCore/StringLogic/LogicProcessor.cs index 7a1ce46..1b9d3f0 100644 --- a/RandomizerCore/StringLogic/LogicProcessor.cs +++ b/RandomizerCore/StringLogic/LogicProcessor.cs @@ -79,6 +79,13 @@ public TermToken GetTermToken(string name) if (globalTokens.TryGetValue(name, out LogicToken lt) || tokenPool.TryGetValue(name, out lt)) return (TermToken)lt; else { + if (name[0] == '*') + { + ReferenceToken rt = new(name[1..]); + tokenPool.Add(name, rt); + return rt; + } + TermToken tt = new SimpleToken(name); tokenPool.Add(name, tt); return tt; diff --git a/RandomizerCore/StringLogic/LogicToken.cs b/RandomizerCore/StringLogic/LogicToken.cs index 8a6d7cd..3beedcb 100644 --- a/RandomizerCore/StringLogic/LogicToken.cs +++ b/RandomizerCore/StringLogic/LogicToken.cs @@ -77,6 +77,14 @@ public record MacroToken(string Name, IMacroSource Source) : TermToken public LogicClause Value => Source.GetMacro(Name); } + /// + /// TermToken which represents a nested LogicClause by name. + /// + public record ReferenceToken(string Target) : TermToken + { + public override string Write() => $"*{Target}"; + } + /// /// TermToken which represents a constant bool. ///