Пример #1
0
        private bool ParseDeleteStatement(TokenReader reader, out Statement statement)
        {
            statement = null;
            Token start = reader.Peek();
            if (!this.Expect(reader, Keyword.Delete))
            {
                return false;
            }

            Expression operand = null;
            if (!this.ParseExpression(reader, out operand))
            {
                return false;
            }

            statement = new DeleteStatement(start, operand);
            return true;
        }
Пример #2
0
        private bool TryEmitDeleteStatement(DeleteStatement deleteStatement, CompilerContext context, Scope scope, MethodImpl method)
        {
            TypeDefinition valueType = null;
            if (!this.TryEmitExpression(deleteStatement.Value, context, scope, method, out valueType))
            {
                return false;
            }

            if (!valueType.IsPointer && !valueType.IsArray)
            {
                this.log.Write(
                    new Message(
                        deleteStatement.Start.Path,
                        deleteStatement.Start.Line,
                        deleteStatement.Start.Column,
                        Severity.Error,
                        Properties.Resources.CodeGenerator_DeleteOperandMustBePointerOrArray));
                return false;
            }

            if (valueType.IsPointer)
            {
                this.PushResult(method, valueType);
                TypeDefinition innerType = valueType.InnerType;
                if (innerType != null)
                {
                    MethodInfo destructor = innerType.GetDestructor();
                    if (destructor != null)
                    {
                        this.PushResult(method, valueType);
                        method.Module.AddProto(destructor);
                        if (destructor.IsVirtual)
                        {
                            FieldInfo vtblPointer = innerType.GetVTablePointer();
                            if (vtblPointer.Offset > 0)
                            {
                                method.Statements.Add(new AsmStatement { Instruction = string.Format("add eax,{0}", vtblPointer.Offset) });
                            }

                            method.Statements.Add(new AsmStatement { Instruction = "mov ecx,[eax]" });
                            if (destructor.VTableIndex > 0)
                            {
                                method.Statements.Add(new AsmStatement { Instruction = string.Format("add ecx,{0}", destructor.VTableIndex * 4) });
                            }

                            method.Statements.Add(new AsmStatement { Instruction = "call dword ptr [ecx]" });
                        }
                        else
                        {
                            method.Statements.Add(new AsmStatement { Instruction = string.Format("call {0}", destructor.MangledName) });
                        }

                        method.Statements.Add(new AsmStatement { Instruction = string.Format("add esp,{0}", valueType.Size) });
                    }
                }

                if (!this.TryEmitFreeCall(deleteStatement.Start, context, scope, method))
                {
                    return false;
                }

                method.Statements.Add(new AsmStatement { Instruction = string.Format("add esp,{0}", valueType.Size) });
                return true;
            }

            log.Write(new Message(
                deleteStatement.Start.Path,
                deleteStatement.Start.Line,
                deleteStatement.Start.Column,
                Severity.Error,
                Properties.Resources.CodeGenerator_DeleteOperandArrayNotSupported));
            return false;
        }