using Cryville.Common.Collections.Generic; using Cryville.Common.Pdt; using System; using System.Collections.Generic; using System.Reflection; namespace Cryville.Crtr.Ruleset { internal class RulesetInterpreter : PdtInterpreter { public RulesetInterpreter(string src, Binder binder) : base(src, binder) { } readonly List s = new(); readonly HashSet a = new(); protected override object InterpretKey(Type type) { if (PairCollection.IsPairCollection(type)) return InterpretJudgeAction(); else if (type == typeof(Constraint)) return InterpretConstraintKey(); else return base.InterpretKey(type); } object InterpretJudgeAction() { a.Clear(); while (true) { int pp = Position; switch (cc) { case '@': GetChar(); a.Add(GetIdentifier()); break; default: return JudgeAction.Construct(a, (string)base.InterpretKey(null)); } ws(); if (Position == pp) throw new FormatException("Invalid judge action format."); } } object InterpretConstraintKey() { s.Clear(); a.Clear(); string key = ""; while (true) { int pp = Position; switch (cc) { case '@': GetChar(); a.Add(GetIdentifier()); break; case '$': GetChar(); s.Add(new RulesetSelector.CreateItem()); key = null; break; case '#': GetChar(); s.Add(new RulesetSelector.Index()); break; case '>': GetChar(); s.Add(new RulesetSelector.Property(GetExp())); break; case ';': case ':': return new ConstraintKey(a.Contains("var") ? ConstraintType.Variable : ConstraintType.Property, key); case '{': return new RulesetSelectors(s); case '}': return null; default: var p4 = GetIdentifier(); s.Add(new RulesetSelector.EventType(p4)); if (key != null) key += p4; break; } ws(); if (Position == pp) throw new FormatException("Invalid selector or key format."); } } } }