Example #1
0
 public UNIT_REF(UNIT u) : this()
 {
     name = u.name.identifier; unit_ref = u;
 }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <syntax>
        /// Объявление-контейнера
        ///         :   [ Спецификатор-контейнера ] unit Имя-контейнера [ FormalGenerics ]
        ///                 { Директива-контейнера }
        ///             is
        ///                 Тело-контейнера
        ///                 [ invariant Список-предикатов ]
        ///             end
        ///
        /// Спецификатор-контейнера
        ///         : ref | val | concurrent | abstract
        ///
        /// Имя-контейнера
        ///         : Составное-имя
        ///
        /// Директива-контейнера
        ///         : Директива-наследования
        ///         | Директива-использования
        ///
        /// Директива-наследования
        ///         : extend Базовый-контейнер { , Базовый-контейнер }
        ///
        /// Базовый-контейнер
        ///         : [ ~ ] UnitTypeName
        ///
        /// Тело-контейнера
        ///         : { Объявление }
        /// </syntax>
        /// <returns></returns>
        public static void parse(bool hidden, bool final, bool abstr, iSCOPE context)
        {
            Debug.Indent();
            Debug.WriteLine("Entering UNIT.parse");

            bool ref_val    = false;  // unit is reference by default
            bool concurrent = false;

            UNIT unit = null;

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

            TokenCode code = TokenCode.Unit;

            switch (token.code)
            {
            case TokenCode.Ref:
                ref_val = true;
                forget();
                code = getUnitKeyword();
                break;

            case TokenCode.Val:
                ref_val = false;
                forget();
                code = getUnitKeyword();
                break;

            case TokenCode.Abstract:
                abstr = true;
                forget();
                code = getUnitKeyword();
                break;

            case TokenCode.Concurrent:
                concurrent = true;
                forget();
                code = getUnitKeyword();
                break;

            case TokenCode.Unit:
                code = TokenCode.Unit;
                forget();
                break;

            case TokenCode.Package:
                code = TokenCode.Package;
                forget();
                break;
            }

            // 1. Unit header

            token = expect(TokenCode.Identifier);
            Token compoundName = IDENTIFIER.parseCompoundName(token);

            if (code == TokenCode.Package)
            {
                if (!ENTITY.options.optConfig)
                {
                    warning(token, "no-config");
                    unit = new UNIT(compoundName.image, ref_val, abstr, concurrent);
                }
                else
                {
                    unit = new PACKAGE(compoundName.image, ref_val, abstr, concurrent);
                }
            }
            else
            {
                unit = new UNIT(compoundName.image, ref_val, abstr, concurrent);
            }

            Debug.WriteLine("======================" + compoundName.image);

            unit.parent = context.self;
            unit.setSpecs(hidden, final);
            Context.enter(unit);

            // 2. Generic parameters

            token = get();
            if (token.code == TokenCode.LBracket)
            {
                forget();
                while (true)
                {
                    var generic = FORMAL_GENERIC.parse(unit);
                    unit.add(generic);

                    token = get();
                    switch (token.code)
                    {
                    case TokenCode.Comma:
                    case TokenCode.Semicolon: forget(); continue;

                    case TokenCode.RBracket:  forget(); goto Finish;

                    default: { /* Syntax error */ break; }
                    }
                }
Finish:
                ;
            }

            // Possible unit alias

            token = get();
            if (token.code == TokenCode.Alias)
            {
                forget();
                token      = expect(TokenCode.Identifier);
                unit.alias = new IDENTIFIER(token);
            }

            // 3. Unit directives: inheritance

            token = get();
            if (token.code == TokenCode.Extend)
            {
                forget();
                while (true)
                {
                    PARENT parent = PARENT.parse(unit);
                    if (parent == null) /* Syntax error */ break {
                        ;
                    }
                    unit.add(parent);

                    token = get();
                    switch (token.code)
                    {
                    case TokenCode.Comma:
                    case TokenCode.Semicolon:
                    case TokenCode.EOL:
                        forget();
                        continue;

                    default:
                        goto Use;
                    }
                }
            }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static new EXPRESSION parse(Token first, iSCOPE context)
        {
            EXPRESSION result = null;
            Token      token  = (first == null) ? get() : first;
            Token      begin  = token;

            switch (token.code)
            {
            case TokenCode.This:
                forget();
                UNIT unit = Context.unit();
                if (unit == null)
                {
                    // Error message!
                    result = new THIS(null);
                }
                else
                {
                    result = new THIS(unit);
                    result.setSpan(token);
                }
                break;

            case TokenCode.Return:
                if (!ENTITY.weAreWithinEnsure)
                {
                    break;
                }
                forget();
                ROUTINE routine = Context.routine();
                if (routine == null)
                {
                }       // error
                else
                {
                    result = new RETURN_EXPR(routine);
                    result.setSpan(token);
                }
                break;

            case TokenCode.Old:
                forget();
                result = EXPRESSION.parse(null, context);
                Span end = result.span;
                OLD  old = new OLD(result);
                result.parent = old;
                result        = old;
                result.setSpan(begin.span, end);
                break;

            case TokenCode.If:
                result = CONDITIONAL.parse(context);
                break;

            case TokenCode.LParen:
                forget();
                Span start_tuple = token.span;
                result = EXPRESSION.parse(null, context);
                token  = get();
                if (token.code == TokenCode.Comma)
                {
                    // Seems to be a tuple
                    forget();
                    TUPLE_EXPR tuple = new TUPLE_EXPR();
                    tuple.add(result);
                    while (true)
                    {
                        EXPRESSION expr = EXPRESSION.parse(null, context);
                        tuple.add(expr);

                        token = get();
                        if (token.code != TokenCode.Comma)
                        {
                            break;
                        }
                        forget();
                    }
                    result = tuple;
                }
                end = expect(TokenCode.RParen).span;
                result.setSpan(token.span, end);
                break;

            case TokenCode.Identifier:
                if (first == null)
                {
                    forget();                      ////// perhaps the same condition should be added for all cases?
                }
                DECLARATION d = Context.find(token);
                if (d == null)
                {
                    result = new UNRESOLVED(context, new IDENTIFIER(token));
                }
                else
                {
                    result = new REFERENCE(d);
                }

                Token token2 = get();
                if (token2.code == TokenCode.LBracket)
                {
                    UNIT_REF unitRef = UNIT_REF.parse(token, false, context);
                    result = new NEW(unitRef);
                    result.setSpan(unitRef.span);
                }
                else
                {
                    result.setSpan(token);
                }
                break;

            case TokenCode.Integer:
            case TokenCode.Real:
            case TokenCode.String:
            case TokenCode.Character:
                result = new LITERAL(token.value, token.span, token.code);
                result.setSpan(token);
                forget();
                break;

            default:
                return(null);
            }
            // result.setSpan(token);
            return(result);
        }
Example #4
0
 public THIS(UNIT u) : base()
 {
     unit = u;
     type = new UNIT_REF(u);
 }
Example #5
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 #6
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 #7
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);
        }