diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 0000000..4d0b366 --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,25 @@ +These people have all supported the development of this project at some point; +be it financially, by offering skills/knowledge, or some other way. +Thank you. + +## Contributors + +### Programmers +- Andrew Rogers ([@cpancake](https://github.com/cpancake)) +- Santeri Kasvi ([@Spanfile](https://github.com/Spanfile)) + +### Localization +- Tamme Schichler ([@Tamschi](https://github.com/Tamschi)) + +## Financial Support + +- [Michael Nielsen](https://twitter.com/Nosteme) + +### Patreon ($5 or more pledged) + +- [Pål Trefall](https://www.patreon.com/user/creators?u=4929142) ([@ptrefall](https://github.com/ptrefall)) +- [Key Wraith](https://www.patreon.com/user/creators?u=4336045) + +## Special Thanks + +- [@voraciousviolet](https://github.com/voraciousviolet) - _Offered valuable ideas and support in the early stages of the project, as well as for its predecessor, the "Moist Banana" story generator._ diff --git a/CmdLine.cs b/CmdLine.cs index 336a5b1..349cf44 100644 --- a/CmdLine.cs +++ b/CmdLine.cs @@ -6,7 +6,7 @@ namespace Rant.Common { internal static class CmdLine { - private static readonly Dictionary Arguments = new Dictionary(); + private static readonly Dictionary> Arguments = new Dictionary>(); private static readonly HashSet Flags = new HashSet(); private static readonly List Paths = new List(); @@ -33,7 +33,14 @@ static CmdLine() { if (isProperty) { - Arguments[args[i - 1].TrimStart('-')] = args[i]; + var name = args[i - 1].TrimStart('-'); + if (Arguments.ContainsKey(name)) + Arguments[name].Add(args[i]); + else + { + Arguments[name] = new List(); + Arguments[name].Add(args[i]); + } isProperty = false; } else if (args[i].StartsWith("--")) @@ -55,20 +62,26 @@ static CmdLine() public static string Property(string name) { - string arg; - if (!Arguments.TryGetValue(name.ToLower(), out arg)) + List args; + if (!Arguments.TryGetValue(name.ToLower(), out args)) { - arg = ""; + return ""; } - return arg; + return args.First(); } public static string Property(string name, string defaultValue) { - string arg; - return !Arguments.TryGetValue(name.ToLower(), out arg) ? defaultValue : arg; + List args; + return !Arguments.TryGetValue(name.ToLower(), out args) ? defaultValue : args.First(); } + public static IEnumerable Properties(string name) + { + List args; + return Arguments.TryGetValue(name.ToLower(), out args) ? args : new List(); + } + public static bool Flag(string name) => Flags.Contains(name); } } diff --git a/LICENSE b/LICENSE index 39c95fc..efcc2bc 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Nicholas Fleck +Copyright (c) 2014-present Nicholas Fleck Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 4417c83..2eb179a 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,35 @@

-Rant logo +Rant logo

+
-

- - Build status - - - - Build status - - -

