Example #1
0
        public static bool parse(iSCOPE context)
        {
            Debug.Indent();
            Debug.WriteLine("Entering DECLARATION.parse");

            bool result = true;

            bool isHidden   = false;
            bool isFinal    = false;
            int  pure_safe  = 0;
            bool isOverride = false;
            bool isRoutine  = false;
            bool isAbstract = false;

            Token token = get();
            Token begin = token;

            // Collecting specifiers
            while (true)
            {
                switch (token.code)
                {
                case TokenCode.Abstract: isAbstract = true;                   forget(); break;

                case TokenCode.Override: isOverride = true;                   forget(); break;

                case TokenCode.Hidden: isHidden = true;                   forget(); break;

                case TokenCode.Final: isFinal = true; isRoutine = true; forget(); break;

                case TokenCode.Routine:                    isRoutine = true; forget(); break;

                case TokenCode.Pure: pure_safe = 1;     isRoutine = true; forget(); break;

                case TokenCode.Safe: pure_safe = 2;     isRoutine = true; forget(); break;

                default: goto OutLoop;
                }
                token = get();
            }
OutLoop:
            // Checking for a leading keyword
            switch (token.code)
            {
            case TokenCode.Unit:
                if (isOverride || isRoutine || pure_safe > 0)
                {
                    // Illegal specifier for unit declaration
                    error(token, "illegal-spec", begin, "unit declaration");
                }

                UNIT.parse(isHidden, isFinal, isAbstract, context);
                break;

            case TokenCode.Const:
                if (isRoutine || pure_safe > 0)
                {
                    // Illegal specifier for constant declaration
                    error(begin, "illegal-spec", begin, "object declaration");
                }

                Token start = token;
                forget(); token = get();
                if (token.code == TokenCode.Is)
                {
                    forget();
                    if (isOverride)
                    {
                        // Illegal specifier for constant declaration
                        error(begin, "illegal-spec", begin, "constant declaration");
                    }
                    CONSTANT.parse(isHidden, isFinal, start, context);
                }
                else
                {
                    if (pure_safe > 0)
                    {
                        // Illegal specifier for variable declaration
                        error(begin, "illegal-spec", begin, "variable declaration");
                    }
                    VARIABLE.parse(isHidden, isFinal, true, isOverride, null, null, context);
                }
                break;

            case TokenCode.Init:
                forget();
                if (isOverride || isFinal || isRoutine || pure_safe > 0)
                {
                    // Illegal specifier for initializer
                    error(begin, "illegal-spec", begin, "initializer declaration");
                }
                ROUTINE.parse(token, isHidden, isFinal, false, 0, context);
                break;

            case TokenCode.Identifier:
                // An identifier just following (optional) specifier(s)
                if (isRoutine || pure_safe > 0)
                {
                    // This is definitely a routine declaration
                    // (Some time after, 'isRoutine' might be removed...)
                    forget();
                    ROUTINE.parse(token, isHidden, isFinal, isOverride, pure_safe, context);
                }
                else
                {
                    // Decide whether this is variable or routine declaration
                    if (!isOverride || !isHidden || !isFinal)
                    {
                        if (!(context is UNIT))
                        {
                            // Tricky point:
                            // We are out of a unit context, i.e., within a routine
                            // or in a global scope, AND there is NO ONE specifier given.
                            // So, we conclude that identifier starts a statement
                            // but not a declaration.
                            // We do nothing and silently exit with result == false.
                            break;
                        }
                    }
                    Token id = token;
                    forget(); token = get();     // forget();
                    switch (token.code)
                    {
                    case TokenCode.LParen:
                    case TokenCode.LBracket:
                    case TokenCode.Then:
                    case TokenCode.Else:
                        ROUTINE.parse(id, isHidden, isFinal, isOverride, pure_safe, context);
                        break;

                    default:
                        forget();
                        VARIABLE.parse(isHidden, isFinal, false, isOverride, id, token, context);
                        break;
                    }
                    break;
                }
                break;

            default:
                // Some other token after optional specifier(s).
                // Perhaps this is an operator sign?
                Token name = ROUTINE.detectOperatorSign(token);
                if (name.code != TokenCode.ERROR)
                {
                    ROUTINE.parse(name, isHidden, isFinal, isOverride, pure_safe, context);
                }
                else if (isRoutine || isOverride || isHidden)
                {
                    // Syntax error in declaration
                    error(token, "syntax-error", "wrong declaration");
                    result = false;
                }
                else
                {
                    // What's this? -- something that is not a declaration.
                    // Don't issue a message
                    // error(token,"syntax-error");
                    result = false;
                }
                break;
            }

            Debug.WriteLine("Exiting DECLARATION.parse");
            Debug.Unindent();

            return(result);
        }
