From 491494600d858505a4d31c1b6687ded3ced50b55 Mon Sep 17 00:00:00 2001 From: Valerie Date: Sun, 31 Mar 2024 21:02:02 -0400 Subject: [PATCH] started transitioning RollExpression parsing into a tokenized oo approach --- Lexer.cs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Roll.cs | 44 ++++++++++++++++++++++++++++ Util.cs | 54 +---------------------------------- 3 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 Lexer.cs create mode 100644 Roll.cs diff --git a/Lexer.cs b/Lexer.cs new file mode 100644 index 0000000..ba96057 --- /dev/null +++ b/Lexer.cs @@ -0,0 +1,87 @@ +using System.Text.RegularExpressions; + +namespace Dungeoneer.Lexing { + + public abstract class Token { + + public virtual string Format() { return Expression(); } + public abstract string Expression(); + + } + + public class LiteralToken : Token { + public string Content { get; private set; } + + public LiteralToken(string text) { Content = text; } + + public override string Expression() { return Content; } + + } + + public class DiceToken : Token { + public int Count { get; private set; } + public int Sides { get; private set; } + private List _result = null; + public List Result { + get { + if(_result == null) { + _result = new List(); + for(int i = 0; i < Count; i++) + _result.Add(Util.Roll(Sides)); + } + return _result; + } + } + public int? _sum = null; + public int Sum { + get { + if(!_sum.HasValue) { + _sum = 0; + foreach(var roll in Result) + _sum += roll; + } + return _sum.Value; + } + } + + public DiceToken(int count, int sides) { + Count = count; + Sides = sides; + } + public DiceToken(Match match) { + Count = int.Parse(match.Groups[1].Value); + Sides = int.Parse(match.Groups[2].Value); + } + + private const string Style = "\x1b[34;1m"; + private static readonly Regex Pattern = new Regex(@"(\d+)d(\d+)"); + + public override string Format() { + var output = $"{Style}( "; + var result = Result; + for(int i = 0; i < Count; i++) + if(i < Count - 1) + output += $"{result[i]}, "; + else + output += $"{result[i]} ){Dungeoneer.Format.Reset}"; + return output; + } + public override string Expression() { return Sum.ToString(); } + + public static Match Match(string text) { return Pattern.Match(text); } + + } + + /*public class DcToken : Token { + + private const string Style = "\x1b[31m"; + private static readonly Regex Pattern = new Regex(@"dc\:(\d+)"); + + public static Match Match(string text) { return Pattern.Match(text); } + + public override string Expression() { return ""; } + + }*/ + +} + diff --git a/Roll.cs b/Roll.cs new file mode 100644 index 0000000..72a23c2 --- /dev/null +++ b/Roll.cs @@ -0,0 +1,44 @@ +using System.Security.Cryptography; +using System.Text.RegularExpressions; + +using Dungeoneer.Lexing; + +namespace Dungeoneer { + + public class RollExpression { + private IList Parts; + public string Print { get; private set; } + public string Expression { get; private set; } + public dynamic Result { + get { + try { return Scripting.Expr($"eval('{Expression}')"); } + catch { return null; } + } + } + + public RollExpression(IList parts) { + this.Parts = parts; + this.Print = ""; + this.Expression = ""; + + // build expression from string parts + foreach(string piece in Parts) { + // die expression substitution + var dieCheck = DiceToken.Match(piece); + if(dieCheck.Success) { + var token = new DiceToken(dieCheck); + + this.Print += $"{token.Format()} "; + this.Expression += $"{token.Expression()} "; + } else { + var part = $"{piece} "; + this.Expression += part; + this.Print += part; + } + } + } + + } + +} + diff --git a/Util.cs b/Util.cs index 52c89b8..a2b9346 100644 --- a/Util.cs +++ b/Util.cs @@ -1,5 +1,4 @@ using System.Security.Cryptography; -using System.Text.RegularExpressions; namespace Dungeoneer { @@ -11,57 +10,6 @@ namespace Dungeoneer { } - public class RollExpression { - private IList Parts; - public string Print { get; private set; } - public string Expression { get; private set; } - public dynamic Result { - get { - try { return Scripting.Expr($"eval('{Expression}')"); } - catch { return null; } - } - } - - private const string DieFormat = "\x1b[34;1m"; - private static readonly Regex DiePattern = new Regex(@"(\d+)d(\d+)"); - - public RollExpression(IList parts) { - this.Parts = parts; - this.Print = ""; - this.Expression = ""; - - // build expression from string parts - foreach(string piece in Parts) { - // die expression substitution - var dieCheck = DiePattern.Match(piece); - if(dieCheck.Success) { - // get /(d+)/ capture group values - var count = int.Parse(dieCheck.Groups[1].Value); - var sides = int.Parse(dieCheck.Groups[2].Value); - - // and build roll outcomes - this.Print += $"{DieFormat}( "; - this.Expression += "( "; - for(int i = 0; i < count; i++) { - var roll = Util.Roll(sides); - if(i < count - 1) { - this.Print += $"{roll}, "; - this.Expression += $"{roll} + "; - } else { - var part = $"{roll} "; - this.Print += $"{roll} ){Format.Reset} "; - this.Expression += $"{roll} ) "; - } - } - } else { - var part = $"{piece} "; - this.Expression += part; - this.Print += part; - } - } - } - - } - } +