Exemplo n.º 1
0
        public static void Main(string[] args)
        {
            bool   mergeErrors = false, execution = true, immediate = false;
            string inputName = null;

            // ------------------------ process command line parameters:

            Console.WriteLine("Parva compiler 2.2017 October");

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].ToLower().Equals("-l"))
                {
                    mergeErrors = true;
                }
                else if (args[i].ToLower().Equals("-d"))
                {
                    Parser.debug = true;
                }
                else if (args[i].ToLower().Equals("-n"))
                {
                    execution = false;
                }
                else if (args[i].ToLower().Equals("-g"))
                {
                    immediate = true;
                }
                else if (args[i].ToLower().Equals("-c"))
                {
                    Parser.listCode = true;
                }
                else if (args[i].ToLower().Equals("-w"))
                {
                    Parser.warnings = false;
                }
                else
                {
                    inputName = args[i];
                }
            }
            if (inputName == null)
            {
                Console.WriteLine("No input file specified");
                Console.WriteLine("Usage: Parva [-l] [-d] [-n] [-g] source.pav");
                Console.WriteLine("-l directs source listing to listing.txt");
                Console.WriteLine("-d turns on debug mode");
                Console.WriteLine("-n no execution after compilation");
                Console.WriteLine("-g execute immediately after compilation (StdIn/StdOut)");
                Console.WriteLine("-c produce .cod listing");
                Console.WriteLine("-w supress warning messages");
                System.Environment.Exit(1);
            }

            // ------------------------ parser and scanner initialization

            int pos = inputName.LastIndexOf('/');

            if (pos < 0)
            {
                pos = inputName.LastIndexOf('\\');
            }
            string dir = inputName.Substring(0, pos + 1);

            Scanner.Init(inputName);
            Errors.Init(inputName, dir, mergeErrors);
            PVM.Init();
            Table.Init();

            // ------------------------ compilation

            Parser.Parse();
            Errors.Summarize();

            // ------------------------ interpretation

            bool   assembledOK = Parser.Successful();
            int    initSP      = CodeGen.GetInitSP();
            string codeName    = newFileName(inputName, ".cod");
            int    codeLength  = CodeGen.GetCodeLength();

            PVM.ListCode(codeName, codeLength);
            if (!assembledOK || codeLength == 0)
            {
                Console.WriteLine("Unable to interpret code");
                System.Environment.Exit(1);
            }
            else if (!execution)
            {
                Console.WriteLine("\nCompiled: exiting with no execution requested");
                System.Environment.Exit(1);
            }
            else
            {
                if (immediate)
                {
                    PVM.QuickInterpret(codeLength, initSP);
                }
                char reply = 'n';
                do
                {
                    Console.Write("\n\nInterpret [y/N]? ");
                    reply = (Console.ReadLine() + " ").ToUpper()[0];
                    if (reply == 'Y')
                    {
                        PVM.Interpret(codeLength, initSP);
                    }
                } while (reply == 'Y');
            }
        } // Main
Exemplo n.º 2
0
 static void ReturnStatement()
 {
     Expect(return_Sym);
     CodeGen.LeaveVoidFunction();
     ExpectWeak(semicolon_Sym, 6);
 }
Exemplo n.º 3
0
        static void Factor(out int type)
        {
            type = Types.noType;
            int      size;
            DesType  des;
            ConstRec con;

            if (la.kind == identifier_Sym)
            {
                Designator(out des);
                type = des.type;
                switch (des.entry.kind)
                {
                case Kinds.Var:
                    CodeGen.Dereference();
                    break;

                case Kinds.Con:
                    CodeGen.LoadConstant(des.entry.value);
                    break;

                default:
                    SemError("wrong kind of identifier");
                    break;
                }
            }
            else if (StartOf(15))
            {
                Constant(out con);
                type = con.type;
                CodeGen.LoadConstant(con.value);
            }
            else if (la.kind == new_Sym)
            {
                Get();
                BasicType(out type);
                type++;
                Expect(lbrack_Sym);
                Expression(out size);
                if (!IsArith(size))
                {
                    SemError("array size must be integer");
                }
                CodeGen.Allocate();
                Expect(rbrack_Sym);
            }
            else if (la.kind == bang_Sym)
            {
                Get();
                Factor(out type);
                if (!IsBool(type))
                {
                    SemError("boolean operand needed");
                }
                else
                {
                    CodeGen.NegateBoolean();
                }
                type = Types.boolType;
            }
            else if (la.kind == lparen_Sym)
            {
                Get();
                Expression(out type);
                Expect(rparen_Sym);
            }
            else
            {
                SynErr(58);
            }
        }
Exemplo n.º 4
0
 static void HaltStatement()
 {
     Expect(halt_Sym);
     CodeGen.LeaveProgram();
     ExpectWeak(semicolon_Sym, 6);
 }
Exemplo n.º 5
0
        static void AddExp(out int type)
        {
            int   type2;
            int   op;
            Label shortcircuit = new Label(!known);

            type = Types.noType;
            if (la.kind == plus_Sym)
            {
                Get();
                Term(out type);
                if (!IsArith(type))
                {
                    SemError("arithmetic operand needed");
                }
            }
            else if (la.kind == minus_Sym)
            {
                Get();
                Term(out type);
                if (!IsArith(type))
                {
                    SemError("arithmetic operand needed");
                }
                CodeGen.NegateInteger();
            }
            else if (StartOf(13))
            {
                Term(out type);
            }
            else
            {
                SynErr(55);
            }
            while (la.kind == plus_Sym || la.kind == minus_Sym || la.kind == barbar_Sym)
            {
                AddOp(out op);
                if (op == CodeGen.or)
                {
                    CodeGen.BooleanOp(shortcircuit, CodeGen.or);
                }
                Term(out type2);
                switch (op)
                {
                case CodeGen.or:
                    if (!IsBool(type) || !IsBool(type2))
                    {
                        SemError("boolean operands needed");
                    }
                    type = Types.boolType;
                    break;

                default:
                    if (!IsArith(type) || !IsArith(type2))
                    {
                        SemError("arithmetic operands needed");
                        type = Types.noType;
                    }
                    CodeGen.BinaryOp(op);
                    break;
                }
            }
            shortcircuit.Here();
        }