예제 #1
0
        public static string ParsePath(Parser.State state)
        {
            StringBuilder pathBuilder = new StringBuilder();

            while (true)
            {
                if (state.GetToken().Type != TokenType.Identifier)
                {
                    state.ErrorCode    = (uint)ErrorCodes.P_IdentifierExpected;
                    state.ErrorMessage =
                        $"Expected path name(<identifier>) " +
                        $"but <{state.GetToken().SubType.ToString()}> " +
                        $"were given";
                    return(null);
                }

                pathBuilder.Append(state.GetToken().Value);
                if (state.GetNextNEToken().SubType == TokenSubType.Colon)
                {
                    pathBuilder.Append(":");
                    state.GetNextNEToken();
                    continue;
                }

                break;
            }

            return(pathBuilder.ToString());
        }
예제 #2
0
        private static bool ParseUse(Parser.State state, CoreNode coreNode)
        {
            if (state.IsErrorOccured())
            {
                return(false);
            }
            if (state.GetToken().Type != TokenType.CompilerDirective)
            {
                return(false);
            }
            if (state.GetToken().Value != "#use")
            {
                return(false);
            }

            state.GetNextNEToken();

            Console.WriteLine("[P]   #use directive found");
            string usePath  = TypeParser.ParsePath(state);
            string useAlias = null;

            if (state.IsErrorOccured())
            {
                return(false);
            }

            if (state.GetToken().Is(TokenType.Identifier, "as"))
            {
                state.GetNextNEToken();
                useAlias = TypeParser.ParsePath(state);

                if (state.IsErrorOccured())
                {
                    return(false);
                }
            }

            coreNode.UsesNodes.Add(new UseNode(usePath, useAlias));
            return(true);
        }
예제 #3
0
        public static BlockNode ParseBlock(Parser.State state)
        {
            if (!state.GetToken().Is(TokenSubType.BraceCurlyLeft, "{"))
            {
                return(null);
            }

            var block = new BlockNode();

            state.GetNextNEToken();
            while (!state.GetToken().Is(TokenSubType.BraceCurlyRight, "}"))
            {
                block.Code.Add(ExpressionParser.Parse(state));
                if (state.IsErrorOccured())
                {
                    return(block);
                }
            }
            state.GetNextNEToken();

            return(block);
        }
예제 #4
0
        public static void ParseParametersList(Parser.State state, FunctionNode function)
        {
            while (!state.GetToken().Is(TokenSubType.BraceRoundRight, ")"))
            {
                if (state.GetToken().Type != TokenType.Identifier)
                {
                    state.ErrorCode    = (uint)ErrorCodes.P_IdentifierExpected;
                    state.ErrorMessage =
                        $"Expected parameter name(<identifier>) " +
                        $"but <{state.GetToken().SubType}>({state.GetToken().Value}) " +
                        $"were given";
                    return;
                }

                var parameterName = state.GetTokenAndMoveNE().Value;

                if (!state.GetToken().Is(TokenSubType.Colon, ":"))
                {
                    state.ErrorCode    = (uint)ErrorCodes.P_ColonBeforeTypeSpeceficationNotFound;
                    state.ErrorMessage =
                        $"Expected <Colon>(:) before parameter type specification " +
                        $"but <{state.GetToken().SubType}>({state.GetToken().Value}) were given";
                    return;
                }
                state.GetNextNEToken();

                var parameterType = TypeParser.Parse(state);

                function.Parameters.Add(new VariableNode
                {
                    Name = parameterName,
                    Type = parameterType
                });

                if (state.GetToken().SubType == TokenSubType.Comma)
                {
                    state.GetNextNEToken();
                }
            }

            state.GetNextNEToken();
        }
