Exemple #1
0
        private static bool Arg(Interpreter interpreter, Source source, Stringe tagname, Argument[] args)
        {
            if (!interpreter.SubArgStack.Any())
            {
                throw new RantException(source, tagname, "Tried to access arguments outside of a subroutine body.");
            }

            Argument arg;
            var      argName = args[0].GetString().Trim();

            if (!interpreter.SubArgStack.Peek().TryGetValue(argName, out arg))
            {
                throw new RantException(source, tagname, "Could not find argument '" + argName + "'.");
            }

            // Argument is string
            if (arg.Flags == ParamFlags.None)
            {
                interpreter.Print(arg.GetString());
                return(false);
            }

            // Argument is tokens
            interpreter.PushState(State.CreateDerivedShared(source, arg.GetTokens(), interpreter));
            return(true);
        }
Exemple #2
0
 private static bool RepNum(Interpreter interpreter, Source source, Stringe tagname, Argument[] args)
 {
     if (interpreter.CurrentRepeater == null)
     {
         throw new RantException(source, tagname, "No active repeaters.");
     }
     interpreter.Print(interpreter.FormatNumber(interpreter.CurrentRepeater.Index + 1));
     return(false);
 }
Exemple #3
0
        private static bool Number(Interpreter interpreter, Source source, Stringe tagName, Argument[] args)
        {
            int a, b;

            if (!Int32.TryParse(args[0].GetString(), out a) || !Int32.TryParse(args[1].GetString(), out b))
            {
                throw new RantException(source, tagName, "Range values could not be parsed. They must be numbers.");
            }
            interpreter.Print(interpreter.FormatNumber(interpreter.RNG.Next(a, b + 1)));
            return(false);
        }
Exemple #4
0
        private static bool Extern(Interpreter interpreter, Source source, Stringe tagname, Argument[] args)
        {
            var name   = args[0].GetString();
            var result = interpreter.Engine.Hooks.Call(name);

            if (result == null)
            {
                throw new RantException(source, tagname, "A hook with the name '" + name + "' does not exist.");
            }
            interpreter.Print(result);
            return(false);
        }
Exemple #5
0
        private static bool CharacterMulti(Interpreter interpreter, RantPattern source, Stringe tagname, Argument[] args)
        {
            int count;

            if (!ParseInt(args[1], out count) || count < 0)
            {
                throw Error(source, tagname, "Invalid character count specified. Must be a non-negative number greater than zero.");
            }
            for (int i = 0; i < count; i++)
            {
                interpreter.Print(SelectFromRanges(args[0], interpreter.RNG));
            }
            return(false);
        }
Exemple #6
0
        private static bool CharacterMulti(Interpreter interpreter, Source source, Stringe tagname, Argument[] args)
        {
            int count;

            if (!Int32.TryParse(args[1], out count) || count < 0)
            {
                throw new RantException(source, tagname, "Invalid character count specified. Must be a non-negative number greater than zero.");
            }
            for (int i = 0; i < count; i++)
            {
                interpreter.Print(Util.SelectFromRanges(args[0], interpreter.RNG));
            }
            return(false);
        }
Exemple #7
0
 private static bool Character(Interpreter interpreter, RantPattern source, Stringe tagname, Argument[] args)
 {
     interpreter.Print(SelectFromRanges(args[0], interpreter.RNG));
     return(false);
 }
Exemple #8
0
 private static bool Src(Interpreter interpreter, RantPattern source, Stringe tagname, Argument[] args)
 {
     interpreter.Print(source.Code);
     return(false);
 }
Exemple #9
0
 private static bool Generation(Interpreter interpreter, RantPattern source, Stringe tagName, Argument[] args)
 {
     interpreter.Print(interpreter.RNG.Generation);
     return(false);
 }
Exemple #10
0
 private static bool NumberDec(Interpreter interpreter, RantPattern source, Stringe tagName, Argument[] args)
 {
     interpreter.Print(interpreter.RNG.NextDouble());
     return(false);
 }
Exemple #11
0
 private static bool DoText(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(reader.ReadToken().Value);
     return(false);
 }
Exemple #12
0
 private static bool ReplaceMatch(Interpreter interpreter, Source source, Stringe tagname, Argument[] args)
 {
     interpreter.Print(interpreter.GetMatchString());
     return(false);
 }
Exemple #13
0
        private static bool DoQuery(Interpreter interpreter, SourceReader reader, State state)
        {
            var first = reader.ReadToken();

            reader.SkipSpace();

            var namesub = reader.Read(TokenType.Text, "list name").Split(new[] { '.' }, 2).ToArray();
            var q       = new Query(namesub[0].Value.Trim(), namesub.Length == 2 ? namesub[1].Value : "", "", reader.Take(TokenType.Dollar), null, null);

            Token <TokenType> token = null;

            // Class filter list. Not initialized unless class filters actually exist.
            List <Tuple <bool, string> > cfList = null;

            while (true)
            {
                if (reader.Take(TokenType.Hyphen))
                {
                    // Initialize the filter list.
                    (cfList ?? (cfList = new List <Tuple <bool, string> >())).Clear();

                    do
                    {
                        bool notin = reader.Take(TokenType.Exclamation);
                        if (notin && q.Exclusive)
                        {
                            throw new RantException(reader.Source, reader.PrevToken, "Cannot use the '!' modifier on exclusive class filters.");
                        }
                        cfList.Add(Tuple.Create(!notin, reader.Read(TokenType.Text, "class identifier").Value.Trim()));
                    } while (reader.Take(TokenType.Pipe));
                    q.ClassFilters.Add(cfList.ToArray());
                }
                else if (reader.Take(TokenType.Question))
                {
                    token = reader.Read(TokenType.Regex, "regex");
                    q.RegexFilters.Add(Tuple.Create(true, Util.ParseRegex(token.Value)));
                }
                else if (reader.Take(TokenType.Without))
                {
                    token = reader.Read(TokenType.Regex, "regex");
                    q.RegexFilters.Add(Tuple.Create(false, Util.ParseRegex(token.Value)));
                }
                else if (reader.Take(TokenType.DoubleColon))
                {
                    token     = reader.Read(TokenType.Text, "carrier name");
                    q.Carrier = token.Value.Trim();
                    if (!reader.Take(TokenType.RightAngle))
                    {
                        throw new RantException(reader.Source, token, "Expected '>' after carrier. (The carrier should be your last query argument!)");
                    }
                    break;
                }
                else if (reader.Take(TokenType.RightAngle))
                {
                    break;
                }
                else if (!reader.SkipSpace())
                {
                    var t = !reader.End ? reader.ReadToken() : null;
                    throw new RantException(reader.Source, t, t == null ? "Unexpected end-of-file in query." : "Unexpected token '" + t.Value + "' in query.");
                }
            }

            interpreter.Print(interpreter.Engine.Vocabulary.Query(interpreter.RNG, q));

            return(false);
        }
Exemple #14
0
 private static bool DoEscape(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(Util.Unescape(reader.ReadToken().Value, interpreter.RNG));
     return(false);
 }
Exemple #15
0
 private static bool DoConstant(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(Util.UnescapeConstantLiteral(reader.ReadToken().Value));
     return(false);
 }
Exemple #16
0
 private static bool Length(Interpreter interpreter, RantPattern source, Stringe tagname, Argument[] args)
 {
     interpreter.Print(args[0].GetString().Length);
     return(false);
 }
Exemple #17
0
 private static bool Dist(Interpreter interpreter, RantPattern source, Stringe tagname, Argument[] args)
 {
     interpreter.Print(interpreter.GetMarkerDistance(args[0], args[1]));
     return(false);
 }
Exemple #18
0
        private static bool DoQuery(Interpreter interpreter, Token <R> firstToken, PatternReader reader, State state)
        {
            reader.SkipSpace();

            bool   storeMacro    = false;
            bool   macroIsGlobal = false;
            string macroName     = null;

            // Check if this is a macro
            if (reader.Take(R.At))
            {
                reader.SkipSpace();

                var macroNameToken = reader.Read(R.Text, "query macro name");
                if (!ValidateName(macroNameToken.Value))
                {
                    throw new RantException(reader.Source, macroNameToken, "Invalid macro name.");
                }

                macroName = macroNameToken.Value;

                reader.SkipSpace();

                // Check if the macro is a definition or a call.
                // A definition will start with a colon ':' or equals '=' after the name. A call will only consist of the name.
                switch (reader.ReadToken().ID)
                {
                case R.Colon:     // Local definition
                {
                    storeMacro = true;
                }
                break;

                case R.Equal:     // Global definition
                {
                    storeMacro    = true;
                    macroIsGlobal = true;
                }
                break;

                case R.RightAngle:     // Call
                {
                    Query q;
                    if (!interpreter.LocalQueryMacros.TryGetValue(macroName, out q) && !interpreter.Engine.GlobalQueryMacros.TryGetValue(macroName, out q))
                    {
                        throw new RantException(reader.Source, macroNameToken, "Nonexistent query macro '\{macroName}'");
                    }
                    interpreter.Print(interpreter.Engine.Vocabulary?.Query(interpreter.RNG, q, interpreter.CarrierSyncState));
                    return(false);
                }
                }
            }

            reader.SkipSpace();
            var namesub = reader.Read(R.Text, "dictionary name").Split(new[] { '.' }, 2).ToArray();

            reader.SkipSpace();

            bool exclusive = reader.Take(R.Dollar);
            List <Tuple <bool, string> >  cfList          = null;
            List <Tuple <bool, string>[]> classFilterList = null;
            List <Tuple <bool, Regex> >   regList         = null;
            Carrier carrier = null;

            Token <R> queryToken = null;

            // Read query arguments
            while (true)
            {
                reader.SkipSpace();
                if (reader.Take(R.Hyphen))
                {
                    reader.SkipSpace();
                    // Initialize the filter list.
                    (cfList ?? (cfList = new List <Tuple <bool, string> >())).Clear();
                    do
                    {
                        bool notin = reader.Take(R.Exclamation);
                        reader.SkipSpace();
                        if (notin && exclusive)
                        {
                            throw new RantException(reader.Source, reader.PrevToken, "Cannot use the '!' modifier on exclusive class filters.");
                        }
                        cfList.Add(Tuple.Create(!notin, reader.Read(R.Text, "class identifier").Value.Trim()));
                        reader.SkipSpace();
                    } while (reader.Take(R.Pipe));
                    (classFilterList ?? (classFilterList = new List <Tuple <bool, string>[]>())).Add(cfList.ToArray());
                }
                else if (reader.Take(R.Question))
                {
                    reader.SkipSpace();
                    queryToken = reader.Read(R.Regex, "regex");
                    (regList ?? (regList = new List <Tuple <bool, Regex> >())).Add(Tuple.Create(true, ParseRegex(queryToken.Value)));
                }
                else if (reader.Take(R.Without))
                {
                    reader.SkipSpace();
                    queryToken = reader.Read(R.Regex, "regex");
                    (regList ?? (regList = new List <Tuple <bool, Regex> >())).Add(Tuple.Create(false, ParseRegex(queryToken.Value)));
                }
                else if (reader.Take(R.DoubleColon)) // Start of carrier
                {
                    reader.SkipSpace();

                    CarrierSyncType type;
                    Token <R>       typeToken;

                    switch ((typeToken = reader.ReadToken()).ID)
                    {
                    case R.Exclamation:
                        type = CarrierSyncType.Unique;
                        break;

                    case R.Equal:
                        type = CarrierSyncType.Match;
                        break;

                    case R.Ampersand:
                        type = CarrierSyncType.Rhyme;
                        break;

                    default:
                        throw new RantException(reader.Source, typeToken, "Unrecognized token '\{typeToken.Value}' in carrier.");
                    }

                    reader.SkipSpace();

                    carrier = new Carrier(type, reader.Read(R.Text, "carrier sync ID").Value, 0, 0);

                    reader.SkipSpace();

                    if (!reader.Take(R.RightAngle))
                    {
                        throw new RantException(reader.Source, queryToken, "Expected '>' after carrier. (The carrier should be your last query argument!)");
                    }
                    break;
                }