feat: add ProgramVariable and ProgramVariableManager for macro variable declarations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
namespace OpenNest.Posts.Cincinnati
|
||||||
|
{
|
||||||
|
public sealed class ProgramVariable
|
||||||
|
{
|
||||||
|
public int Number { get; }
|
||||||
|
public string Name { get; }
|
||||||
|
public string Expression { get; set; }
|
||||||
|
|
||||||
|
public ProgramVariable(int number, string name, string expression = null)
|
||||||
|
{
|
||||||
|
Number = number;
|
||||||
|
Name = name;
|
||||||
|
Expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Reference => $"#{Number}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenNest.Posts.Cincinnati
|
||||||
|
{
|
||||||
|
public sealed class ProgramVariableManager
|
||||||
|
{
|
||||||
|
private readonly Dictionary<int, ProgramVariable> _variables = new();
|
||||||
|
|
||||||
|
public ProgramVariable GetOrCreate(string name, int number, string expression = null)
|
||||||
|
{
|
||||||
|
if (_variables.TryGetValue(number, out var existing))
|
||||||
|
return existing;
|
||||||
|
|
||||||
|
var variable = new ProgramVariable(number, name, expression);
|
||||||
|
_variables[number] = variable;
|
||||||
|
return variable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<string> EmitDeclarations()
|
||||||
|
{
|
||||||
|
return _variables.Values
|
||||||
|
.Where(v => v.Expression != null)
|
||||||
|
.OrderBy(v => v.Number)
|
||||||
|
.Select(v => $"{v.Reference}={v.Expression} ({FormatComment(v.Name)})")
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FormatComment(string name)
|
||||||
|
{
|
||||||
|
// "LeadInFeedrate" -> "LEAD IN FEEDRATE"
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var c in name)
|
||||||
|
{
|
||||||
|
if (char.IsUpper(c) && sb.Length > 0)
|
||||||
|
sb.Append(' ');
|
||||||
|
sb.Append(char.ToUpper(c));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using OpenNest.Posts.Cincinnati;
|
||||||
|
|
||||||
|
namespace OpenNest.Tests.Cincinnati;
|
||||||
|
|
||||||
|
public class ProgramVariableManagerTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void GetOrCreate_ReturnsNewVariable()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
var v = mgr.GetOrCreate("LeadInFeedrate", 126);
|
||||||
|
Assert.Equal(126, v.Number);
|
||||||
|
Assert.Equal("LeadInFeedrate", v.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetOrCreate_ReturnsSameVariable_WhenCalledTwice()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
var v1 = mgr.GetOrCreate("LeadInFeedrate", 126);
|
||||||
|
var v2 = mgr.GetOrCreate("LeadInFeedrate", 126);
|
||||||
|
Assert.Same(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetOrCreate_WithExpression_SetsExpression()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
var v = mgr.GetOrCreate("LeadInFeedrate", 126, "[#148*0.5]");
|
||||||
|
Assert.Equal("[#148*0.5]", v.Expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetOrCreate_WithLiteral_SetsExpression()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
var v = mgr.GetOrCreate("CircleFeedrate", 128, ".8");
|
||||||
|
Assert.Equal(".8", v.Expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Reference_ReturnsHashNumber()
|
||||||
|
{
|
||||||
|
var v = new ProgramVariable(126, "LeadInFeedrate");
|
||||||
|
Assert.Equal("#126", v.Reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EmitDeclarations_ProducesCorrectLines()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
mgr.GetOrCreate("LeadInFeedrate", 126, "[#148*0.5]");
|
||||||
|
mgr.GetOrCreate("CircleFeedrate", 128, ".8");
|
||||||
|
|
||||||
|
var lines = mgr.EmitDeclarations();
|
||||||
|
|
||||||
|
Assert.Contains("#126=[#148*0.5] (LEAD IN FEEDRATE)", lines);
|
||||||
|
Assert.Contains("#128=.8 (CIRCLE FEEDRATE)", lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EmitDeclarations_SkipsVariablesWithNoExpression()
|
||||||
|
{
|
||||||
|
var mgr = new ProgramVariableManager();
|
||||||
|
mgr.GetOrCreate("ProcessFeedrate", 148);
|
||||||
|
|
||||||
|
var lines = mgr.EmitDeclarations();
|
||||||
|
|
||||||
|
Assert.Empty(lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user