Example #2
0
        public static void parse(TokenCode stop1, TokenCode stop2, TokenCode stop3, iSCOPE context)
        {
            Debug.Indent();
            Debug.WriteLine("Entering BODY.parse");

            Token token;
            Token start = get();

            while (true)
            {
                bool res = STATEMENT.parse(context, stop1, stop2, stop3);

                if (!res)
                {
                    // Neither a statement nor a simple declaration.
                    // Perhaps, a nested/local function?
                    token = get();
                    switch (token.code)
                    {
                    case TokenCode.Routine:
                    case TokenCode.Safe:
                    case TokenCode.Pure:
                        forget();
                        int pure_safe = 0;
                        switch (token.code)
                        {
                        case TokenCode.Pure: pure_safe = 1; break;

                        case TokenCode.Safe: pure_safe = 2; break;
                        }
                        ROUTINE.parse(null, false, false, false, pure_safe, context);
                        break;

                    case TokenCode.Unit:
                    case TokenCode.Ref:
                    case TokenCode.Val:
                        // A _local_ unit???
                        UNIT.parse(context);
                        break;

                    default:
                        // What's this?
                        break;
                    }
                }

                token = get();
                if (token.code == TokenCode.Semicolon /*|| wasEOL*/)
                {
                    forget();
                }
                if (token.code == stop1)
                {
                    break;                        // don't 'forget()'
                }
                if (stop2 != TokenCode.ERROR && token.code == stop2)
                {
                    break;                                                    // don't 'forget()'
                }
                if (stop3 != TokenCode.ERROR && token.code == stop3)
                {
                    break;                                                    // don't 'forget()'
                }
            }

            BODY body = context as BODY;

            if (body == null) /* A system error */ } {
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static COMPILATION parse()
        {
            Debug.Indent();
            Debug.WriteLine("Entering COMPILATION.parse");

            COMPILATION compilation = new COMPILATION();

            Context.enter(compilation);

            Token start     = get();
            Token startAnon = null;
            Token endAnon   = null;

            int pure_safe = 0;

            while (true)
            {
                Token token = get();
                Token begin = token;
                switch (token.code)
                {
                case TokenCode.Final:
                    forget();
                    token = get();
                    switch (token.code)
                    {
                    case TokenCode.Unit:
                    case TokenCode.Package:
                    case TokenCode.Ref:
                    case TokenCode.Val:
                    case TokenCode.Concurrent:
                        // Don't forget()
                        UNIT.parse(false, true, false, compilation);
                        break;

                    case TokenCode.Abstract:
                        forget();
                        UNIT.parse(false, true, true, compilation);
                        break;

                    case TokenCode.Safe:
                    case TokenCode.Pure:
                    case TokenCode.Routine:
                        forget();
                        switch (token.code)
                        {
                        case TokenCode.Pure: pure_safe = 1; break;

                        case TokenCode.Safe: pure_safe = 2; break;
                        }
                        ROUTINE.parse(null, false, true, false, pure_safe, compilation);
                        pure_safe = 0;
                        break;
                    }
                    break;

                case TokenCode.Ref:
                case TokenCode.Val:
                case TokenCode.Concurrent:
                case TokenCode.Unit:
                case TokenCode.Package:
                    UNIT.parse(false, false, false, compilation);
                    break;

                case TokenCode.Abstract:
                    forget();
                    UNIT.parse(false, false, true, compilation);
                    break;

                case TokenCode.Use:
                    USE.parse(compilation);
                    break;

                case TokenCode.Routine:
                case TokenCode.Safe:
                case TokenCode.Pure:
                    forget();
                    switch (token.code)
                    {
                    case TokenCode.Pure: pure_safe = 1; break;

                    case TokenCode.Safe: pure_safe = 2; break;
                    }
                    ROUTINE.parse(null, false, false, false, pure_safe, compilation);
                    pure_safe = 0;
                    break;

                case TokenCode.EOS:
                    goto Finish;

                case TokenCode.EOL:
                    forget();
                    break;

                default:
                    // A call/assignment statement, or an error
                    if (startAnon == null)
                    {
                        startAnon = get();
                    }
                    bool result = STATEMENT.parse(compilation.anonymous.routineBody,
                                                  TokenCode.EOS, TokenCode.ERROR, TokenCode.ERROR);
                    if (!result)
                    {
                        // There was not a statement:
                        // apparently, this is a syntax error
                        goto Finish;
                    }
                    endAnon = get();
                    break;
                }
            }
Finish:
            compilation.setSpan(start, get());
            if (startAnon != null && endAnon != null)
            {
                compilation.anonymous.setSpan(startAnon, endAnon);
            }

            Debug.WriteLine("Exiting COMPILATION.parse");
            Debug.Unindent();

            Context.exit();
            return(compilation);
        }