Пример #1
0
        static void Designator(out DesType des)
        {
            string name;
            int    indexType;

            Ident(out name);
            Entry entry = Table.Find(name);

            if (!entry.declared)
            {
                SemError("undeclared identifier");
            }
            des = new DesType(entry);
            if (entry.kind == Kinds.Var)
            {
                CodeGen.LoadAddress(entry);
            }
            if (la.kind == lbrack_Sym)
            {
                Get();
                if (IsArray(des.type))
                {
                    des.type--;
                }
                else
                {
                    SemError("unexpected subscript");
                }
                if (des.entry.kind != Kinds.Var)
                {
                    SemError("unexpected subscript");
                }
                CodeGen.Dereference();
                Expression(out indexType);
                if (!IsArith(indexType))
                {
                    SemError("invalid subscript type");
                }
                CodeGen.Index();
                Expect(rbrack_Sym);
            }
        }
Пример #2
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);
            }
        }