Esempio n. 1
0
        public Expr Parse(TokenStream stream)
        {
            TokenType nextTokenType = stream.Peek().Type;

            // Variable declaration expression.
            if (TokenIdentifier.IsType(nextTokenType))
            {
                return(new VarDeclareExprParser().Parse(stream));
            }
            // Numeric expression.
            else if (TokenIdentifier.IsNumeric(nextTokenType))
            {
                return(new NumericExprParser().Parse(stream));
            }
            // Identifier expression.
            else if (nextTokenType == TokenType.Identifier)
            {
                return(new IdentifierExprParser().Parse(stream));
            }
            // Parentheses expression.
            else if (nextTokenType == TokenType.SymbolParenthesesL)
            {
                return(new ParenthesesExprParser().Parse(stream));
            }

            // At this point, return null.
            return(null);
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        public FormalArg Parse(TokenStream stream)
        {
            // Initialize the type value.
            string typeValue;

            // Check if the next token is a type
            if (TokenIdentifier.IsType(stream.Peek()))
            {
                // Capture argument type value.
                typeValue = stream.Next().Value;
            }
            else
            {
                // TODO: Better error lol.
                throw new Exception("Oops you need a type!");
            }

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

            // Create the formal argument entity.
            var arg = new FormalArg(type);

            // Capture the argument's name.
            var name = stream.Next(TokenType.Identifier).Value;

            // Assign the argument's name.
            arg.SetName(name);

            return(arg);
        }
Esempio n. 4
0
        public Type Parse(TokenStream stream)
        {
            // Consume type token.
            Token type = stream.Next();

            // Ensure type value is a type.
            if (!TokenIdentifier.IsType(type))
            {
                throw new Exception($"Expected a type but got '{type.Type}'");
            }

            // Create the type.
            return(new Type(type.Value));
        }
Esempio n. 5
0
        public Expr Parse(ParserContext context)
        {
            // Capture the current token's type.
            Token token = context.Stream.Current;

            // Variable declaration expression.
            if (TokenIdentifier.IsType(token, context))
            {
                return(new VarDeclareExprParser().Parse(context));
            }
            // If expression.
            else if (token.Type == TokenType.KeywordIf)
            {
                return(new IfExprParser().Parse(context));
            }

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

            // Return the parsed expression.
            return(expr);
        }
Esempio n. 6
0
        /// <summary>
        ///     Process the next sequence. Returns true
        ///     if the sequence was successfully processed.
        /// </summary>
        public bool Next()
        {
            // TODO: What if EOF token has not been processed itself?
            // End reached.
            if (stream.LastItem)
            {
                return(false);
            }

            // TODO: Finish fixing this, parsers overflowing (+1) because of this issue with the Program start (05/02/2019).
            TokenType type = stream.Get().Type;

            // Skip program start token.
            if (type == TokenType.ProgramStart)
            {
                stream.Skip();

                // Assign type as next token type, continue execution.
                type = stream.Get().Type;
            }

            // Skip unknown tokens for error recovery.
            if (type == TokenType.Unknown)
            {
                // TODO: Use error reporting.
                Console.WriteLine("Warning: Skipping unknown token");

                return(false);
            }
            // Function definition or global variable.
            else if (TokenIdentifier.IsType(type))
            {
                // Peek the token after identifier.
                Token afterIdentifier = stream.Peek(2);

                // Function definition.
                if (afterIdentifier.Type == TokenType.SymbolParenthesesL)
                {
                    // Invoke the function parser.
                    Function function = new FunctionParser().Parse(stream);

                    // Emit the function.
                    function.Emit(Module.Source);
                }
                // Otherwise, global variable declaration.
                else
                {
                    // Invoke the global variable parser.
                    GlobalVar globalVariable = new GlobalVarParser().Parse(stream);

                    // Emit the global variable.
                    globalVariable.Emit(Module.Source);
                }
            }
            // External definition.
            else if (type == TokenType.KeywordExternal)
            {
                // Invoke the external definition parser.
                Extern external = new ExternParser().Parse(stream);

                // Emit the external definition.
                external.Emit(Module.Source);
            }
            // Otherwise, top-level expression.
            else
            {
                // Invoke the top-level expression parser.
                Function exprDelegate = new TopLevelExprParser().Parse(stream);

                // Emit the top-level expression.
                exprDelegate.Emit(Module.Source);
            }

            // At this point, an entity was processed.
            return(true);
        }
Esempio n. 7
0
        public Type Parse(ParserContext context)
        {
            // Capture current type token.
            Token token = context.Stream.Current;

            // Ensure current token is a type.
            if (!TokenIdentifier.IsType(token, context))
            {
                throw new Exception($"Expected a type but got '{token.Type}'");
            }

            // Skip and capture the next token.
            Token nextToken = context.Stream.Next();

            // Create the array length (and flag), defaulting to null.
            uint?arrayLength = null;

            // Determine if type is an array.
            if (nextToken.Type == TokenType.SymbolBracketL)
            {
                // Skip bracket start token.
                context.Stream.Skip();

                // TODO: Must ensure array length is integer somehow.
                // TODO: Invoke expression parser to capture array length.
                // TODO: arrayLength.Value = new ExprParser().Parse(context);

                // TODO: BEGIN temporary solution.

                // Ensure current token is an integer.
                context.Stream.EnsureCurrent(TokenType.LiteralInteger);

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

                // Assign the token value as the array length.
                arrayLength = uint.Parse(integerToken.Value);

                // Skip over the captured integer token.
                context.Stream.Skip();

                // TODO: END temporary solution.

                // Ensure the current token is a closing bracket.
                context.Stream.EnsureCurrent(TokenType.SymbolBracketR);

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

            // Update the next token buffer.
            nextToken = context.Stream.Get();

            // Create the pointer flag.
            bool isPointer = false;

            // Determine if pointer sequence exists.
            if (nextToken.Type == TokenType.OperatorMultiplication)
            {
                // Raise the pointer flag.
                isPointer = true;

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

            // Create the type.
            return(new Type(context.SymbolTable, token, isPointer, arrayLength));
        }