private static IEnumerator <RantAction> NotNthO(Sandbox sb, [RantDescription("The interval at which the pattern should not be run.")] int interval, [RantDescription("The number of iterations to offset the interval by.")] int offset, [RantDescription("The pattern to run when the condition is satisfied.")] RantAction pattern) { if (!sb.Blocks.Any()) { yield break; } if (Util.Mod(sb.Blocks.Peek().Iteration - offset, interval) == 0) { yield break; } yield return(pattern); }
private static IEnumerator <RichActionBase> SyncSetPinnedState(Sandbox sb, RantObject that, [RichardPropertyArgument("syncName", "string", Description = "The name of the synchronizer to set pinned state on.")] RantObject obj1, [RichardPropertyArgument("pinnedState", "bool", Description = "The pinned state that will be assigned to this synchronizer.")] RantObject obj2) { string syncName = obj1.Value as string; object pinnedState = obj2.Value; if (syncName == null) { throw new RantRuntimeException(sb.Pattern, null, "syncName must be a string."); } if (!(pinnedState is bool)) { throw new RantRuntimeException(sb.Pattern, null, "pinnedState must be a bool."); } sb.SyncManager.SetPinned(syncName, (bool)pinnedState); yield break; }
private static IEnumerator <RichActionBase> MathMin(Sandbox sb, RantObject that, [RichardPropertyArgument("a", "number")] RantObject arg1, [RichardPropertyArgument("b", "number")] RantObject arg2) { var a = arg1.Value; if (!(a is double)) { throw new RantRuntimeException(sb.Pattern, null, "A must be a number."); } var b = arg2.Value; if (!(b is double)) { throw new RantRuntimeException(sb.Pattern, null, "B must be a number."); } sb.ScriptObjectStack.Push(Math.Min((double)a, (double)b)); yield break; }
private static IEnumerator <RichActionBase> MathAtan2(Sandbox sb, RantObject that, [RichardPropertyArgument("y", "number", Description = "The Y value of the atan2 operation.")] RantObject arg1, [RichardPropertyArgument("x", "number", Description = "The X value of the atan2 operation.")] RantObject arg2) { var y = arg1.Value; if (!(y is double)) { throw new RantRuntimeException(sb.Pattern, null, "Y must be a number."); } var x = arg2.Value; if (!(x is double)) { throw new RantRuntimeException(sb.Pattern, null, "X must be a number."); } sb.ScriptObjectStack.Push(Math.Atan2((double)y, (double)x)); yield break; }
private static IEnumerator <RichActionBase> TargetSend(Sandbox sb, RantObject that, [RichardPropertyArgument("targetName", "string", Description = "The name of the target to write to.")] RantObject obj1, [RichardPropertyArgument("value", "string", Description = "The value to write to the target.")] RantObject obj2 ) { string targetName = obj1.Value as string; string value = obj2.Value as string; if (targetName == null) { throw new RantRuntimeException(sb.Pattern, null, "targetName must be a string."); } if (value == null) { throw new RantRuntimeException(sb.Pattern, null, "value must be a string."); } sb.Output.PrintToTarget(targetName, value); yield break; }
private static void Use(Sandbox sb, string name) { if (sb.UserModules.ContainsKey(name)) { sb.Modules[name] = sb.UserModules[name]; return; } if (sb.PackageModules.ContainsKey(name)) { sb.Modules[name] = sb.PackageModules[name]; return; } string file; if (File.Exists(name + ".module.rant")) { file = name + ".module.rant"; } else if (File.Exists(name + ".rant")) { file = name + ".rant"; } else if (File.Exists(name)) { file = name; } else { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Could not find module '{name}'."); } var pattern = RantPattern.FromFile(file); if (pattern.Module == null) { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"No module is defined in {file}."); } sb.Modules[Path.GetFileNameWithoutExtension(name)] = pattern.Module; }
private static IEnumerator <RichActionBase> SyncSet(Sandbox sb, RantObject that, [RichardPropertyArgument("syncName", "string", Description = "The name of the synchronizer to create.")] RantObject obj1, [RichardPropertyArgument("syncType", "string", Description = "The type of synchronizer to create.")] RantObject obj2) { string syncName = obj1.Value as string; string syncType = obj2.Value as string; if (syncName == null) { throw new RantRuntimeException(sb.Pattern, null, "syncName must be a string."); } if (syncType == null) { throw new RantRuntimeException(sb.Pattern, null, "syncType must be a string."); } object type; Util.TryParseEnum(typeof(SyncType), syncType, out type); sb.SyncManager.Create(syncName, (SyncType)type, true); yield break; }
private static IEnumerator <RantAction> Import(Sandbox sb, [RantDescription("The name or path of the pattern to load.")] string name) { RantAction action; try { action = sb.Engine.GetPattern(name).Action; } catch (RantCompilerException e) { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Failed to compile imported pattern '{name}':\n{e.Message}"); } catch (Exception e) { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Failed to import '{name}':\n{e.Message}"); } yield return(action); }
private static IEnumerator <RichActionBase> SyncReseed(Sandbox sb, RantObject that, [RichardPropertyArgument("syncName", "string", Description = "The name of the synchronizer to reseed.")] RantObject obj1, [RichardPropertyArgument("seed", "string", Description = "The value that the synchronizer will be seeded with.")] RantObject obj2) { string syncName = obj1.Value as string; string seed = obj2.Value as string; if (syncName == null) { throw new RantRuntimeException(sb.Pattern, null, "syncName must be a string."); } if (seed == null) { throw new RantRuntimeException(sb.Pattern, null, "seed must be a string."); } if (!sb.SyncManager.SynchronizerExists(syncName)) { throw new RantRuntimeException(sb.Pattern, null, "Synchronizer does not exist."); } sb.SyncManager[syncName].Reseed(seed); yield break; }
private static void Define(Sandbox sb, [RantDescription("The list of flags to define.")] params string[] flags) { foreach (var flag in flags.Where(f => !Util.IsNullOrWhiteSpace(f) && Util.ValidateName(f))) { sb.Engine.Flags.Add(flag); } }
private static void Persist(Sandbox sb, AttribPersistence persistence) { sb.CurrentBlockAttribs.Persistence = persistence; }
private static void Start(Sandbox sb, [RantDescription("The pattern to run before the next block.")] RantAction beforePattern) { sb.CurrentBlockAttribs.Start = beforePattern; }
private static void PrintEmoji(Sandbox sb, [RantDescription("The emoji shortcode to use, without colons.")] string shortcode) { shortcode = shortcode.ToLower(); if(!Emoji.Shortcodes.ContainsKey(shortcode)) { sb.Print("[missing emoji]"); return; } sb.Print(Char.ConvertFromUtf32(Emoji.Shortcodes[shortcode])); }
private static void Emdash(Sandbox sb) => sb.Print("\x2014");
private static void PatternArg(Sandbox sb, [RantDescription("The name of the argument to access.")] string argName) { if (sb.PatternArgs == null) return; sb.Output.Print(sb.PatternArgs[argName]); }
private static void Yield(Sandbox sb) { sb.SetYield(); }
private static void Case(Sandbox sb, [RantDescription("The capitalization mode to use.")] Capitalization textCase) { sb.Output.Capitalize(textCase); }
private static void Chance(Sandbox sb, [RantDescription("The percent probability that the next block will execute.")] double chance) { sb.CurrentBlockAttribs.Chance = chance < 0 ? 0 : chance > 100 ? 100 : chance; }
private static void After(Sandbox sb, [RantDescription("The pattern to run after each iteration of the next block.")] RantAction afterAction) { sb.CurrentBlockAttribs.After = afterAction; }
private static void Before(Sandbox sb, [RantDescription("The pattern to run before each iteration of the next block.")] RantAction beforeAction) { sb.CurrentBlockAttribs.Before = beforeAction; }
private static void RepEach(Sandbox sb) { sb.CurrentBlockAttribs.RepEach = true; }
private static void Rep(Sandbox sb, [RantDescription("The number of times to repeat the next block.")] int times) { sb.CurrentBlockAttribs.Repetitions = times; }
private static void Endian(Sandbox sb, [RantDescription("The endianness to use.")] Endianness endianness) { sb.Output.Do(chain => chain.Last.NumberFormatter.Endianness = endianness); }
private static void Toggle(Sandbox sb, params string[] flags) { foreach (var flag in flags.Where(f => !Util.IsNullOrWhiteSpace(f) && Util.ValidateName(f))) { if (sb.Engine.Flags.Contains(flag)) { sb.Engine.Flags.Remove(flag); } else { sb.Engine.Flags.Add(flag); } } }
private static IEnumerator<RantAction> Then(Sandbox sb, RantAction conditionPassPattern) { if (sb.Engine.Flags.All(flag => sb.ConditionFlags.Contains(flag) == sb.FlagConditionExpectedResult)) { yield return conditionPassPattern; } }
private static void CapsInfer(Sandbox sb, [RantDescription("A string that is capitalized in the format to be set.")] string sample) { var output = sb.Output; if (String.IsNullOrEmpty(sample)) { output.Capitalize(Capitalization.None); return; } var words = sample.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (words.Length == 1) { var word = words[0]; if (word.Length == 1) { if (Char.IsUpper(word[0])) { output.Capitalize(Capitalization.First); } else { output.Capitalize(Capitalization.None); } } else if (Util.IsUppercase(word)) { output.Capitalize(Capitalization.Upper); } else if (Char.IsUpper(word.SkipWhile(c => !Char.IsLetterOrDigit(c)).FirstOrDefault())) { output.Capitalize(Capitalization.First); } else { output.Capitalize(Capitalization.None); } } else { // No letters? Forget it. if (!sample.Any(Char.IsLetter)) { output.Capitalize(Capitalization.None); return; } // Is all-caps? if (Util.IsUppercase(sample)) { output.Capitalize(Formatters.Capitalization.Upper); return; } var sentences = sample.Split(new[] { '.', '?', '!' }, StringSplitOptions.RemoveEmptyEntries) .Select(str => str.Trim()) .Where(str => !String.IsNullOrEmpty(str) && !Char.IsDigit(str[0])).ToArray(); // All words capitalized? var lwords = words.Where(w => Char.IsLetter(w[0])).ToArray(); if (lwords.Any() && (sentences.Length == 1 || sentences.Any(s => s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1))) { if (lwords.All(lw => Char.IsUpper(lw[0]))) { output.Capitalize(Capitalization.Word); return; } if (lwords.All(lw => Char.IsLower(lw[0]) == sb.Format.Excludes(lw))) { output.Capitalize(Capitalization.Title); return; } } // All sentences capitalized? bool all = true; bool none = true; foreach (var sentence in sentences) { bool isCapitalized = Char.IsUpper(sentence.SkipWhile(c => !Char.IsLetter(c)).FirstOrDefault()); all = all && isCapitalized; none = none && !isCapitalized; } if (sentences.Length > 1 && all) { output.Capitalize(Capitalization.Sentence); } else if (none) { output.Capitalize(Capitalization.Lower); } else if (Char.IsUpper(sample.SkipWhile(c => !Char.IsLetterOrDigit(c)).FirstOrDefault())) { output.Capitalize(Capitalization.First); } else { output.Capitalize(Capitalization.None); } } }
private static IEnumerator<RantAction> Branch(Sandbox sb, string id, RantAction branchAction) { sb.RNG.Branch(id.Hash()); yield return branchAction; sb.RNG.Merge(); }
private static void Depth(Sandbox sb) { sb.Print(sb.Blocks.Count); }
private static void RegisteredTrademark(Sandbox sb) => sb.Print("\x00ae");
private static void Rhyme(Sandbox sb, [RantDescription("The rhyme types to use.")] RhymeFlags flags) { sb.QueryState.Rhymer.AllowedRhymes = flags; }
private static void Bullet(Sandbox sb) => sb.Print("\x2022");
private static void SyncUnpin(Sandbox sb, [RantDescription("The name of the synchronizer to unpin.")] string name) { sb.SyncManager.SetPinned(name, false); }
private static void NumberFormat(Sandbox sb, [RantDescription("The number format to use.")] NumberFormat format) { sb.Output.Do(chain => chain.Last.NumberFormatter.NumberFormat = format); }
private static void SyncStep(Sandbox sb, [RantDescription("The name of the synchronizer to iterate.")] string name) { sb.SyncManager.Step(name); }
private static void End(Sandbox sb, [RantDescription("The pattern to run after the next block.")] RantAction endPattern) { sb.CurrentBlockAttribs.End = endPattern; }
private static void SyncReset(Sandbox sb, [RantDescription("The name of the synchronizer to reset.")] string name) { sb.SyncManager.Reset(name); }
private static IEnumerator<RantAction> Import(Sandbox sb, [RantDescription("The name or path of the pattern to load.")] string name) { RantAction action; try { action = sb.Engine.GetPattern(name).Action; } catch (RantCompilerException e) { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Failed to compile imported pattern '{name}':\n{e.Message}"); } catch (Exception e) { throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Failed to import '{name}':\n{e.Message}"); } yield return action; }
private static void Target(Sandbox sb, [RantDescription("The name of the target.")] string targetName) { sb.Output.InsertTarget(targetName); }
private static void Undef(Sandbox sb, [RantDescription("The list of flags to undefine.")] params string[] flags) { foreach (var flag in flags) { sb.Engine.Flags.Remove(flag); } }
private static void GetTargetValue(Sandbox sb, [RantDescription("The name of the target whose value to print.")] string targetName) { sb.Output.Do(chain => chain.Print(chain.GetTargetValue(targetName))); }
private static void IfNDef(Sandbox sb, params string[] flags) { sb.FlagConditionExpectedResult = false; sb.ConditionFlags.Clear(); foreach (var flag in flags.Where(f => !Util.IsNullOrWhiteSpace(f) && Util.ValidateName(f))) { sb.ConditionFlags.Add(flag); } }
private static void ClearTarget(Sandbox sb, [RantDescription("The name of the target to be cleared.")] string targetName) { sb.Output.Do(chain => chain.ClearTarget(targetName)); }
private static IEnumerator<RantAction> Else(Sandbox sb, RantAction conditionFailPattern) { if (sb.Engine.Flags.Any(flag => sb.ConditionFlags.Contains(flag) != sb.FlagConditionExpectedResult)) { yield return conditionFailPattern; } }
private static void Branch(Sandbox sb, string id) { sb.RNG.Branch(id.Hash()); }
private static void Merge(Sandbox sb) { sb.RNG.Merge(); }
private static void Trademark(Sandbox sb) => sb.Print("\x2122");
private static void Plural(Sandbox sb, string word) { sb.Print(sb.Format.Pluralizer.Pluralize(word)); }
private static void Copyright(Sandbox sb) => sb.Print("\x00a9");
private static void Endash(Sandbox sb) => sb.Print("\x2013");
private static IEnumerator<RantAction> NotNth(Sandbox sb, [RantDescription("The interval at which the pattern should not be run.")] int interval, [RantDescription("The pattern to run when the condition is satisfied.")] RantAction pattern) { if (!sb.Blocks.Any()) yield break; if (sb.Blocks.Peek().Iteration % interval == 0) yield break; yield return pattern; }
private static void Eszett(Sandbox sb) => sb.Print("\x00df");
private static IEnumerator<RantAction> NotNthO(Sandbox sb, [RantDescription("The interval at which the pattern should not be run.")] int interval, [RantDescription("The number of iterations to offset the interval by.")] int offset, [RantDescription("The pattern to run when the condition is satisfied.")] RantAction pattern) { if (!sb.Blocks.Any()) yield break; if (Util.Mod(sb.Blocks.Peek().Iteration - offset, interval) == 0) yield break; yield return pattern; }
private static void Number(Sandbox sb, [RantDescription("The minimum value of the number to generate.")] int min, [RantDescription("The maximum value of the number to generate.")] int max) { sb.Print(sb.RNG.Next(min, max + 1)); }
private static void Use(Sandbox sb, string name) { if(sb.UserModules.ContainsKey(name)) { sb.Modules[name] = sb.UserModules[name]; return; } if(sb.PackageModules.ContainsKey(name)) { sb.Modules[name] = sb.PackageModules[name]; return; } string file; if (File.Exists(name + ".module.rant")) file = name + ".module.rant"; else if (File.Exists(name + ".rant")) file = name + ".rant"; else if (File.Exists(name)) file = name; else throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"Could not find module '{name}'."); var pattern = RantPattern.FromFile(file); if (pattern.Module == null) throw new RantRuntimeException(sb.Pattern, sb.CurrentAction.Range, $"No module is defined in {file}."); sb.Modules[Path.GetFileNameWithoutExtension(name)] = pattern.Module; }