Beispiel #1
0
    static tType StFunc(int F)
    {
        switch (F)
        {
        case spABS:
            IntExpression();
            Gen.Abs();
            return(tType.Int);

        case spMAX:
            ParseType();
            Gen.Cmd(int.MaxValue);
            return(tType.Int);

        case spMIN:
            ParseType();
            Gen.Min();
            return(tType.Int);

        case spODD:
            IntExpression();
            Gen.Odd();
            return(tType.Bool);
        }
        return(tType.None); // Чтоб не было предупреждений
    }
Beispiel #2
0
// Имя {"(" Выраж | Тип ")"} | Число | "(" Выраж ")"
    static tType Factor()
    {
        Obj   X;
        tType T = tType.None;

        if (Scan.Lex == tLex.lexName)
        {
            if ((X = Table.Find(Scan.Name)).Cat == tCat.Var)
            {
                Gen.Addr(X); //Адрес переменной
                Gen.Cmd(OVM.cmLoad);
                Scan.NextLex();
                return(X.Type);
            }
            else if (X.Cat == tCat.Const)
            {
                Gen.Const(X.Val);
                Scan.NextLex();
                return(X.Type);
            }
            else if (X.Cat == tCat.StProc &&
                     X.Type != tType.None)
            {
                Scan.NextLex();
                Check(tLex.lexLPar, "\"(\"");
                T = StFunc(X.Val);
                Check(tLex.lexRPar, "\")\"");
            }
            else
            {
                Error.Expected(
                    "переменная, константа или процедура-функции"
                    );
            }
        }
        else if (Scan.Lex == tLex.lexNum)
        {
            Gen.Const(Scan.Num);
            Scan.NextLex();
            return(tType.Int);
        }
        else if (Scan.Lex == tLex.lexLPar)
        {
            Scan.NextLex();
            T = Expression();
            Check(tLex.lexRPar, "\")\"");
        }
        else
        {
            Error.Expected("имя, число или \"(\"");
        }
        return(T);
    }
Beispiel #3
0
// ["+"|"-"] Слагаемое {ОперСлож Слагаемое}
    static tType SimpleExpr()
    {
        tType T;
        tLex  Op;

        if (Scan.Lex == tLex.lexPlus ||
            Scan.Lex == tLex.lexMinus)
        {
            Op = Scan.Lex;
            Scan.NextLex();
            if ((T = Term()) != tType.Int)
            {
                Error.Expected("выражение целого типа");
            }
            if (Op == tLex.lexMinus)
            {
                Gen.Cmd(OVM.cmNeg);
            }
        }
        else
        {
            T = Term();
        }
        if (Scan.Lex == tLex.lexPlus ||
            Scan.Lex == tLex.lexMinus)
        {
            if (T != tType.Int)
            {
                Error.Message(
                    "Несоответствие операции типу операнда"
                    );
            }
            do
            {
                Op = Scan.Lex;
                Scan.NextLex();
                if ((T = Term()) != tType.Int)
                {
                    Error.Expected("выражение целого типа");
                }
                switch (Op)
                {
                case tLex.lexPlus:  Gen.Cmd(OVM.cmAdd); break;

                case tLex.lexMinus: Gen.Cmd(OVM.cmSub); break;
                }
            } while(Scan.Lex == tLex.lexPlus ||
                    Scan.Lex == tLex.lexMinus);
        }
        return(T);
    }
Beispiel #4
0
// Переменная "=" Выраж
    static void AssStatement()
    {
        Variable();
        if (Scan.Lex == tLex.lexAss)
        {
            Scan.NextLex();
            IntExpression();
            Gen.Cmd(OVM.cmSave);
        }
        else
        {
            Error.Expected("\":=\"");
        }
    }
Beispiel #5
0
    static void WhileStatement()
    {
        int WhilePC = Gen.PC;

        Check(tLex.lexWHILE, "WHILE");
        BoolExpression();
        int CondPC = Gen.PC;

        Check(tLex.lexDO, "DO");
        StatSeq();
        Check(tLex.lexEND, "END");
        Gen.Cmd(WhilePC);
        Gen.Cmd(OVM.cmGOTO);
        Gen.Fixup(CondPC);
    }
Beispiel #6
0
// MODULE Имя ";" [Импорт] ПослОбъявл [BEGIN ПослОператоров]
// END Имя "."
    static void Module()
    {
        Obj ModRef; //Ссылка на имя модуля в таблице

        Check(tLex.lexMODULE, "MODULE");
        if (Scan.Lex != tLex.lexName)
        {
            Error.Expected("имя модуля");
        }
        //Имя модуля - в таблицу имен
        ModRef = Table.NewName(Scan.Name, tCat.Module);
        Scan.NextLex();
        Check(tLex.lexSemi, "\";\"");
        if (Scan.Lex == tLex.lexIMPORT)
        {
            Import();
        }
        DeclSeq();
        if (Scan.Lex == tLex.lexBEGIN)
        {
            Scan.NextLex();
            StatSeq();
        }
        Check(tLex.lexEND, "END");

        //Сравнение имени модуля и имени после END
        if (Scan.Lex != tLex.lexName)
        {
            Error.Expected("имя модуля");
        }
        else if (Scan.Name != ModRef.Name)
        {
            Error.Expected(
                "имя модуля \"" + ModRef.Name + "\""
                );
        }
        else
        {
            Scan.NextLex();
        }
        if (Scan.Lex != tLex.lexDot)
        {
            Error.Expected("\".\"");
        }
        Gen.Cmd(0);              // Код возврата
        Gen.Cmd(OVM.cmStop);     // Команда останова
        Gen.AllocateVariables(); // Размещение переменных
    }
Beispiel #7
0
    static void IfStatement()
    {
        int CondPC;
        int LastGOTO;

        Check(tLex.lexIF, "IF");
        LastGOTO = 0;    //Предыдущего перехода нет
        BoolExpression();
        CondPC = Gen.PC; //Запомн. положение усл. перехода
        Check(tLex.lexTHEN, "THEN");
        StatSeq();
        while (Scan.Lex == tLex.lexELSIF)
        {
            Gen.Cmd(LastGOTO);   //Фиктивный адрес, указывающий
            Gen.Cmd(OVM.cmGOTO); //на место предыдущего перехода
            LastGOTO = Gen.PC;   //Запомнить место GOTO
            Scan.NextLex();
            Gen.Fixup(CondPC);   //Зафикс. адрес условного перехода
            BoolExpression();
            CondPC = Gen.PC;     //Запомн. положение усл. перехода
            Check(tLex.lexTHEN, "THEN");
            StatSeq();
        }
        if (Scan.Lex == tLex.lexELSE)
        {
            Gen.Cmd(LastGOTO);   //Фиктивный адрес, указывающий
            Gen.Cmd(OVM.cmGOTO); //на место предыдущего перехода
            LastGOTO = Gen.PC;   //Запомнить место последнего GOTO
            Scan.NextLex();
            Gen.Fixup(CondPC);   //Зафикс. адрес условного перехода
            StatSeq();
        }
        else
        {
            Gen.Fixup(CondPC); //Если ELSE отсутствует
        }
        Check(tLex.lexEND, "END");
        Gen.Fixup(LastGOTO); //Направить сюда все GOTO
    }
Beispiel #8
0
// Множитель {ОперУмн Множитель}
    static tType Term()
    {
        tLex  Op;
        tType T = Factor();

        if (Scan.Lex == tLex.lexMult || Scan.Lex == tLex.lexDIV ||
            Scan.Lex == tLex.lexMOD)
        {
            if (T != tType.Int)
            {
                Error.Message(
                    "Несоответствие операции типу операнда"
                    );
            }
            do
            {
                Op = Scan.Lex;
                Scan.NextLex();
                if ((T = Factor()) != tType.Int)
                {
                    Error.Expected("выражение целого типа");
                }
                switch (Op)
                {
                case tLex.lexMult: Gen.Cmd(OVM.cmMult); break;

                case tLex.lexDIV:  Gen.Cmd(OVM.cmDiv); break;

                case tLex.lexMOD:  Gen.Cmd(OVM.cmMod); break;
                }
            } while(Scan.Lex == tLex.lexMult ||
                    Scan.Lex == tLex.lexDIV ||
                    Scan.Lex == tLex.lexMOD);
        }
        return(T);
    }
Beispiel #9
0
    static void StProc(int P)
    {
        switch (P)
        {
        case spDEC:
            Variable();
            Gen.Cmd(OVM.cmDup);
            Gen.Cmd(OVM.cmLoad);
            if (Scan.Lex == tLex.lexComma)
            {
                Scan.NextLex();
                IntExpression();
            }
            else
            {
                Gen.Cmd(1);
            }
            Gen.Cmd(OVM.cmSub);
            Gen.Cmd(OVM.cmSave);
            return;

        case spINC:
            Variable();
            Gen.Cmd(OVM.cmDup);
            Gen.Cmd(OVM.cmLoad);
            if (Scan.Lex == tLex.lexComma)
            {
                Scan.NextLex();
                IntExpression();
            }
            else
            {
                Gen.Cmd(1);
            }
            Gen.Cmd(OVM.cmAdd);
            Gen.Cmd(OVM.cmSave);
            return;

        case spInOpen:
            // Пусто ;
            return;

        case spInInt:
            Variable();
            Gen.Cmd(OVM.cmIn);
            Gen.Cmd(OVM.cmSave);
            return;

        case spOutInt:
            IntExpression();
            Check(tLex.lexComma, "\",\"");
            IntExpression();
            Gen.Cmd(OVM.cmOut);
            return;

        case spOutLn:
            Gen.Cmd(OVM.cmOutLn);
            return;

        case spHALT:
            Gen.Const(ConstExpr());
            Gen.Cmd(OVM.cmStop);
            return;
        }
    }