From 817f1e413f0bcc26929e6fe8934de42f56ff6c2e Mon Sep 17 00:00:00 2001 From: homothetyhk Date: Sat, 2 Jul 2022 20:28:57 -0700 Subject: [PATCH] Fix StringLogic bugs. --- RandomizerCore/StringLogic/Infix.cs | 4 +++- RandomizerCore/StringLogic/RPN.cs | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/RandomizerCore/StringLogic/Infix.cs b/RandomizerCore/StringLogic/Infix.cs index 5c99568..77524c9 100644 --- a/RandomizerCore/StringLogic/Infix.cs +++ b/RandomizerCore/StringLogic/Infix.cs @@ -2,9 +2,11 @@ { public static class Infix { + private static readonly LogicProcessor _sharedTokenSource = new(); + public static List Tokenize(string infix) { - return Tokenize(infix, null); + return Tokenize(infix, _sharedTokenSource); } public static List Tokenize(string infix, ITokenSource tokenSource) diff --git a/RandomizerCore/StringLogic/RPN.cs b/RandomizerCore/StringLogic/RPN.cs index 03f195e..9965fe5 100644 --- a/RandomizerCore/StringLogic/RPN.cs +++ b/RandomizerCore/StringLogic/RPN.cs @@ -38,7 +38,7 @@ public static int GetBoundOperator(IReadOnlyList logic, int startInd else if (logic[index] is TermToken) operands++; else throw new ArgumentException("Unknown token found in logic.", nameof(logic)); - if (operands - operators == 1 && logic[index] is OperatorToken) break; + if (operands - operators <= 1 && logic[index] is OperatorToken) break; } if (index == logic.Count) throw new InvalidOperationException("Malformed logic."); @@ -74,9 +74,9 @@ internal static Range GetClauseRangeFromEnd(IReadOnlyList logic, int /// Returns the disjunctive normal form of the expression. That is, ///
ORing together the results of ANDing the terms in each list results in an expression equivalent to the input. /// - public static List> GetDNF(IReadOnlyList logic) + public static List> GetDNF(IReadOnlyList logic) { - Stack>> stack = new(); + Stack>> stack = new(); foreach (LogicToken lt in logic) { if (lt is OperatorToken ot) @@ -84,24 +84,24 @@ public static List> GetDNF(IReadOnlyList logic) switch (ot.OperatorType) { case OperatorType.AND: - List> andRight = stack.Pop(); - List> andLeft = stack.Pop(); - List> and = new(andRight.Count * andLeft.Count); + List> andRight = stack.Pop(); + List> andLeft = stack.Pop(); + List> and = new(andRight.Count * andLeft.Count); for (int i = 0; i < andRight.Count; i++) { for (int j = 0; j < andLeft.Count; j++) { - List c = new(andRight[i].Count + andLeft[j].Count); - c.AddRange(andLeft[j]); - c.AddRange(andRight[i]); + HashSet c = new(andRight[i].Count + andLeft[j].Count); + c.UnionWith(andLeft[j]); + c.UnionWith(andRight[i]); and.Add(c); } } stack.Push(and); break; case OperatorType.OR: - List> orRight = stack.Pop(); - List> orLeft = stack.Pop(); + List> orRight = stack.Pop(); + List> orLeft = stack.Pop(); orLeft.AddRange(orRight); stack.Push(orLeft); break;