Пример #1
0
        public Expr Parse(ParserContext context)
        {
            // Ensure current token is parentheses start.
            context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL);

            // Peek at the next token.
            Token peek = context.Stream.Peek();

            // Lambda expresion.
            if (TokenIdentifier.IsType(peek, context) || peek.Type == TokenType.SymbolParenthesesR)
            {
                // Delegate to the lambda expression parser.
                return(new LambdaExprParser().Parse(context));
            }

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

            // Parse the expression.
            Expr expr = new ExprParser().Parse(context);

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

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

            // Return the expression.
            return(expr);
        }
Пример #2
0
        public List <Expr> Parse(ParserContext context)
        {
            // Create the resulting argument list.
            List <Expr> arguments = new List <Expr>();

            // Parse the next value.
            Expr value = new ExprParser().Parse(context);

            // Append value to the argument list.
            arguments.Add(value);

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

            // Expect either a comma or pipe symbol.
            if (token.Type != SyntaxAnalysis.TokenType.OperatorPipe && token.Type != SyntaxAnalysis.TokenType.SymbolComma)
            {
                throw new Exception($"Expected next token to be of type either comma symbol or pipe operator, but got '{token.Type}'");
            }
            // There is another value.
            else if (token.Type == SyntaxAnalysis.TokenType.SymbolComma)
            {
                // Skip comma token.
                context.Stream.Skip();

                // Recursively invoke a new pipe args parser instance.
                List <Expr> nextArguments = new PipeArgsParser().Parse(context);

                // Append resulting arguments.
                arguments.AddRange(nextArguments);
            }

            // Return the resulting argument list.
            return(arguments);
        }
Пример #3
0
        public Expr Parse(ParserContext context)
        {
            // Ensure current return keyword.
            context.Stream.EnsureCurrent(SyntaxAnalysis.TokenType.KeywordReturn);

            // Skip over the return keyword.
            context.Stream.Skip();

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

            // There is no return expression.
            if (token.Type == SyntaxAnalysis.TokenType.SymbolSemiColon)
            {
                // Skip the semi-colon.
                context.Stream.Skip();

                // TODO: Should return void? Investigate.
                // Return null as no expression/return value was captured.
                return(null);
            }

            // Otherwise, invoke the expression parser.
            Expr expr = new ExprParser().Parse(context);

            // Ensure current is a semi-colon.
            context.Stream.EnsureCurrent(SyntaxAnalysis.TokenType.SymbolSemiColon);

            // Skip the semi-colon.
            context.Stream.Skip();

            // Return the expression.
            return(expr);
        }
Пример #4
0
        public VarDeclareExpr Parse(ParserContext context)
        {
            // Parse the type.
            Type type = new TypeParser().Parse(context);

            // Create the variable declaration & link the type.
            VarDeclareExpr declaration = new VarDeclareExpr(type, null);

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

            // Assign the name.
            declaration.SetName(identifier);

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

            // A value is being assigned.
            if (token.Type == SyntaxAnalysis.TokenType.OperatorAssignment)
            {
                // Skip the assignment operator.
                context.Stream.Skip();

                // Parse value.
                Expr value = new ExprParser().Parse(context);

                // Assign value.
                declaration.Value = value;
            }

            // Return the resulting declaration construct.
            return(declaration);
        }
Пример #5
0
        public Expr Parse(TokenStream stream)
        {
            // Skip return keyword.
            stream.Skip(TokenType.KeywordReturn);

            // Look at the next token.
            Token nextToken = stream.Peek();

            // There is no return expression.
            if (nextToken.Type == TokenType.SymbolSemiColon)
            {
                // Skip to the semi-colon.
                stream.Skip(TokenType.SymbolSemiColon);

                // Return null as no expression/return value was captured.
                return(null);
            }

            // Otherwise, invoke the expression parser.
            Expr expr = new ExprParser().Parse(stream);

            // Consume semi-colon after the expression.
            stream.Skip(TokenType.SymbolSemiColon);

            return(expr);
        }
Пример #6
0
        public Expr Parse(TokenStream stream)
        {
            // Skip to parentheses start token.
            stream.Skip(TokenType.SymbolParenthesesL);

            // Parse the expression.
            Expr expr = new ExprParser().Parse(stream);

            // Skip to parentheses end token.
            stream.Skip(TokenType.SymbolParenthesesR);

            return(expr);
        }