예제 #5
0
        public static TypeNode Parse(Parser.State state)
        {
            state.Save();
            TypeNode type = new TypeNode();

            while (true)
            {
                var tok = state.GetToken();
                if (tok.Is(TokenType.Identifier, "const"))
                {
                    if (type.IsConstant)
                    {
                        state.ErrorCode    = (uint)ErrorCodes.P_DuplicatedModifier;
                        state.ErrorMessage =
                            "<const> type modifier can not be used twice" +
                            " for the same type";
                        return(null);
                    }

                    type.IsConstant = true;
                }
                else if (tok.Is(TokenType.Identifier, "ref"))
                {
                    state.GetNextNEToken();
                    type.IsReference   = true;
                    type.ReferenceType = Parse(state);

                    if (type.IsConstant)
                    {
                        state.ErrorCode    = (uint)ErrorCodes.P_ReferenceCanNotBeConstant;
                        state.ErrorMessage =
                            "Reference can not have a constant modifier:\n" +
                            type.ToString();
                    }

                    return(type);
                }
                else if (tok.Is(TokenSubType.BraceSquareLeft, "["))
                {
                    state.GetNextNEToken();
                    type.IsArrayType = true;

                    // TODO: Parse sizes
                    if (!state.GetToken().Is(TokenSubType.BraceSquareRight, "]"))
                    {
                        state.ErrorCode    = 999;
                        state.ErrorMessage =
                            "Array does not support sizes and dimmensions " +
                            "in the current version";
                        return(type);
                    }
                    state.GetNextNEToken();

                    type.ReferenceType = Parse(state);

                    if (type.ReferenceType.IsReference)
                    {
                        state.ErrorCode    = (uint)ErrorCodes.P_ArrayCanNotContainReferences;
                        state.ErrorMessage =
                            "Array can not consist of references";
                    }

                    return(type);
                }
                else
                {
                    // End of modifiers
                    break;
                }

                state.GetNextNEToken();
            }

            type.TypePath = ParsePath(state);
            return(type);
        }
예제 #6
0
        private static bool ParseFunctionDeclaration(Parser.State state, CoreNode coreNode)
        {
            state.Save();

            if (state.GetToken().Type != TokenType.Identifier)
            {
                state.Restore();
                return(false);
            }

            string name = state.GetTokenAndMoveNE().Value;

            if (!state.GetToken().Is(TokenSubType.Colon, ":"))
            {
                state.ErrorCode    = (uint)ErrorCodes.P_ColonBeforeTypeSpeceficationNotFound;
                state.ErrorMessage =
                    $"Expected <Colon>(:) before function type specification " +
                    $"but <{state.GetToken().SubType}>({state.GetToken().Value}) were given";
                return(false);
            }
            state.GetNextNEToken();

            TypeNode type = TypeParser.Parse(state);

            if (state.IsErrorOccured())
            {
                return(false);
            }

            /*
             * // Only for class methods
             * bool isInstance = state.GetToken().Is(TokenSubType.Dot, ".");
             * bool isStatic = state.GetToken().Is(TokenSubType.Colon, ":");
             *
             * if (!(isStatic || isInstance))
             * {
             *  state.ErrorCode = (uint)ErrorCodes.P_MethodTypeExpected;
             *  state.ErrorMessage =
             *      $"Expected '.' or ':' as type modifier, but " +
             *      $"<{state.GetToken().SubType.ToString()}> were found";
             *  return false;
             * }
             */

            FunctionNode function = new FunctionNode
            {
                Parent = coreNode,
                Name   = name,
                Type   = FunctionNode.EType.Static,

                ReturnType = type
            };

            coreNode.FunctionNodes.Add(function);

            if (!state.GetToken().Is(TokenSubType.BraceRoundLeft, "("))
            {
                state.ErrorCode    = (uint)ErrorCodes.P_OpeningBracketExpected;
                state.ErrorMessage =
                    $"Opening round bracket is expected before parameters list " +
                    $"but <{state.GetToken().SubType}> were given";

                return(false);
            }

            state.GetNextNEToken();
            FunctionParser.ParseParametersList(state, function);
            if (state.IsErrorOccured())
            {
                return(true);
            }

            // FunctionParser.ParseTemplateValues(state, function);
            function.Code = CodeParser.Parse(state);
            return(!state.IsErrorOccured());
        }