Пример #1
0
        public Value Parse(ParserContext context)
        {
            // Invoke the kind parser.
            Kind kind = new KindParser().Parse(context);

            // Abstract current token.
            Token token = context.Stream.Current;

            // Abstract the token's value.
            string tokenValue = token.Value;

            // Ensure current token is recognized as a valid value.
            if (!Recognition.IsLiteral(token))
            {
                throw new Exception($"Invalid token provided as value: {token.Type}");
            }
            // Strip character/string delimiters if applicable.
            else if (token.Type == TokenType.LiteralString || token.Type == TokenType.LiteralCharacter)
            {
                tokenValue = Util.ExtractStringLiteralValue(tokenValue);
            }

            // Create the value construct.
            Value value = new Value(kind, tokenValue);

            context.Stream.Skip();

            // Return the construct.
            return(value);
        }
Пример #2
0
        public Routine Parse(ParserContext context)
        {
            // Ensure current token is of type symbol at.
            context.Stream.EnsureCurrent(TokenType.SymbolAt);

            // Skip symbol at token.
            context.Stream.Skip();

            // Invoke the identifier parser.
            string identifier = new IdentifierParser().Parse(context);

            // Ensure current token is of type parentheses start.
            context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL);

            // Skip parentheses start token.
            context.Stream.Skip();

            // Capture the current token as the buffer.
            Token buffer = context.Stream.Current;

            // Create the argument buffer list.
            List <(Kind, Reference)> args = new List <(Kind, Reference)>();

            // Begin argument parsing.
            while (buffer.Type != TokenType.SymbolParenthesesR)
            {
                // Invoke kind parser.
                Kind kind = new KindParser().Parse(context);

                // Invoke reference parser.
                Reference reference = new ReferenceParser().Parse(context);

                // Abstract current token.
                Token token = context.Stream.Current;

                // Current token must be symbol comma or parentheses end.
                if (token.Type != TokenType.SymbolParenthesesR && token.Type != TokenType.SymbolComma)
                {
                    throw new Exception($"Unexpected token in argument list: {token.Type}");
                }
                // Skip symbol comma token.
                else if (token.Type == TokenType.SymbolComma)
                {
                    context.Stream.Skip();
                }

                // Append the argument.
                args.Add((kind, reference));

                // Update the buffer.
                buffer = context.Stream.Current;
            }

            // Ensure current token is symbol parentheses end.
            context.Stream.EnsureCurrent(TokenType.SymbolParenthesesR);

            // Skip parentheses end.
            context.Stream.Skip();

            // Invoke kind parser to parse return kind.
            Kind returnKind = new KindParser().Parse(context);

            // Update the token buffer.
            buffer = context.Stream.Current;

            // Parse the body.
            Section body = new SectionParser().Parse(context);

            // Ensure current token is of type symbol tilde.
            context.Stream.EnsureCurrent(TokenType.SymbolTilde);

            // Skip symbol tilde.
            context.Stream.Skip();

            // Create the prototype.
            Prototype prototype = new Prototype(identifier, args.ToArray(), returnKind, false);

            // Create the routine construct.
            Routine routine = new Routine(prototype, body);

            // Return the resulting routine.
            return(routine);
        }