from thinglang.compiler.buffer import CompilationBuffer
from thinglang.compiler.opcodes import OpcodePopDereferenced, OpcodeDereference
from thinglang.lexer.tokens.access import LexicalAccess
from thinglang.lexer.values.identifier import Identifier
from thinglang.lexer.values.numeric import NumericValue
from thinglang.parser.errors import InvalidIndexedAccess
from thinglang.parser.nodes.base_node import BaseNode
from thinglang.parser.rule import ParserRule
from thinglang.parser.values.named_access import NamedAccess
from thinglang.utils.type_descriptors import ValueType


class IndexedAccess(BaseNode, ValueType):
    """
    Represents an indexed dereference.

    Examples:
        lst[0]
        hobbies[2]
     """

    def __init__(self, target, index):
        super(IndexedAccess, self).__init__([target, index])

        self.target, self.index = target, index

    def __repr__(self):
        return '{}[{}]'.format(self.target, self.index)

    def transpile(self):
        return '{}[{}]'.format(self.target.transpile(), self.index.transpile())

    def compile(self, context: CompilationBuffer, pop_last=False, without_last=False):
        if without_last and not self.extensions:
            return self[0].compile(context)

        ref = context.push_ref(context.resolve(self.root), self.source_ref)

        for ext, last in self.extensions:
            if last and without_last:
                break

            ref = context.symbols.resolve_partial(ref, ext)
            cls = OpcodePopDereferenced if pop_last and last else OpcodeDereference
            context.append(cls(ref.element_index), self.source_ref)

        return ref

    def __eq__(self, other):
        return type(self) == type(other) and self.target == other.target and self.index == other.index

@@ -128,16 +128,65 @@
 eference
+, OpcodePushIndexImmediate, %5C%0A    OpcodePushIndex
 %0Afrom th
@@ -1158,122 +1158,36 @@
 ffer
-, pop_last=False, without_last=False):%0A        if without_last and not self.extensions:%0A            return self%5B0%5D
+):%0A        ctx = self.target
 .com
@@ -1200,17 +1200,16 @@
 ontext)%0A
-%0A
         
@@ -1214,321 +1214,258 @@
   re
-f = context.push_ref(context.resolve(self.root), self.source_ref)%0A%0A        for ext, last in self.extensions:%0A            if last and without_last:%0A                break%0A%0A            ref = context.symbols.resolve_partial(ref, ext)%0A            cls = OpcodePopDereferenced if pop_last and last else OpcodeDereference
+solved_type = context.symbols%5Bctx.type%5D%5BIdentifier('get')%5D%0A%0A        if isinstance(self.index, NumericValue):%0A            context.append(OpcodePushIndexImmediate(self.index.value), self.source_ref)%0A        else:%0A            self.index.compile(context)
 %0A   
@@ -1492,29 +1492,24 @@
 end(
-cls(ref.element_i
+OpcodePushI
 ndex
+(
 ), s
@@ -1542,17 +1542,27 @@
 eturn re
-f
+solved_type
 %0A%0A    de

Add compilation procedure for indexed access (get only, for now)