Пример #7
0
        public ArrayExpr Parse(ParserContext context)
        {
            // Ensure current token is bracket start.
            context.Stream.EnsureCurrent(TokenType.SymbolBracketL);

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

            // Create the value buffer list.
            List <Expr> values = new List <Expr>();

            // Begin parsing values.
            context.Stream.NextUntil(TokenType.SymbolBracketR, (Token token) =>
            {
                // Invoke expression parser.
                Expr value = new ExprParser().Parse(context);

                // Add the captured expression to the list.
                values.Add(value);

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

                // Ensure current token is either semi-colon or bracket end.
                if (current.Type != TokenType.SymbolComma && current.Type != TokenType.SymbolBracketR)
                {
                    throw new Exception($"Expected token in array expression to be of type comma or bracket end, but got '{current.Type}'");
                }
                // Skip comma token.
                else if (current.Type == TokenType.SymbolComma)
                {
                    context.Stream.Skip();
                }

                // Signal to update iterator to current token, since parsers where invoked.
                return(true);
            });

            // Ensure current token is bracket end.
            context.Stream.EnsureCurrent(TokenType.SymbolBracketR);

            // Skip bracket end token.
            context.Stream.Skip();

            // Create the resulting array construct.
            ArrayExpr arrayExpr = new ArrayExpr(this.type, values.ToArray());

            // Return the resulting array construct.
            return(arrayExpr);
        }
Пример #8
0
        public List <Expr> Parse(ParserContext context)
        {
            // Ensure current token is parentheses start.
            context.Stream.EnsureCurrent(TokenType.SymbolParenthesesL);

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

            // Create the argument list result.
            List <Expr> args = new List <Expr>();

            // Contains at least one argument.
            if (context.Stream.Current.Type != TokenType.SymbolParenthesesR)
            {
                while (true)
                {
                    // Invoke the expression parser to parse the argument.
                    Expr arg = new ExprParser().Parse(context);

                    // Append the parsed argument.
                    args.Add(arg);

                    // Capture the current token's type.
                    TokenType currentTokenType = context.Stream.Current.Type;

                    // Arguments ended.
                    if (currentTokenType == TokenType.SymbolParenthesesR)
                    {
                        break;
                    }
                    // Otherwise, expect a comma.
                    else if (currentTokenType != TokenType.SymbolComma)
                    {
                        throw new Exception("Unexpected token in function call argument list");
                    }

                    // Skip token.
                    context.Stream.Skip();
                }
            }

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

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

            return(args);
        }
Пример #9
0
        public Function Parse(TokenStream stream)
        {
            // TODO: Use expression? Maybe add it to the body block?
            // Parse the expression.
            Expr expr = new ExprParser().Parse(stream);

            // Create the anonymous function.
            var function = new Function();

            // Set the function name to anonymous.
            function.SetNameAnonymous();

            // Create default prototype.
            function.CreatePrototype();

            // TODO: Finish implementing (continue Kaleidoscope tutorial).
            Block body = function.CreateBody();

            return(function);
        }
Пример #10
0
        public StructProperty Parse(ParserContext context)
        {
            // Invoke identifier parser.
            string identifier = new IdentifierParser().Parse(context);

            // Ensure current token is symbol colon.
            context.Stream.EnsureCurrent(TokenType.SymbolColon);

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

            // Invoke expression parser to capture the value.
            Expr value = new ExprParser().Parse(context);

            // Create the resulting property construct.
            StructProperty property = new StructProperty(identifier, value, this.index);

            // Return the resulting property construct.
            return(property);
        }
Пример #11
0
        public VarDeclareExpr Parse(TokenStream stream)
        {
            // Consume the type string.
            var typeValue = stream.Next().Value;

            // Create the type.
            var type = new Type(typeValue);

            // Create the variable declaration & link the type.
            var declaration = new VarDeclareExpr(type, null);

            // Consume the variable name.
            var name = stream.Next().Value;

            // Ensure captured name is not null nor empty.
            if (string.IsNullOrEmpty(name))
            {
                throw new Exception("Unexpected variable declaration identifier to be null or empty");
            }

            // Assign the name.
            declaration.SetName(name);

            // Peek next token for value.
            Token nextToken = stream.Peek();

            // Value is being assigned.
            if (nextToken.Type == TokenType.OperatorAssignment)
            {
                // Skip over the Assignment operator
                stream.Skip();

                // Parse value.
                Expr value = new ExprParser().Parse(stream);

                // Assign value.
                declaration.Value = value;
            }

            return(declaration);
        }
Пример #12
0
        public List <Expr> Parse(TokenStream stream)
        {
            // Create the argument list result.
            var args = new List <Expr>();

            // Contains at least one argument.
            if (stream.Get().Type != TokenType.SymbolParenthesesL)
            {
                while (true)
                {
                    // Invoke the expression parser to parse the argument.
                    Expr arg = new ExprParser().Parse(stream);

                    // Append the parsed argument.
                    args.Add(arg);

                    TokenType currentTokenType = stream.Get().Type;

                    // Arguments ended.
                    if (currentTokenType == TokenType.SymbolParenthesesR)
                    {
                        break;
                    }
                    // Otherwise, expect a comma.
                    else if (currentTokenType != TokenType.SymbolComma)
                    {
                        throw new Exception("Unexpected token in function call argument list");
                    }

                    // Skip token.
                    stream.Skip();
                }
            }

            return(args);
        }