- -##What is Rant? - -Rant is a language for procedurally generating text, written in C#. It combines a markup language with functional and imperative programming concepts to deliver a powerful, but easy-to-use tool for adding rich variations to your text. The ultimate goal of Rant is to augment your creativity with the boundless potential of randomness, helping you consider your next great idea as not just a static concept, but a seed for countless possibilities. +**Rant** is an all-purpose procedural text engine +that is most simply described as the opposite of Regex. +It has been refined to include a dizzying array of features for handling everything from +the most basic of string generation tasks to advanced dialogue generation, +code templating, automatic formatting, and more. -[berkin.me/rant](http://berkin.me/rant) +The goal of the project is to enable developers of all kinds +to automate repetitive writing tasks with a high degree of creative freedom. -##Features of Rant +## Features -* Recursive, weighted branching with customizable selection strategies -* Dictionary queries -* Automation for capitalization, rhyming, and indefinite articles -* Multiple output support -* Richard, an experimental embedded scripting language -* Probability modifiers -* Loops, conditionals, and subroutines -* Package loader for easy resource management -* Unmanaged function exports for use in C/C++ applications *(Windows only, sorry!)* -* Compatible with Unity -* **And a whole lot more!** +* Recursive, weighted branching with several selection modes +* Queryable dictionaries +* Automatic capitalization, rhyming, English indefinite articles, and multi-lingual number verbalization +* Print to multiple separate outputs +* Probability modifiers for pattern elements +* Loops, conditional statements, and subroutines +* Fully-functional object model +* Import/Export resources easily with the .rantpkg format +* Compatible with Unity 2017 +* *And much, much, much more...* -##Examples +## Examples -**Fill in the blanks** +**Liven up a narrative with a few simple queries.** ``` - likes to with pet on . + likes to with pet on . ``` ``` Alick likes to mount shuttlecocks with his pet bat on Mondays. @@ -45,12 +37,12 @@ Alick likes to mount shuttlecocks with his pet bat on Mondays. --- -**Generate ten random numbers between 1 and 50 and spell them out** +**Count to ten and spell it out.** ``` -[case:sentence][numfmt:verbal-en][rep:10][sep:\s]{[num:1;50].} +[case:sentence][numfmt:verbal][rs:10;\s]{[rn].} ``` ``` -Four. Ten. Thirteen. Fifteen. Eighteen. Twenty four. Seven. Forty eight. Nineteen. Twenty five. +One. Two. Three. Four. Five. Six. Seven. Eight. Nine. Ten. ``` --- @@ -69,68 +61,50 @@ The drug dug the smug plug. --- -**?????** -``` -[rs:16;\N] -{ - [r:50]{([rr])\u2593|([re])\s} -} -``` -``` -▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓ ▓▓▓▓ ▓ ▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓ ▓▓▓ ▓ ▓ -▓▓▓▓▓▓ ▓▓▓▓▓ ▓ ▓▓▓ ▓ ▓ ▓ ▓▓▓▓ ▓▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓ ▓ ▓ ▓▓ ▓▓ ▓▓ -▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓ ▓▓ ▓ ▓ ▓ ▓ ▓ ▓▓▓▓ ▓ -▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓ ▓ ▓ ▓▓ -▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓ ▓▓ ▓▓▓ ▓ ▓ ▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓ ▓▓ ▓▓▓▓ ▓▓▓ ▓ -▓▓▓▓▓▓▓▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓ ▓ -▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓ ▓▓ -▓▓▓▓▓▓▓▓▓▓ ▓ ▓ ▓▓ ▓ ▓▓▓▓▓▓▓ ▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓▓ ▓ ▓▓ ▓▓▓ ▓▓▓▓▓ ▓ ▓▓ -▓▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓ ▓ ▓▓▓ ▓ ▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓ ▓▓ ▓▓▓ ▓▓ ▓ -▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓ ▓ ▓ ▓ -▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓ ▓ ▓▓▓ ▓ -``` +## NuGet +Rant is also available as a [NuGet package](https://www.nuget.org/packages/Rant/). +Enter this command in your package manager, +and the latest version of Rant will automagically get installed in your project: -##NuGet -Rant is also available as a [NuGet package](https://www.nuget.org/packages/Rant/). Punch the following into your package manager console and smash the Enter key enthusiastically to get it: ``` PM> Install-Package Rant ``` + Or if development builds are your thing: + ``` PM> Install-Package Rant -Pre ``` -But remember, the latest version will always be available on the repository first. - -##License +## License Rant is provided under [The MIT License](https://github.com/TheBerkin/Rant/blob/master/LICENSE). -##Improve Rant -If there is something you want fixed, added, or changed, feel free to submit an issue/pull request. You are welcome to help with any of the following: -* Documentation -* Fixing bugs -* Optimization -* New functions -* New language features -* Improving old language features -* New API features -* Formatting support for other cultures - -##Learn Rant -See [berkin.me/rantdocs](http://berkin.me/rantdocs) for full documentation of the API and Rant language, as well as additional example code. - -##Support Rant -If you love my work and want to support it by donating, you can do so [here](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&encrypted=-----BEGIN+PKCS7-----MIIHFgYJKoZIhvcNAQcEoIIHBzCCBwMCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYCnAa5a%2BlNDRPC3XmQ9m0fiEQcJzDJ0ukikmnDuVGFs%2BrGHX23SXuDeWT8v7FOAPu6Rdipva1soJIjJTUuk0HiEzwPAiSVjkV%2Fj8NSlcbPNnSyHEmiE7%2BDzKpJBGGA4WH8gwbtDUQ%2Be9ILdjUJIZ2KSwcWwbxexk0QP%2BAHKQ0i4xTELMAkGBSsOAwIaBQAwgZMGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIshT08dOlnw2AcGtKUFBUobeoq2XmJHDzw42kMkNWgad2zWdpmoL75wRaCKYjBDGX1MVw9NE5agB8QJfBdrNYZLZPB2i5lKBA%2BPccoi4c9us%2FSVLoNGffwTlY7dNvP%2F1EP0u%2BU3pX2X8e7JBjjcu%2FrdqyQJ5xJf8vGv%2BgggOHMIIDgzCCAuygAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20wHhcNMDQwMjEzMTAxMzE1WhcNMzUwMjEzMTAxMzE1WjCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMFHTt38RMxLXJyO2SmS%2BNdl72T7oKJ4u4uw%2B6awntALWh03PewmIJuzbALScsTS4sZoS1fKciBGoh11gIfHzylvkdNe%2FhJl66%2FRGqrj5rFb08sAABNTzDTiqqNpJeBsYs%2Fc2aiGozptX2RlnBktH%2BSUNpAajW724Nv2Wvhif6sFAgMBAAGjge4wgeswHQYDVR0OBBYEFJaffLvGbxe9WT9S1wob7BDWZJRrMIG7BgNVHSMEgbMwgbCAFJaffLvGbxe9WT9S1wob7BDWZJRroYGUpIGRMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbYIBADAMBgNVHRMEBTADAQH%2FMA0GCSqGSIb3DQEBBQUAA4GBAIFfOlaagFrl71%2Bjq6OKidbWFSE%2BQ4FqROvdgIONth%2B8kSK%2F%2FY%2F4ihuE4Ymvzn5ceE3S%2FiBSQQMjyvb%2Bs2TWbQYDwcp129OPIbD9epdr4tJOUNiSojw7BHwYRiPh58S1xGlFgHFXwrEBb3dgNbMUa%2Bu4qectsMAXpVHnD9wIyfmHMYIBmjCCAZYCAQEwgZQwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tAgEAMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNTA2MjYwMzI3MjdaMCMGCSqGSIb3DQEJBDEWBBS8ixZRspLeAGmBXnwP4OjcWr228TANBgkqhkiG9w0BAQEFAASBgHnORUb9B9jxH0olsERVeNBf9hok18rGVNIvIedgiojMKSQb13UsNbN4ys%2BWln4OsOhcNh%2FKo2UthrwEB0gZEVNnD6%2BuDL1ogyFAadA3VNHrni7H7iCk3WrgsxgIynHGV68yAOqbcwp8WizAR%2BlHTaxRaZ2jwQ2O%2FRVI%2FkJ34QGs-----END+PKCS7-----%0A++++++++). Donating isn't required, but it's much appreciated! - -##Other projects -If you like Rant, you may also like these other, Rant-related projects: -* [**RIDE**](http://github.com/RantLang/RIDE): The official (and highly WIP) Rant IDE -* [**Rantionary**](http://github.com/TheBerkin/Rantionary): The official Rant dictionary - -:squirrel: +## Improve Rant +If there is something you want fixed, added, or changed, feel free to submit an issue/pull request; I will try to get back to you within a day. If you would like to translate Rant into your native language, simply write a .lang file for it [like this one here](https://github.com/TheBerkin/Rant/blob/dev-3.0/Rant/Localization/en-US.lang). + +## Rant Resources +* [Rant Homepage](http://berkin.me/rant) +* [Rant Documentation](http://berkin.me/rantdocs) +* [Rantionary - Rant Standard Dictionary](https://github.com/TheBerkin/Rantionary) + +## Build Status + + + Build status + +
+ + Build status + + +## Support My Projects +
+

