void Stat()
        {
            int type; string name; Obj obj; int reg = 0, index1 = 0; string arrayName;

            switch (la.kind)
            {
            case 2: {
                Ident(out name);
                obj = tab.Find(name);
                if (la.kind == 24)
                {
                    Get();
                    Expect(1);
                    index1 = Convert.ToInt32(t.val);
                    if (index1 > obj.index | index1 < 0)
                    {
                        SemErr("Wrong index");
                    }

                    Expect(25);
                }
                if (la.kind == 26)
                {
                    Get();
                    if (obj.kind == proc || (obj.kind == constant && obj.assign))
                    {
                        if (obj.kind != constant)
                        {
                            SemErr("cannot assign to procedure");
                        }
                        else
                        {
                            SemErr("Cannot re-asign already assign constant");
                        }
                    }

                    if (StartOf(3))
                    {
                        Expr(out reg,
                             out type);
                        if (type == obj.type)
                        {
                            if (obj.level == 0)
                            {
                                gen.StoreGlobal(reg, obj.adr, name);
                            }
                            else
                            {
                                gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr, name);
                            }
                        }
                        if (obj.kind == constant)
                        {
                            obj.assign = true;
                        }
                    }
                    else if (la.kind == 24)
                    {
                        Get();
                        int arrayIndex = 0;
                        Expect(1);
                        index1 = Convert.ToInt32(t.val);
                        Expect(25);
                        Ident(out arrayName);
                        Obj holder1 = tab.Find(arrayName);

                        if (arrayIndex > holder1.index || arrayIndex < 0)
                        {
                            SemErr("Array index out of bounds");
                        }

                        if (holder1.type != obj.type)
                        {
                            SemErr("Wrong types");
                        }

                        if (holder1.kind == var || holder1.kind == constant)
                        {
                            if (holder1.level == 0)
                            {
                                gen.LoadGlobal(reg, holder1.adr + arrayIndex, arrayName);
                            }
                            else
                            {
                                gen.LoadLocal(reg, tab.curLevel - obj.level, holder1.adr + arrayIndex, arrayName);
                            }

                            if (obj.type == boolean)
                            {
                                gen.ResetZ(reg);
                            }

                            if (obj.level == 0)
                            {
                                gen.StoreGlobal(reg, obj.adr + index1, name);
                            }
                            else
                            {
                                gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr + index1, name);
                            }
                            obj.assign = true;
                        }
                    }
                    else if (la.kind == 19)
                    {
                        Get();
                        Expr(out reg,
                             out type);
                        Expect(20);
                        Expect(27);
                        int reg1, type1, reg2, type2;
                        int l1 = 0; int l2 = 1;
                        if (type == boolean)
                        {
                            l1 = gen.NewLabel();
                            gen.BranchFalse(l1);
                        }
                        else
                        {
                            SemErr("Bool expected");
                        }

                        Expr(out reg1,
                             out type1);
                        Expect(28);
                        l2 = gen.NewLabel();

                        gen.Branch(l2);
                        gen.Label(l1);
                        if (obj.level == 0)
                        {
                            gen.StoreGlobal(reg1, obj.adr + index1, name);
                        }
                        else
                        {
                            gen.StoreLocal(reg, tab.curLevel - obj.level, obj.adr + index1, name);
                        }


                        Expr(out reg2,
                             out type2);
                        gen.Label(l2);
                        if (obj.level == 0)
                        {
                            gen.StoreGlobal(reg2, obj.adr + index1, name);
                        }
                        else
                        {
                            gen.StoreLocal(reg2, tab.curLevel - obj.level, obj.adr + index1, name);
                        }
                    }
                    else
                    {
                        SynErr(48);
                    }
                    Expect(29);
                }
                else if (la.kind == 8)
                {
                    Get();
                    Expect(9);
                    Expect(29);
                    if (obj.kind == proc)
                    {
                        gen.Call(name);
                    }
                    else
                    {
                        SemErr("object is not a procedure");
                    }
                }
                else
                {
                    SynErr(49);
                }
                break;
            }

            case 30: {
                Get();
                int l1, l2; l1 = 0;
                Expr(out reg,
                     out type);
                if (type == boolean)
                {
                    l1 = gen.NewLabel();
                    gen.BranchFalse(l1);
                }
                else
                {
                    SemErr("boolean type expected");
                }

                l2 = gen.NewLabel();
                gen.Branch(l2);
                gen.Label(l1);

                if (la.kind == 31)
                {
                    Get();
                    Stat();
                }
                gen.Label(l2);
                break;
            }

            case 32: {
                Get();
                int l1, l2;
                l1 = gen.NewLabel();
                gen.Label(l1); l2 = 0;

                Expr(out reg,
                     out type);
                if (type == boolean)
                {
                    l2 = gen.NewLabel();
                    gen.BranchFalse(l2);
                }
                else
                {
                    SemErr("boolean type expected");
                }

                Stat();
                gen.Branch(l1);
                gen.Label(l2);

                break;
            }

            case 33: {
                Get();
                Expect(8);
                Stat();
                int loop, exit;
                loop = gen.NewLabel();
                gen.Label(loop); exit = 0;

                Stat();
                Expr(out reg,
                     out type);
                if (type == boolean)
                {
                    gen.BranchFalse(exit);
                }
                else
                {
                    SemErr("Bool expected");
                }


                Expect(9);
                Expect(34);
                Expect(16);
                Stat();
                Expect(17);
                gen.Branch(loop);
                gen.Label(exit);

                break;
            }

            case 35: {
                Get();
                Ident(out name);
                Expect(29);
                obj = tab.Find(name);
                if (obj.type == integer)
                {
                    gen.ReadInteger();
                    if (obj.level == 0)
                    {
                        gen.StoreGlobal(0, obj.adr, name);
                    }
                    else
                    {
                        gen.StoreLocal(0, tab.curLevel - obj.level, obj.adr, name);
                    }
                }
                else
                {
                    SemErr("integer type expected");
                }

                break;
            }

            case 36: {
                Get();
                string text;
                if (StartOf(3))
                {
                    Expr(out reg,
                         out type);
                    switch (type)
                    {
                    case integer: gen.WriteInteger(reg, false);
                        break;

                    case boolean: gen.WriteBoolean(false);
                        break;
                    }
                }
                else if (la.kind == 3)
                {
                    String(out text);
                    gen.WriteString(text);
                }
                else
                {
                    SynErr(50);
                }
                Expect(29);
                break;
            }

            case 37: {
                Get();
                Expr(out reg,
                     out type);
                switch (type)
                {
                case integer: gen.WriteInteger(reg, true);
                    break;

                case boolean: gen.WriteBoolean(true);
                    break;
                }

                Expect(29);
                break;
            }

            case 16: {
                Get();
                tab.OpenSubScope();
                while (StartOf(4))
                {
                    if (la.kind == 41)
                    {
                        ConstantDecl();
                    }
                    else if (la.kind == 39 || la.kind == 40)
                    {
                        VarDecl();
                    }
                    else
                    {
                        Stat();
                    }
                }
                Expect(17);
                tab.CloseSubScope();
                break;
            }

            default: SynErr(51); break;
            }
        }
示例#2
0
        // close current scope
        public void CloseScope()
        {
            Obj obj, scope;

            scope = topScope;
            String str;

            while (scope != null)
            {
                obj = scope.locals;
                while (obj != null)
                { // for all objects in this scope
                    str  = "; ";
                    str += obj.name + " is a ";


                    if (obj.kind == 0)
                    {
                        if (obj.level >= 1)
                        {
                            str += "local variable ";
                        }
                        else
                        {
                            str += "global variable ";
                        }

                        str += "of type ";

                        if (obj.type == 0)
                        {
                            str += "undefined";
                        }

                        else if (obj.type == 1)
                        {
                            str += "Integer ";
                        }

                        else
                        {
                            str += "Boolean ";
                        }
                    }

                    else if (obj.kind == 1)
                    {
                        str += "procedure ";
                    }

                    else if (obj.kind == 2)
                    {
                        str += "scope ";
                    }

                    else
                    {
                        str = "constant ";
                    }


                    Console.WriteLine(str);
                    obj = obj.next;
                }
                scope = scope.outer;
            }
            topScope = topScope.outer;
            curLevel--;
        }