private static bool CapsInfer(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { // TODO: Make capsinfer properly infer "first" capitalization given multiple sentences. Currently, it mistakes it for "word" mode. var words = Regex.Matches(args[0].GetString(), @"\w+").OfType<Match>().Select(m => m.Value).ToArray(); int wCount = words.Length; int uCount = 0; int fwCount = 0; bool firstCharIsUpper = false; for (int i = 0; i < wCount; i++) { if (words[i].All(Char.IsUpper)) { uCount++; } if (Char.IsUpper(words[i][0])) { fwCount++; if (i == 0) firstCharIsUpper = true; } } if (uCount == wCount) { interpreter.CurrentState.Output.SetCaps(Capitalization.Upper); } else if (wCount > 1 && fwCount == wCount) { interpreter.CurrentState.Output.SetCaps(Capitalization.Word); } else if (firstCharIsUpper) { interpreter.CurrentState.Output.SetCaps(Capitalization.First); } return false; }
public TagBlueprint(Interpreter interpreter, Source source, Stringe name, IEnumerable<Token<TokenType>>[] args = null) : base(interpreter) { Source = source; Name = name; if (!Interpreter.TagFuncs.TryGetValue(Name.Value.ToLower().Trim(), out _tagDef)) { throw new ProcessusException(Source, Name, "The tag '" + Name.Value + "' does not exist."); } _tagDef.ValidateArgCount(source, name, args != null ? args.Length : 0); if (args == null) { _args = Enumerable.Empty<TagArg>().ToArray(); } else { // Insert token arguments into the array, set string args to null. _args = args.Select((a, i) => _tagDef.ArgTypes[i] == TagArgType.Tokens ? TagArg.FromTokens(a) : null).ToArray(); // Queue string arguments on the stack. for (int i = 0; i < _tagDef.ArgTypes.Length; i++) { if (_tagDef.ArgTypes[i] == TagArgType.Result) { interpreter.PushState(Interpreter.State.CreateDerivedDistinct(source, args[i], interpreter)); } } } }
public override bool Use() { var srcstr = I.PopResultString(); var src = new Source("Meta_" + String.Format("{0:X16}", srcstr.Hash()), SourceType.Metapattern, srcstr); I.PushState(Interpreter.State.Create(src, I)); return true; }
public State(Interpreter ii, Source source, ChannelStack output) { _finished = false; _preBlueprints = new Stack<Blueprint>(); _postBlueprints = new Stack<Blueprint>(); _interpreter = ii; _output = output; _reader = new SourceReader(source); _sharesOutput = (output == _interpreter._output && _interpreter.PrevState != null) || (_interpreter._stateStack.Any() && output == _interpreter._stateStack.Peek().Output); }
private static bool Extern(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { var name = args[0].GetString(); var result = interpreter.Engine.Hooks.Call(name); if (result == null) { throw new ProcessusException(source, tagname, "A hook with the name '" + name + "' does not exist."); } interpreter.Print(result); return false; }
private State(Interpreter ii, Source derivedSource, IEnumerable<Token<TokenType>> tokens, ChannelStack output) { _finished = false; _preBlueprints = new Stack<Blueprint>(); _postBlueprints = new Stack<Blueprint>(); _interpreter = ii; _output = output; _reader = new SourceReader(new Source(derivedSource.Name, derivedSource.Type, tokens, derivedSource.Code)); _sharesOutput = (output == _interpreter._output && _interpreter.PrevState != null) || (_interpreter._stateStack.Any() && output == _interpreter._stateStack.Peek().Output); }
internal ProcessusException(Source source, Stringe token, string message = "A generic syntax error was encountered.") : base((token != null ? ("(Ln " + token.Line + ", Col " + token.Column + ") - ") : "") + message) { _source = source.Code; if (token != null) { _line = token.Line; _col = token.Column; _index = token.Offset; _length = token.Length; } else { _line = _col = 1; _index = 0; _length = 0; } }
public SubCallBlueprint(Interpreter interpreter, Source source, Subroutine subroutine, IEnumerable<Token<TokenType>>[] args) : base(interpreter) { _subroutine = subroutine; if (args == null) { _args = Enumerable.Empty<TagArg>().ToArray(); } else { // Insert token arguments into the array, set string args to null. _args = args.Select((a, i) => _subroutine.Parameters[i].Item2 == TagArgType.Tokens ? TagArg.FromTokens(a) : null).ToArray(); // Queue string arguments on the stack. for (int i = 0; i < _subroutine.ParamCount; i++) { if (_subroutine.Parameters[i].Item2 == TagArgType.Result) { interpreter.PushState(Interpreter.State.CreateDerivedDistinct(source, args[i], interpreter)); } } } }
private static bool NumFmt(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { NumberFormat fmt; var fmtstr = args[0].GetString(); if (!Enum.TryParse(Util.NameToCamel(fmtstr), out fmt)) { throw new ProcessusException(source, tagname, "Invalid number format '" + fmtstr + "'"); } interpreter.NumberFormat = fmt; return false; }
private static bool Arg(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { if (!interpreter.SubArgStack.Any()) throw new ProcessusException(source, tagname, "Tried to access arguments outside of a subroutine body."); TagArg arg; var argName = args[0].GetString().Trim(); if (!interpreter.SubArgStack.Peek().TryGetValue(argName, out arg)) throw new ProcessusException(source, tagname, "Could not find argument '" + argName + "'."); // Argument is string if (arg.Type == TagArgType.Result) { interpreter.Print(arg.GetString()); return false; } // Argument is tokens interpreter.PushState(State.CreateDerivedShared(source, arg.GetTokens(), interpreter)); return true; }
private static bool Reset(Interpreter interpreter, Source source, Stringe tagName, TagArg[] args) { interpreter.Reset(args[0].GetString()); return false; }
private static bool RepNum(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { if (interpreter.CurrentRepeater == null) throw new ProcessusException(source, tagname, "No active repeaters."); interpreter.Print(interpreter.FormatNumber(interpreter.CurrentRepeater.Index + 1)); return false; }
public bool Invoke(Interpreter interpreter, Source source, Stringe tagName, TagArg[] args) { return _func(interpreter, source, tagName, args); }
/// <summary> /// Executes the specified source and returns the resulting output. /// </summary> /// <param name="input">The source to execute.</param> /// <param name="charLimit">The maximum number of characters that can be printed. An exception will be thrown if the limit is exceeded. Set to zero or below for unlimited characters.</param> /// <returns></returns> public Output Do(Source input, int charLimit = 0) { return new Interpreter(this, input, new RNG(Seeds.NextRaw()), charLimit).Run(); }
/// <summary> /// Executes the specified source using a custom random number generator and returns the resulting output. /// </summary> /// <param name="input">The source to execute.</param> /// <param name="rng">The random number generator to use when generating output.</param> /// <param name="charLimit">The maximum number of characters that can be printed. An exception will be thrown if the limit is exceeded. Set to zero or below for unlimited characters.</param> /// <returns></returns> public Output Do(Source input, RNG rng, int charLimit = 0) { return new Interpreter(this, input, rng, charLimit).Run(); }
private static bool ReplaceMatch(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { interpreter.Print(interpreter.GetMatchString()); return false; }
private static bool Number(Interpreter interpreter, Source source, Stringe tagName, TagArg[] args) { int a, b; if (!Int32.TryParse(args[0].GetString(), out a) || !Int32.TryParse(args[1].GetString(), out b)) { throw new ProcessusException(source, tagName, "Range values could not be parsed. They must be numbers."); } interpreter.Print(interpreter.FormatNumber(interpreter.RNG.Next(a, b + 1))); return false; }
private static bool Desync(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { interpreter.Desync(); return false; }
private static bool Sync(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { var typeStr = args[1].GetString(); SyncType type; if (!Enum.TryParse(typeStr, true, out type)) { throw new ProcessusException(source, tagname, "Invalid synchronizer type: '" + typeStr + "'"); } interpreter.Sync(args[0].GetString(), type); return false; }
private static bool Pin(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { interpreter.Pin(args[0].GetString()); return false; }
private static bool First(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { if (interpreter.CurrentRepeater == null || !interpreter.CurrentRepeater.IsFirst) return false; interpreter.PushState(State.CreateDerivedDistinct(source, args[0].GetTokens(), interpreter, interpreter.CurrentState.Output)); return true; }
private static bool Nth(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { int offset, interval; if (!Int32.TryParse(args[0].GetString(), out interval)) { throw new ProcessusException(source, tagname, "Invalid interval value."); } if (interval <= 0) { throw new ProcessusException(source, tagname, "Interval must be greater than zero."); } if (!Int32.TryParse(args[1].GetString(), out offset)) { throw new ProcessusException(source, tagname, "Invalid offset value."); } if (interpreter.CurrentRepeater == null || !interpreter.CurrentRepeater.Nth(offset, interval)) return false; interpreter.PushState(State.CreateDerivedDistinct(source, args[2].GetTokens(), interpreter, interpreter.CurrentState.Output)); return true; }
private static bool Caps(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { Capitalization caps; var caps_str = args[0].GetString(); if (!Enum.TryParse(Util.NameToCamel(caps_str), out caps)) { throw new ProcessusException(source, tagname, "Invalid capitalization format '" + caps_str + "'"); } interpreter.CurrentState.Output.SetCaps(caps); return false; }
private static bool Separator(Interpreter interpreter, Source source, Stringe tagName, TagArg[] args) { interpreter.NextAttribs.Separator = args[0].GetTokens(); return false; }
internal static Source Derived(string name, Source source, IEnumerable<Token<TokenType>> tokens) { return new Source(name, source._type, tokens, source._code); }
private static bool Repeat(Interpreter interpreter, Source source, Stringe tagName, TagArg[] args) { var reps = args[0].GetString().ToLower().Trim(); if (reps == "each") { interpreter.NextAttribs.Repetitons = Repeater.Each; return false; } int num; if (!Int32.TryParse(reps, out num)) { throw new ProcessusException(source, tagName, "Invalid repetition value '" + reps + "' - must be a number."); } if (num < 0) { throw new ProcessusException(source, tagName, "Repetition value cannot be negative."); } interpreter.NextAttribs.Repetitons = num; return false; }
/// <summary> /// Executes the specified source using a custom seed and returns the resulting output. /// </summary> /// <param name="input">The source to execute.</param> /// <param name="seed">The seed to generate output with.</param> /// <param name="charLimit">The maximum number of characters that can be printed. An exception will be thrown if the limit is exceeded. Set to zero or below for unlimited characters.</param> /// <returns></returns> public Output Do(Source input, long seed, int charLimit = 0) { return new Interpreter(this, input, new RNG(seed), charLimit).Run(); }
public void ValidateArgCount(Source source, Stringe tagName, int count) { if (count != _paramCount) throw new ProcessusException(source, tagName, "Tag '" + tagName.Value + "' expected " + _paramCount + " " + (_paramCount == 1 ? "argument" : "arguments") + " but got " + count + "."); }
private static bool Chance(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { int a; if (!Int32.TryParse(args[0].GetString(), out a)) { throw new ProcessusException(source, tagname, "Invalid chance number."); } interpreter.SetChance(a); return false; }
private static bool Alt(Interpreter interpreter, Source source, Stringe tagname, TagArg[] args) { var testState = State.CreateDerivedDistinct(source, args[0].GetTokens(), interpreter, interpreter.CurrentState.Output); testState.AddPostBlueprint(new AltBlueprint(interpreter, testState, args[1].GetTokens())); interpreter.PushState(testState); return true; }