+ +

+ +If you love my work, please consider supporting me on [Patreon](https://patreon.com/Berkin). Alternatively, I also accept donations through [PayPal](http://paypal.me/nicholasfleck). +Donations help me make projects like Rant even better. Thank you. + + diff --git a/Rave/App.config b/Rant.Benchmark/App.config similarity index 91% rename from Rave/App.config rename to Rant.Benchmark/App.config index 8e15646..88fa402 100644 --- a/Rave/App.config +++ b/Rant.Benchmark/App.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/Rave/CmdLine.cs b/Rant.Benchmark/CmdLine.cs similarity index 80% rename from Rave/CmdLine.cs rename to Rant.Benchmark/CmdLine.cs index 5762de2..336a5b1 100644 --- a/Rave/CmdLine.cs +++ b/Rant.Benchmark/CmdLine.cs @@ -2,15 +2,18 @@ using System.Collections.Generic; using System.Linq; -namespace Rave +namespace Rant.Common { internal static class CmdLine { private static readonly Dictionary Arguments = new Dictionary(); private static readonly HashSet Flags = new HashSet(); private static readonly List Paths = new List(); - - public static readonly string Command = String.Empty; + + /// + /// Determines whether the user specified a question mark as the argument. + /// + public static readonly bool Help; static CmdLine() { @@ -18,11 +21,15 @@ static CmdLine() int argc = args.Length; if (argc == 0) return; - Command = args[0].ToLower().Trim(); + if (argc == 1 && args[0] == "?") + { + Help = true; + return; + } - bool isProperty = false; + bool isProperty = false; - for (int i = 1; i < args.Length; i++) + for (int i = 0; i < args.Length; i++) { if (isProperty) { diff --git a/Rant.Benchmark/Program.cs b/Rant.Benchmark/Program.cs new file mode 100644 index 0000000..9f43acc --- /dev/null +++ b/Rant.Benchmark/Program.cs @@ -0,0 +1,94 @@ +using Rant.Vocabulary; +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.ExceptionServices; +using static Rant.Common.CmdLine; + +namespace Rant.Benchmark +{ + class Program + { + public static readonly string PKG_PATH = Property("package"); + public static readonly int ITERATIONS; + + static Program() + { + if (!int.TryParse(Property("iterations"), out ITERATIONS)) + ITERATIONS = 5; + } + + static void Main(string[] args) + { + var rant = new RantEngine(); + + if (!string.IsNullOrEmpty(PKG_PATH)) + { + rant.LoadPackage(PKG_PATH); + } + else + { + foreach (string pkg in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.rantpkg", SearchOption.AllDirectories)) + { + rant.LoadPackage(pkg); + } + } + + var stopwatch = new Stopwatch(); + + // find classes + var classes = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.GetMethods().Any(m => m.GetCustomAttributes().Any())); + + PrintWithColor($"Displaying averages of {ITERATIONS} runs.", ConsoleColor.Cyan); + + foreach (var type in classes) + { + var suiteObj = Activator.CreateInstance(type); + var methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); + PrintWithColor(type.ToString() + ":", ConsoleColor.Yellow); + + foreach (var method in methods) + { + var test = method.GetCustomAttribute(); + Console.Write("\t" + test.Name + ": "); + + var totalSpan = new TimeSpan(0, 0, 0, 0, 0); + + for (var i = 0; i < ITERATIONS; i++) + { + stopwatch.Reset(); + stopwatch.Start(); + + try + { + var result = method.Invoke(suiteObj, new object[] { rant }); + } + catch (TargetInvocationException e) + { + ExceptionDispatchInfo.Capture(e.InnerException).Throw(); + } + + stopwatch.Stop(); + + totalSpan += stopwatch.Elapsed; + } + + var avgSpan = TimeSpan.FromMilliseconds(totalSpan.TotalMilliseconds / ITERATIONS); + PrintWithColor(avgSpan.ToString("c"), ConsoleColor.Magenta); + } + + PrintWithColor("Done", ConsoleColor.Green); + } + } + + private static void PrintWithColor(string str, ConsoleColor color) + { + var oldColor = Console.ForegroundColor; + Console.ForegroundColor = color; + Console.WriteLine(str); + Console.ForegroundColor = oldColor; + } + } +} \ No newline at end of file diff --git a/Rave/Properties/AssemblyInfo.cs b/Rant.Benchmark/Properties/AssemblyInfo.cs similarity index 81% rename from Rave/Properties/AssemblyInfo.cs rename to Rant.Benchmark/Properties/AssemblyInfo.cs index 9d03d53..ca9ec14 100644 --- a/Rave/Properties/AssemblyInfo.cs +++ b/Rant.Benchmark/Properties/AssemblyInfo.cs @@ -5,12 +5,12 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Rave")] -[assembly: AssemblyDescription("Command-line utilities for Rant")] +[assembly: AssemblyTitle("Rant.Benchmark")] +[assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Rave")] -[assembly: AssemblyCopyright("Copyright © Nicholas Fleck 2015")] +[assembly: AssemblyProduct("Rant.Benchmark")] +[assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,7 +20,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("409c7dd6-8deb-4df9-9d1e-91861b782a35")] +[assembly: Guid("3da28b64-bd56-4f33-9249-33c1acb499da")] // Version information for an assembly consists of the following four values: // diff --git a/Rant.Benchmark/Rant.Benchmark.csproj b/Rant.Benchmark/Rant.Benchmark.csproj new file mode 100644 index 0000000..7e0b613 --- /dev/null +++ b/Rant.Benchmark/Rant.Benchmark.csproj @@ -0,0 +1,69 @@ + + + + + Debug + AnyCPU + {3DA28B64-BD56-4F33-9249-33C1ACB499DA} + Exe + Properties + Rant.Benchmark + Rant.Benchmark + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + {a4b6fd1a-44a6-42d2-b4aa-57bc85d2cdd7} + Rant + + + + + \ No newline at end of file diff --git a/Rant.Benchmark/Test.cs b/Rant.Benchmark/Test.cs new file mode 100644 index 0000000..46f5a61 --- /dev/null +++ b/Rant.Benchmark/Test.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rant.Benchmark +{ + public class Test : Attribute + { + public string Name; + public string Desc; + } +} diff --git a/Rant.Benchmark/Tests/Query.cs b/Rant.Benchmark/Tests/Query.cs new file mode 100644 index 0000000..3fc7d91 --- /dev/null +++ b/Rant.Benchmark/Tests/Query.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Rant; + +namespace Rant.Benchmark.Tests +{ + public class Query + { + [Test(Name = "Bare Query (10k)")] + public string BareQuery(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}").Main; + } + + [Test(Name = "Query With Class Filter (10k)")] + public string QueryOneClass(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}").Main; + } + + [Test(Name = "Query With Multiple Class Filters (10k)")] + public string QueryMultiClass(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}").Main; + } + + [Test(Name = "Query With Syllable Count Filter (Min) (10k)")] + public string QuerySyllableMin(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}"); + } + + [Test(Name = "Query With Syllable Count Filter (Exact) (10k)")] + public string QuerySyllableExact(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}"); + } + + [Test(Name = "Query With Syllable Count Filter (Max) (10k)")] + public string QuerySyllableMax(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}"); + } + + [Test(Name = "Query With Syllable Count Filter (Range) (10k)")] + public string QuerySyllableRange(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}"); + } + + [Test(Name = "Query With Syllable Count And Class Filter (10k)")] + public string QuerySyllableClassRange(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}"); + } + + [Test(Name = "Negative Class Filter (10k)")] + public string NegativeClassFilter(RantEngine rant) + { + return rant.Do(@"[rs:10k;\s]{}").Main; + } + } +} diff --git a/Rant.Console/Program.cs b/Rant.Console/Program.cs index 675bfc0..07d903a 100644 --- a/Rant.Console/Program.cs +++ b/Rant.Console/Program.cs @@ -1,37 +1,41 @@ using System; using System.Diagnostics; -using System.IO; using System.Globalization; +using System.IO; using System.Linq; +using System.Text; +using System.Collections.Generic; using Rant; -using Rant.Common; using Rant.Vocabulary; - using static System.Console; using static Rant.Common.CmdLine; +using Rant.Formats; namespace RantConsole { - class Program + internal class Program { +#if !DEBUG public const double PATTERN_TIMEOUT = 10.0; - public static readonly string FILE = GetPaths().FirstOrDefault(); - public static readonly string DIC_PATH = Property("dict"); - public static readonly string PKG_PATH = Property("package"); - public static readonly long SEED; - public static readonly bool USE_SEED; +#else + public const double PATTERN_TIMEOUT = 0.0; +#endif + public static readonly string FILE = GetPaths().FirstOrDefault(); + public static readonly string PKG_DIR = Property("pkgdir"); + public static readonly IEnumerable PKG_FILES = Properties("pkg"); + public static readonly long SEED; + public static readonly bool USE_SEED; static Program() { - USE_SEED = Int64.TryParse(Property("seed"), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out SEED); + USE_SEED = long.TryParse(Property("seed"), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out SEED); } - static void Main(string[] args) + private static void Main(string[] args) { - //Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory; - + OutputEncoding = Encoding.UTF8; Title = "Rant Console" + (Flag("nsfw") ? " [NSFW]" : ""); var rant = new RantEngine(); @@ -40,36 +44,41 @@ static void Main(string[] args) try { #endif - if (!String.IsNullOrEmpty(DIC_PATH)) - { - rant.Dictionary = RantDictionary.FromDirectory(DIC_PATH); - } - else - { - foreach (var dic in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dic", SearchOption.AllDirectories)) - { - rant.Dictionary.AddTable(RantDictionaryTable.FromFile(dic)); - } - } - - if (!String.IsNullOrEmpty(PKG_PATH)) - { + if (PKG_FILES.Any()) + { +#if DEBUG + Stopwatch timer = Stopwatch.StartNew(); +#endif + foreach (var pkg in PKG_FILES) + { + rant.LoadPackage(pkg); + } +#if DEBUG + timer.Stop(); + WriteLine($"Package loading: {timer.ElapsedMilliseconds}ms"); +#endif + } + else if (!string.IsNullOrEmpty(PKG_DIR)) + { #if DEBUG Stopwatch timer = Stopwatch.StartNew(); #endif - rant.LoadPackage(PKG_PATH); + foreach (var pkg in Directory.GetFiles(PKG_DIR, "*.rantpkg")) + { + rant.LoadPackage(pkg); + } #if DEBUG timer.Stop(); WriteLine($"Package loading: {timer.ElapsedMilliseconds}ms"); #endif - } - else - { - foreach (var pkg in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.rantpkg", SearchOption.AllDirectories)) - { - rant.LoadPackage(pkg); - } - } + } + else + { + foreach (string pkg in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.rantpkg", SearchOption.AllDirectories)) + { + rant.LoadPackage(pkg); + } + } #if !DEBUG } catch (Exception e) @@ -80,13 +89,13 @@ static void Main(string[] args) #endif if (Flag("nsfw")) rant.Dictionary.IncludeHiddenClass("nsfw"); - if (!String.IsNullOrEmpty(FILE)) + if (!string.IsNullOrEmpty(FILE)) { #if !DEBUG try { #endif - PrintOutput(rant, File.ReadAllText(FILE)); + PrintOutput(rant, FILE, true); #if !DEBUG } catch (Exception ex) @@ -104,13 +113,18 @@ static void Main(string[] args) while (true) { ForegroundColor = Flag("nsfw") ? ConsoleColor.DarkRed : ConsoleColor.Gray; - Write("RANT> "); // real number symbol + Write("RANT> "); ForegroundColor = ConsoleColor.White; - PrintOutput(rant, ReadLine()); + string input = ReadLine(); + if (input == null) + { + return; + } + PrintOutput(rant, input); } } - static void PrintOutput(RantEngine engine, string source, bool isFile = false) + private static void PrintOutput(RantEngine engine, string source, bool isFile = false) { try { @@ -118,9 +132,12 @@ static void PrintOutput(RantEngine engine, string source, bool isFile = false) sw.Start(); var pattern = isFile - ? RantPattern.FromFile(source) - : RantPattern.FromString(source); + ? source.EndsWith(".rantpgm") + ? RantProgram.LoadFile(source) + : RantProgram.CompileFile(source) + : RantProgram.CompileString(source); sw.Stop(); + var compileTime = sw.Elapsed; sw.Restart(); @@ -131,7 +148,7 @@ static void PrintOutput(RantEngine engine, string source, bool isFile = false) var runTime = sw.Elapsed; - bool writeToFile = !String.IsNullOrEmpty(Property("out")); + bool writeToFile = !string.IsNullOrEmpty(Property("out")); foreach (var chan in output) { if (chan.Name != "main") @@ -147,15 +164,15 @@ static void PrintOutput(RantEngine engine, string source, bool isFile = false) ForegroundColor = ConsoleColor.Green; if (chan.Value.Length > 0) { - if (pattern.Type == RantPatternOrigin.File && writeToFile) + if (pattern.Type == RantProgramOrigin.File && writeToFile) { - var path = Property("out"); + string path = Property("out"); File.WriteAllText( Path.Combine(Path.GetDirectoryName(path), - Path.GetFileNameWithoutExtension(path) + - (chan.Name != "main" - ? $".{chan.Name}" - : "" + "." + Path.GetExtension(path))), + Path.GetFileNameWithoutExtension(path) + + (chan.Name != "main" + ? $".{chan.Name}" + : "" + "." + Path.GetExtension(path))), chan.Value); } else @@ -163,40 +180,41 @@ static void PrintOutput(RantEngine engine, string source, bool isFile = false) #if DEBUG WriteLine($"'{chan.Value}'"); #else - WriteLine(chan.Value); + WriteLine(chan.Value.Normalize(NormalizationForm.FormC)); #endif } } else if (!writeToFile) { ForegroundColor = ConsoleColor.DarkGray; - if (pattern.Type != RantPatternOrigin.File) WriteLine("[Empty]"); + if (pattern.Type != RantProgramOrigin.File) WriteLine("[Empty]"); } ResetColor(); WriteLine(); } - if ((pattern.Type != RantPatternOrigin.File || Flag("wait")) && !Flag("nostats")) + if (!Flag("nostats")) { PrintStats( new Stat("Seed", - $"{output.Seed:X16}{(output.BaseGeneration != 0 ? ":" + output.BaseGeneration : String.Empty)}"), - new Stat("Compile Time", compileTime.ToString("c")), + $"{output.Seed:X16}{(output.BaseGeneration != 0 ? ":" + output.BaseGeneration : string.Empty)}"), + new Stat(isFile && source.EndsWith(".rantpgm") ? "Load Time" : "Compile Time", compileTime.ToString("c")), new Stat("Run Time", runTime.ToString("c")) ); WriteLine(); } + if (isFile && Flag("wait")) Console.ReadKey(); } #if !DEBUG catch (RantRuntimeException e) { ForegroundColor = ConsoleColor.Red; - WriteLine($"Runtime error: {e.Message}"); + WriteLine(e); } catch (RantCompilerException e) { ForegroundColor = ConsoleColor.Yellow; - WriteLine($"Compiler error: {e.Message}"); + WriteLine(e.Message); } catch (Exception e) { @@ -209,10 +227,10 @@ static void PrintOutput(RantEngine engine, string source, bool isFile = false) } } - static void PrintStats(params Stat[] stats) + private static void PrintStats(params Stat[] stats) { int alignment = stats.Max(s => s.Name.Length); - var fmtString = $"{{0, {alignment}}}: "; + string fmtString = $"{{0, {alignment}}}: "; foreach (var stat in stats) { ForegroundColor = ConsoleColor.DarkGray; @@ -235,4 +253,4 @@ public Stat(string name, object value) } } } -} +} \ No newline at end of file diff --git a/Rant.Console/Properties/AssemblyInfo.cs b/Rant.Console/Properties/AssemblyInfo.cs index f393086..b351a4a 100644 --- a/Rant.Console/Properties/AssemblyInfo.cs +++ b/Rant.Console/Properties/AssemblyInfo.cs @@ -4,11 +4,11 @@ // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("RantConsole")] +[assembly: AssemblyTitle("Rant Console")] [assembly: AssemblyDescription("Rant Console")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("RantConsole")] +[assembly: AssemblyProduct("Rant Console")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/Rant.Console/Rant.Console.csproj b/Rant.Console/Rant.Console.csproj index 4e2a723..cd41afd 100644 --- a/Rant.Console/Rant.Console.csproj +++ b/Rant.Console/Rant.Console.csproj @@ -17,7 +17,7 @@ true full false - ..\bin\MainBuild\ + ..\bin\Debug\ DEBUG;TRACE prompt 4 @@ -26,12 +26,12 @@ AnyCPU none true - ..\bin\MainBuild\ + ..\bin\Release\ TRACE prompt 4 - + C:\rant\ TRACE true @@ -45,10 +45,6 @@ - - ..\packages\UnmanagedExports.1.2.7\lib\net\RGiesecke.DllExport.Metadata.dll - False - @@ -66,7 +62,6 @@ - @@ -75,7 +70,6 @@ -