using GDWeave.Godot; using Teemaw.Calico.Util; using static GDWeave.Godot.TokenType; namespace Teemaw.Calico.LexicalTransformer; using MultiTokenPattern = Func[]; public static class TransformationPatternFactory { /// /// Creates a new pattern array which matches `extends <Identifier>\n`. Useful for patching into the global /// scope. /// /// public static MultiTokenPattern CreateGlobalsPattern() { return [ t => t.Type is PrExtends, t => t.Type is Identifier, t => t.Type is Newline ]; } /// /// Creates a new pattern array which matches a function definition. This will not match the preceding or trailing /// Newline tokens. /// /// The name of the function to match. /// /// An array of the names of arguments of the function to match. If null or empty, the returned checks will only /// match a function which does not accept arguments. /// /// public static MultiTokenPattern CreateFunctionDefinitionPattern(string name, string[]? args = null) { var checks = new List>(); checks.Add(t => t.Type is PrFunction); checks.Add(t => t is IdentifierToken token && token.Name == name); checks.Add(t => t.Type is ParenthesisOpen); if (args is { Length: > 0 }) { foreach (var arg in args) { checks.Add(t => t is IdentifierToken token && token.Name == arg); checks.Add(t => t.Type is Comma); } checks.RemoveAt(checks.Count - 1); } checks.Add(t => t.Type is ParenthesisClose); checks.Add(t => t.Type is Colon); return checks.ToArray(); } /// /// Creates a new pattern array which matches the provided GDScript snippet. /// /// A GDScript snippet to match. /// The base indent of the snippet. /// public static MultiTokenPattern CreateGdSnippetPattern(string snippet, uint indent = 0) { var tokens = ScriptTokenizer.Tokenize(snippet, indent); return tokens.Select(snippetToken => (Func)(t => { if (t.Type == Identifier) { return snippetToken is IdentifierToken snippetIdentifier && t is IdentifierToken identifier && snippetIdentifier.Name == identifier.Name; } if (t.Type == Constant) { return snippetToken is ConstantToken snippetConstant && t is ConstantToken constant && snippetConstant.Value.Equals(constant.Value); } return t.Type == snippetToken.Type; })).ToArray(); } }