Compare commits
No commits in common. "512c91d2de67d17ade5d71d62cd99da6cd090c88" and "4f276df6c1bec660f0d83e17c61baa8d957527b1" have entirely different histories.
512c91d2de
...
4f276df6c1
|
@ -10,7 +10,7 @@ namespace MultiversalDiplomacy.Model;
|
||||||
/// and other script inputs. It also provides helper functions to extract the captured order elements as tuples,
|
/// and other script inputs. It also provides helper functions to extract the captured order elements as tuples,
|
||||||
/// which function as the structured intermediate representation between raw user input and full Order objects.
|
/// which function as the structured intermediate representation between raw user input and full Order objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OrderParser(World world)
|
public class OrderRegex(World world)
|
||||||
{
|
{
|
||||||
public const string Type = "(A|F|Army|Fleet)";
|
public const string Type = "(A|F|Army|Fleet)";
|
||||||
|
|
||||||
|
@ -34,15 +34,6 @@ public class OrderParser(World world)
|
||||||
|
|
||||||
public const string ViaConvoy = "(convoy|via convoy|by convoy)";
|
public const string ViaConvoy = "(convoy|via convoy|by convoy)";
|
||||||
|
|
||||||
public Regex PowerCommand = new($"^{world.Map.PowerRegex}(?:[:])? (.*)$");
|
|
||||||
|
|
||||||
public static (
|
|
||||||
string power,
|
|
||||||
string command)
|
|
||||||
ParsePowerCommand(Match match) => (
|
|
||||||
match.Groups[1].Value,
|
|
||||||
match.Groups[2].Value);
|
|
||||||
|
|
||||||
public Regex Hold => new(
|
public Regex Hold => new(
|
||||||
$"^{UnitSpec} {HoldVerb}$",
|
$"^{UnitSpec} {HoldVerb}$",
|
||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
|
@ -206,7 +197,7 @@ public class OrderParser(World world)
|
||||||
|
|
||||||
public static bool TryParseOrder(World world, string power, string command, [NotNullWhen(true)] out Order? order) {
|
public static bool TryParseOrder(World world, string power, string command, [NotNullWhen(true)] out Order? order) {
|
||||||
order = null;
|
order = null;
|
||||||
OrderParser re = new(world);
|
OrderRegex re = new(world);
|
||||||
|
|
||||||
if (re.Hold.Match(command) is Match holdMatch && holdMatch.Success) {
|
if (re.Hold.Match(command) is Match holdMatch && holdMatch.Success) {
|
||||||
return TryParseHoldOrder(world, power, holdMatch, out order);
|
return TryParseHoldOrder(world, power, holdMatch, out order);
|
|
@ -36,7 +36,8 @@ public class AdjudicationQueryScriptHandler(World world, bool strict = false) :
|
||||||
|
|
||||||
case "assert":
|
case "assert":
|
||||||
string assertion = input["assert ".Length..];
|
string assertion = input["assert ".Length..];
|
||||||
Regex prov = new($"{World.Map.ProvinceRegex} (.*)");
|
OrderRegex re = new(World);
|
||||||
|
Regex prov = new($"{re.Province} (.*)");
|
||||||
Match match = prov.Match(assertion);
|
Match match = prov.Match(assertion);
|
||||||
if (!match.Success) {
|
if (!match.Success) {
|
||||||
Console.WriteLine($"Could not parse province from \"{assertion}\"");
|
Console.WriteLine($"Could not parse province from \"{assertion}\"");
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class GameScriptHandler(World world, bool strict = false) : IScriptHandle
|
||||||
orderText = match.Groups[2].Value;
|
orderText = match.Groups[2].Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OrderParser.TryParseOrder(World, orderPower, orderText, out Order? order)) {
|
if (OrderRegex.TryParseOrder(World, orderPower, orderText, out Order? order)) {
|
||||||
Console.WriteLine($"Parsed {orderPower} order \"{orderText}\" but doing anything with it isn't implemented yet");
|
Console.WriteLine($"Parsed {orderPower} order \"{orderText}\" but doing anything with it isn't implemented yet");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class SetupScriptHandler(World world, bool strict = false) : IScriptHandl
|
||||||
|
|
||||||
case "unit":
|
case "unit":
|
||||||
string unitSpec = input["unit ".Length..];
|
string unitSpec = input["unit ".Length..];
|
||||||
if (OrderParser.TryParseUnit(World, unitSpec, out Unit? newUnit)) {
|
if (OrderRegex.TryParseUnit(World, unitSpec, out Unit? newUnit)) {
|
||||||
World = World.Update(units: World.Units.Append(newUnit));
|
World = World.Update(units: World.Units.Append(newUnit));
|
||||||
Console.WriteLine($"Created {newUnit}");
|
Console.WriteLine($"Created {newUnit}");
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -41,10 +41,10 @@ public class RegexTest
|
||||||
[TestCaseSource(nameof(HoldRegexMatchesTestCases))]
|
[TestCaseSource(nameof(HoldRegexMatchesTestCases))]
|
||||||
public void HoldRegexMatches(string order, string[] expected)
|
public void HoldRegexMatches(string order, string[] expected)
|
||||||
{
|
{
|
||||||
OrderParser re = new(World.WithStandardMap());
|
OrderRegex re = new(World.WithStandardMap());
|
||||||
var match = re.Hold.Match(order);
|
var match = re.Hold.Match(order);
|
||||||
Assert.True(match.Success, "Match failed");
|
Assert.True(match.Success, "Match failed");
|
||||||
var (type, timeline, province, location, turn, holdVerb) = OrderParser.ParseHold(match);
|
var (type, timeline, province, location, turn, holdVerb) = OrderRegex.ParseHold(match);
|
||||||
string[] actual = [type, timeline, province, location, turn, holdVerb];
|
string[] actual = [type, timeline, province, location, turn, holdVerb];
|
||||||
// Use EquivalentTo for more detailed error message
|
// Use EquivalentTo for more detailed error message
|
||||||
Assert.That(actual, Is.EquivalentTo(expected), "Unexpected parse results");
|
Assert.That(actual, Is.EquivalentTo(expected), "Unexpected parse results");
|
||||||
|
@ -94,11 +94,11 @@ public class RegexTest
|
||||||
[TestCaseSource(nameof(MoveRegexMatchesTestCases))]
|
[TestCaseSource(nameof(MoveRegexMatchesTestCases))]
|
||||||
public void MoveRegexMatches(string order, string[] expected)
|
public void MoveRegexMatches(string order, string[] expected)
|
||||||
{
|
{
|
||||||
OrderParser re = new(World.WithStandardMap());
|
OrderRegex re = new(World.WithStandardMap());
|
||||||
var match = re.Move.Match(order);
|
var match = re.Move.Match(order);
|
||||||
Assert.True(match.Success, "Match failed");
|
Assert.True(match.Success, "Match failed");
|
||||||
var (type, timeline, province, location, turn, moveVerb,
|
var (type, timeline, province, location, turn, moveVerb,
|
||||||
destTimeline, destProvince, destLocation, destTurn, viaConvoy) = OrderParser.ParseMove(match);
|
destTimeline, destProvince, destLocation, destTurn, viaConvoy) = OrderRegex.ParseMove(match);
|
||||||
string[] actual = [type, timeline, province, location, turn, moveVerb,
|
string[] actual = [type, timeline, province, location, turn, moveVerb,
|
||||||
destTimeline, destProvince, destLocation, destTurn, viaConvoy];
|
destTimeline, destProvince, destLocation, destTurn, viaConvoy];
|
||||||
// Use EquivalentTo for more detailed error message
|
// Use EquivalentTo for more detailed error message
|
||||||
|
@ -145,11 +145,11 @@ public class RegexTest
|
||||||
[TestCaseSource(nameof(SupportHoldRegexMatchesTestCases))]
|
[TestCaseSource(nameof(SupportHoldRegexMatchesTestCases))]
|
||||||
public void SupportHoldRegexMatches(string order, string[] expected)
|
public void SupportHoldRegexMatches(string order, string[] expected)
|
||||||
{
|
{
|
||||||
OrderParser re = new(World.WithStandardMap());
|
OrderRegex re = new(World.WithStandardMap());
|
||||||
var match = re.SupportHold.Match(order);
|
var match = re.SupportHold.Match(order);
|
||||||
Assert.True(match.Success, "Match failed");
|
Assert.True(match.Success, "Match failed");
|
||||||
var (type, timeline, province, location, turn, supportVerb,
|
var (type, timeline, province, location, turn, supportVerb,
|
||||||
targetType, targetTimeline, targetProvince, targetLocation, targetTurn) = OrderParser.ParseSupportHold(match);
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn) = OrderRegex.ParseSupportHold(match);
|
||||||
string[] actual = [type, timeline, province, location, turn, supportVerb,
|
string[] actual = [type, timeline, province, location, turn, supportVerb,
|
||||||
targetType, targetTimeline, targetProvince, targetLocation, targetTurn];
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn];
|
||||||
// Use EquivalentTo for more detailed error message
|
// Use EquivalentTo for more detailed error message
|
||||||
|
@ -184,12 +184,12 @@ public class RegexTest
|
||||||
[TestCaseSource(nameof(SupportMoveRegexMatchesTestCases))]
|
[TestCaseSource(nameof(SupportMoveRegexMatchesTestCases))]
|
||||||
public void SupportMoveRegexMatches(string order, string[] expected)
|
public void SupportMoveRegexMatches(string order, string[] expected)
|
||||||
{
|
{
|
||||||
OrderParser re = new(World.WithStandardMap());
|
OrderRegex re = new(World.WithStandardMap());
|
||||||
var match = re.SupportMove.Match(order);
|
var match = re.SupportMove.Match(order);
|
||||||
Assert.True(match.Success, "Match failed");
|
Assert.True(match.Success, "Match failed");
|
||||||
var (type, timeline, province, location, turn, supportVerb,
|
var (type, timeline, province, location, turn, supportVerb,
|
||||||
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
||||||
destTimeline, destProvince, destLocation, destTurn) = OrderParser.ParseSupportMove(match);
|
destTimeline, destProvince, destLocation, destTurn) = OrderRegex.ParseSupportMove(match);
|
||||||
string[] actual = [type, timeline, province, location, turn, supportVerb,
|
string[] actual = [type, timeline, province, location, turn, supportVerb,
|
||||||
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
targetType, targetTimeline, targetProvince, targetLocation, targetTurn, moveVerb,
|
||||||
destTimeline, destProvince, destLocation, destTurn];
|
destTimeline, destProvince, destLocation, destTurn];
|
||||||
|
@ -202,10 +202,10 @@ public class RegexTest
|
||||||
public void OrderParsingTest()
|
public void OrderParsingTest()
|
||||||
{
|
{
|
||||||
World world = World.WithStandardMap().AddUnits("Germany A Mun");
|
World world = World.WithStandardMap().AddUnits("Germany A Mun");
|
||||||
OrderParser re = new(world);
|
OrderRegex re = new(world);
|
||||||
|
|
||||||
var match = re.Move.Match("A Mun - Tyr");
|
var match = re.Move.Match("A Mun - Tyr");
|
||||||
var success = OrderParser.TryParseMoveOrder(world, "Germany", match, out Order? order);
|
var success = OrderRegex.TryParseMoveOrder(world, "Germany", match, out Order? order);
|
||||||
|
|
||||||
Assert.That(success, Is.True);
|
Assert.That(success, Is.True);
|
||||||
Assert.That(order, Is.TypeOf<MoveOrder>());
|
Assert.That(order, Is.TypeOf<MoveOrder>());
|
|
@ -1,51 +0,0 @@
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
using MultiversalDiplomacy.Script;
|
|
||||||
|
|
||||||
namespace MultiversalDiplomacyTests;
|
|
||||||
|
|
||||||
public class ReplDriver(IScriptHandler initialHandler, bool echo = false)
|
|
||||||
{
|
|
||||||
public IScriptHandler? Handler { get; private set; } = initialHandler;
|
|
||||||
|
|
||||||
private string? LastInput { get; set; } = "";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether to print the inputs as they are executed. This is primarily a debugging aid.
|
|
||||||
/// </summary>
|
|
||||||
bool Echo { get; } = echo;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Input a multiline string into the repl. Call <see cref="Ready"/> or <see cref="Closed"/> at the end so the
|
|
||||||
/// statement is valid.
|
|
||||||
/// </summary>
|
|
||||||
public ReplDriver this[string input] => ExecuteAll(input);
|
|
||||||
|
|
||||||
public ReplDriver ExecuteAll(string multiline)
|
|
||||||
{
|
|
||||||
var lines = multiline.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
|
||||||
return lines.Aggregate(this, (repl, line) => repl.Execute(line));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReplDriver Execute(string inputLine)
|
|
||||||
{
|
|
||||||
if (Handler is null) throw new AssertionException(
|
|
||||||
$"Cannot execute \"{inputLine}\", handler quit. Last input was \"{LastInput}\"");
|
|
||||||
if (Echo) Console.WriteLine($"{Handler.Prompt}{inputLine}");
|
|
||||||
|
|
||||||
Handler = Handler.HandleInput(inputLine);
|
|
||||||
LastInput = inputLine;
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Ready()
|
|
||||||
{
|
|
||||||
Assert.That(Handler, Is.Not.Null, "Handler is closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Closed()
|
|
||||||
{
|
|
||||||
Assert.That(Handler, Is.Null, "Handler is not closed");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
using MultiversalDiplomacy.Model;
|
|
||||||
using MultiversalDiplomacy.Script;
|
|
||||||
|
|
||||||
namespace MultiversalDiplomacyTests;
|
|
||||||
|
|
||||||
public class ReplTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void SetupHandler()
|
|
||||||
{
|
|
||||||
SetupScriptHandler setup = new(World.WithStandardMap(), strict: true);
|
|
||||||
ReplDriver repl = new(setup);
|
|
||||||
|
|
||||||
repl["""
|
|
||||||
unit Germany A Munich
|
|
||||||
unit Austria Army Tyrolia
|
|
||||||
unit England F London
|
|
||||||
"""].Ready();
|
|
||||||
|
|
||||||
Assert.That(repl.Handler, Is.TypeOf<SetupScriptHandler>());
|
|
||||||
SetupScriptHandler handler = (SetupScriptHandler)repl.Handler!;
|
|
||||||
Assert.That(handler.World.Units.Count, Is.EqualTo(3));
|
|
||||||
Assert.That(handler.World.GetUnitAt("Mun"), Is.Not.Null);
|
|
||||||
Assert.That(handler.World.GetUnitAt("Tyr"), Is.Not.Null);
|
|
||||||
Assert.That(handler.World.GetUnitAt("Lon"), Is.Not.Null);
|
|
||||||
|
|
||||||
repl["""
|
|
||||||
---
|
|
||||||
"""].Ready();
|
|
||||||
|
|
||||||
Assert.That(repl.Handler, Is.TypeOf<GameScriptHandler>());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue