Пример #1
0
        private bool DoElement(SourceReader reader, State state)
        {
            TokenFunc func;

            if (TokenFuncs.TryGetValue(reader.PeekToken().Identifier, out func))
            {
                return(func(this, reader, state));
            }
            Print(reader.ReadToken().Value);
            return(false);
        }
Пример #2
0
        private static bool DoTag(Interpreter interpreter, SourceReader reader, State state)
        {
            reader.Read(TokenType.LeftSquare);
            var name = reader.ReadToken();

            // Check if metapattern
            if (name.Identifier == TokenType.Question)
            {
                state.AddPreBlueprint(new MetapatternBlueprint(interpreter));
                interpreter.PushState(State.CreateDerivedDistinct(reader.Source, reader.ReadToScopeClose(TokenType.LeftSquare, TokenType.RightSquare, BracketPairs.All), interpreter));
                return(true);
            }

            // Check if replacer
            if (name.Identifier == TokenType.Regex)
            {
                return(DoReplacer(name, interpreter, reader, state));
            }

            if (name.Identifier == TokenType.Dollar)
            {
                return(reader.IsNext(TokenType.Text) ? DoSubCall(name, interpreter, reader, state) : DoSubDefinition(name, interpreter, reader, state));
            }

            if (!Util.ValidateName(name.Value.Trim()))
            {
                throw new RantException(reader.Source, name, "Invalid tag name '" + name.Value + "'");
            }

            bool none = false;

            if (!reader.Take(TokenType.Colon))
            {
                if (!reader.Take(TokenType.RightSquare))
                {
                    throw new RantException(reader.Source, name, "Expected ':' or ']' after tag name.");
                }
                none = true;
            }

            if (none)
            {
                state.AddPreBlueprint(new TagBlueprint(interpreter, reader.Source, name));
            }
            else
            {
                var items = reader.ReadItemsToClosureTrimmed(TokenType.LeftSquare, TokenType.RightSquare,
                                                             TokenType.Semicolon, BracketPairs.All).ToArray();

                state.AddPreBlueprint(new TagBlueprint(interpreter, reader.Source, name, items));
            }
            return(true);
        }
Пример #3
0
        private static bool DoSubCall(Token <TokenType> first, Interpreter interpreter, SourceReader reader, State state)
        {
            var name = reader.ReadToken();

            if (!Util.ValidateName(name.Value))
            {
                throw new RantException(reader.Source, name, "Invalid subroutine name '" + name.Value + "'");
            }

            bool none = false;

            if (!reader.Take(TokenType.Colon))
            {
                if (!reader.Take(TokenType.RightSquare))
                {
                    throw new RantException(reader.Source, name, "Expected ':' or ']' after subroutine name.");
                }

                none = true;
            }

            IEnumerable <Token <TokenType> >[] args = null;
            Subroutine sub = null;

            if (none)
            {
                if ((sub = interpreter.Engine.Subroutines.Get(name.Value, 0)) == null)
                {
                    throw new RantException(reader.Source, name, "No subroutine was found with the name '" + name.Value + "' and 0 parameters.");
                }
            }
            else
            {
                args = reader.ReadItemsToClosureTrimmed(TokenType.LeftSquare, TokenType.RightSquare, TokenType.Semicolon,
                                                        BracketPairs.All).ToArray();
                if ((sub = interpreter.Engine.Subroutines.Get(name.Value, args.Length)) == null)
                {
                    throw new RantException(reader.Source, name, "No subroutine was found with the name '" + name.Value + "' and " + args.Length + " parameter" + (args.Length != 1 ? "s" : "") + ".");
                }
            }

            state.AddPreBlueprint(new SubCallBlueprint(interpreter, reader.Source, sub, args));

            return(true);
        }
Пример #4
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);
        }
Пример #5
0
 private static bool DoEscape(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(Util.Unescape(reader.ReadToken().Value, interpreter.RNG));
     return(false);
 }
Пример #6
0
 private static bool DoConstant(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(Util.UnescapeConstantLiteral(reader.ReadToken().Value));
     return(false);
 }
Пример #7
0
 private static bool DoText(Interpreter interpreter, SourceReader reader, State state)
 {
     interpreter.Print(reader.ReadToken().Value);
     return(false);
 }