from thinglang.compiler.buffer import CompilationBuffer
from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal
from thinglang.lexer.blocks.exceptions import LexicalHandle
from thinglang.lexer.values.identifier import Identifier
from thinglang.parser.nodes import BaseNode
from thinglang.parser.rule import ParserRule


class HandleBlock(BaseNode):
    """
    An exception handling block
    """

    def __init__(self, exception_type: Identifier, exception_name: Identifier=None):
        super(HandleBlock, self).__init__([exception_type, exception_name])
        self.exception_type, self.exception_name = exception_type, exception_name

    def compile(self, context: CompilationBuffer):
        assert self.parent is None, 'Handle blocks may not be part of the AST after finalization'

        buffer = context.optional()

        if self.exception_name is not None:
            buffer.append(OpcodePopLocal.from_reference(context.resolve(self.exception_name)), self.source_ref)

        super(HandleBlock, self).compile(buffer)
        buffer.append(OpcodeJump(context.next_index, absolute=True), self.source_ref)
        return context.epilogue(buffer)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block_with_value(_: LexicalHandle, exception_type: Identifier, exception_name: Identifier):
        return HandleBlock(exception_type, exception_name)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block(_: LexicalHandle, exception_type: Identifier):
        return HandleBlock(exception_type)

from thinglang.compiler.buffer import CompilationBuffer
from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal, OpcodePop
from thinglang.lexer.blocks.exceptions import LexicalHandle
from thinglang.lexer.values.identifier import Identifier
from thinglang.parser.nodes import BaseNode
from thinglang.parser.rule import ParserRule


class HandleBlock(BaseNode):
    """
    An exception handling block
    """

    def __init__(self, exception_type: Identifier, exception_name: Identifier=None):
        super(HandleBlock, self).__init__([exception_type, exception_name])
        self.exception_type, self.exception_name = exception_type, exception_name

    def compile(self, context: CompilationBuffer):
        assert self.parent is None, 'Handle blocks may not be part of the AST after finalization'

        buffer = context.optional()

        if self.exception_name is not None:
            buffer.append(OpcodePopLocal.from_reference(context.resolve(self.exception_name)), self.source_ref)
        else:
            buffer.append(OpcodePop(), self.source_ref)

        super(HandleBlock, self).compile(buffer)
        buffer.append(OpcodeJump(context.next_index, absolute=True), self.source_ref)
        return context.epilogue(buffer)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block_with_value(_: LexicalHandle, exception_type: Identifier, exception_name: Identifier):
        return HandleBlock(exception_type, exception_name)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block(_: LexicalHandle, exception_type: Identifier):
        return HandleBlock(exception_type)

Add missing void pop in uncaptured exception blocks
Add missing void pop in uncaptured exception blocks

  from thinglang.compiler.buffer import CompilationBuffer
- from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal
+ from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal, OpcodePop
  from thinglang.lexer.blocks.exceptions import LexicalHandle
  from thinglang.lexer.values.identifier import Identifier
  from thinglang.parser.nodes import BaseNode
  from thinglang.parser.rule import ParserRule
  
  
  class HandleBlock(BaseNode):
      """
      An exception handling block
      """
  
      def __init__(self, exception_type: Identifier, exception_name: Identifier=None):
          super(HandleBlock, self).__init__([exception_type, exception_name])
          self.exception_type, self.exception_name = exception_type, exception_name
  
      def compile(self, context: CompilationBuffer):
          assert self.parent is None, 'Handle blocks may not be part of the AST after finalization'
  
          buffer = context.optional()
  
          if self.exception_name is not None:
              buffer.append(OpcodePopLocal.from_reference(context.resolve(self.exception_name)), self.source_ref)
+         else:
+             buffer.append(OpcodePop(), self.source_ref)
  
          super(HandleBlock, self).compile(buffer)
          buffer.append(OpcodeJump(context.next_index, absolute=True), self.source_ref)
          return context.epilogue(buffer)
  
      @staticmethod
      @ParserRule.mark
      def parse_handle_block_with_value(_: LexicalHandle, exception_type: Identifier, exception_name: Identifier):
          return HandleBlock(exception_type, exception_name)
  
      @staticmethod
      @ParserRule.mark
      def parse_handle_block(_: LexicalHandle, exception_type: Identifier):
          return HandleBlock(exception_type)
  
Add missing void pop in uncaptured exception blocks
## Code Before:
from thinglang.compiler.buffer import CompilationBuffer
from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal
from thinglang.lexer.blocks.exceptions import LexicalHandle
from thinglang.lexer.values.identifier import Identifier
from thinglang.parser.nodes import BaseNode
from thinglang.parser.rule import ParserRule


class HandleBlock(BaseNode):
    """
    An exception handling block
    """

    def __init__(self, exception_type: Identifier, exception_name: Identifier=None):
        super(HandleBlock, self).__init__([exception_type, exception_name])
        self.exception_type, self.exception_name = exception_type, exception_name

    def compile(self, context: CompilationBuffer):
        assert self.parent is None, 'Handle blocks may not be part of the AST after finalization'

        buffer = context.optional()

        if self.exception_name is not None:
            buffer.append(OpcodePopLocal.from_reference(context.resolve(self.exception_name)), self.source_ref)

        super(HandleBlock, self).compile(buffer)
        buffer.append(OpcodeJump(context.next_index, absolute=True), self.source_ref)
        return context.epilogue(buffer)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block_with_value(_: LexicalHandle, exception_type: Identifier, exception_name: Identifier):
        return HandleBlock(exception_type, exception_name)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block(_: LexicalHandle, exception_type: Identifier):
        return HandleBlock(exception_type)

## Instruction:
Add missing void pop in uncaptured exception blocks
## Code After:
from thinglang.compiler.buffer import CompilationBuffer
from thinglang.compiler.opcodes import OpcodeJump, OpcodePopLocal, OpcodePop
from thinglang.lexer.blocks.exceptions import LexicalHandle
from thinglang.lexer.values.identifier import Identifier
from thinglang.parser.nodes import BaseNode
from thinglang.parser.rule import ParserRule


class HandleBlock(BaseNode):
    """
    An exception handling block
    """

    def __init__(self, exception_type: Identifier, exception_name: Identifier=None):
        super(HandleBlock, self).__init__([exception_type, exception_name])
        self.exception_type, self.exception_name = exception_type, exception_name

    def compile(self, context: CompilationBuffer):
        assert self.parent is None, 'Handle blocks may not be part of the AST after finalization'

        buffer = context.optional()

        if self.exception_name is not None:
            buffer.append(OpcodePopLocal.from_reference(context.resolve(self.exception_name)), self.source_ref)
        else:
            buffer.append(OpcodePop(), self.source_ref)

        super(HandleBlock, self).compile(buffer)
        buffer.append(OpcodeJump(context.next_index, absolute=True), self.source_ref)
        return context.epilogue(buffer)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block_with_value(_: LexicalHandle, exception_type: Identifier, exception_name: Identifier):
        return HandleBlock(exception_type, exception_name)

    @staticmethod
    @ParserRule.mark
    def parse_handle_block(_: LexicalHandle, exception_type: Identifier):
        return HandleBlock(exception_type)
