<commit_before>import logging
from abc import abstractmethod as abstract, ABC

from ..errors import *

# Python predefines
Type = None
Scope = None
Module = None
Function = None
FunctionType = None

#
# Infrastructure
#

def verify(module:Module, builtins:Module, logger:logging.Logger = None):
    if logger is None: logger = logging.getLogger()

    module.verify(State(builtins, logger))

class State:
    def __init__(self, builtins:Module, logger:logging.Logger):
        self.builtins = builtins
        self.logger = logger

#
# Abstract Base Structures
#

class Object(ABC):
    @abstract
    def verify(self, scope:Scope, state:State):
        pass

    @abstract
    def resolveType(self) -> Type:
        """ Returns the type of this object.
        Must return an instance of Type or None.
        If the type is None, this object is considered void (side-effects only)
        Otherwise the object can be used as a value.
        """

    def resolveCall(self, signature:FunctionType) -> Function:
        """ Returns a function that matches a call signature for this object.
        Must return either a Function instance or raise a TypeError
        """
        raise TypeError("{} object is not callable".format(self))

    def __repr__(self):
        return "{}:{}".format(self.__class__.__name__, self.resolveType())

class ScopeObject(Object):
    name = None
    parent = None

    def __init__(self, name):
        self.name = name

    @abstract
    def verify(self, state:State):
        pass

    def __repr__(self):
        return "{}({}):{}".format(self.__class__.__name__, self.name, self.resolveType())

class Scope(ScopeObject):
    verified = False # cache for circular program flows

    parent = None
    children = None

    def __init__(self, name, children:{str: ScopeObject} = None):
        if children is None: children = {}
        super().__init__(name)

        # set children
        self.children = children
        for child in children.values():
            child.parent = self

    def addChild(self, child:ScopeObject):
        child.parent = self
        self.children[child.name] = child

    def verify(self, state:State) -> None:
        if self.verified: return
        self.verified = True

        for child in self.children.values():
            child.verify(state)

    def resolveReferenceDown(self, reference:str, state:State) -> Object:
        objects = self.collectReferencesDown(reference, state)
        if len(objects) < 1:
            raise MissingReferenceError("Missing reference to {}".format(reference))
        elif len(objects) > 1:
            raise AmbiguetyError("Ambiguous reference to {}".format(reference))
        return objects[0]

    def resolveReferenceUp(self, reference:str, state:State) -> Object: #TODO: Make this work
        return self._resolveReference(reference)

    def collectReferencesDown(self, reference:str, state:State) -> Object:
        out = []
        # check local
        obj = self.children.get(reference, None)
        if obj is not None:
            out.append(obj)
        # check parent
        more = self.parent.collectReferencesDown(reference, state) if self.parent else state.builtins.collectReferencesDown(reference, state)
        if more is not None:
            out += more
        return out

    def __repr__(self):
        return "{}({}):{}<{}>".format(self.__class__.__name__, self.name, self.resolveType(),
            ", ".join(repr(child) for child in self.children.values()))

class Type(Scope):
    @abstract
    def checkCompatibility(self, other:Type) -> bool:
        pass

    def resolveCompatibility(self, other:Type):
        if not self.checkCompatibility(other):
            raise TypeError("{} is not compatible with {}".format(self, other))

    def __repr__(self):
        return "{}".format(self.__class__.__name__)

#
# Jam Structures
#

class Comment(Object):
    contents = None

    def __init__(self, contents):
        self.contents = contents

    def verify(self, scope:Scope, state:State):
        state.logger.debug(self)

    def resolveType(self):
        return None

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.contents)

class Assignment(Object):
    reference = None
    variable = None # resolved through reference
<commit_msg>Changed implementation to follow the reference README<commit_after>import logging
from abc import abstractmethod as abstract, ABC

from ..errors import *

# Python predefines
Object = None
Scope = None
Type = None
Module = None
Function = None
FunctionType = None

#
# Infrastructure
#

def verify(module:Module, builtins:Module, logger:logging.Logger = None):
    if logger is None: logger = logging.getLogger()

    module.verify(State(builtins, logger))

class State:
    def __init__(self, builtins:Module, logger:logging.Logger):
        self.builtins = builtins
        self.logger = logger

def resolveReference(scope:Object, state:State, object:Object, reference:str):
    attrs = object.collectAttributes(scope, state, reference)

    # If the object is a scope, resolve up the tree
    if isinstance(object, Scope):
        while object.parent is not None:
            object = object.parent
            attrs += object.collectAttributes(scope, state, reference)

    if len(attrs) < 1:
        raise MissingReferenceError("No reference to {}".format(reference))
    elif len(attrs) > 1:
        raise AmbiguetyError("Ambiguous reference to {}".format(reference))

    return attrs[0]

#
# Abstract Base Structures
#

class Object(ABC):
    @abstract
    def verify(self, scope:Scope, state:State):
        pass

    @abstract
    def resolveType(self, scope:Scope, state:State):
        pass

    def collectAttributes(scope:Scope, state:State, reference:str) -> [Object]:
        return self.resolveType(scope, state).collectAttributes(state, reference)

    def __repr__(self):
        return "{}:{}".format(self.__class__.__name__, self.resolveType())

class Scope(Object):
    name = None
    parent = None

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "{}({}):{}".format(self.__class__.__name__, self.name, self.resolveType())

class Type(Scope):
    @abstract
    def collectAttributes(self, state:State, reference:str) -> [Object]:
        pass

    @abstract
    def checkCompatibility(self, other:Type) -> bool:
        pass

    def __repr__(self):
        return "{}".format(self.__class__.__name__)

#
# Jam Structures
#

class Comment(Object):
    contents = None

    def __init__(self, contents):
        self.contents = contents

    def verify(self, scope:Scope, state:State):
        state.logger.debug(self)

    def resolveType(self):
        return None

    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.contents)

class Assignment(Object):
    reference = None
    variable = None # resolved through reference

{'fraction_non_alphanumeric': 0.1092896174863388, 'fraction_numerical': 0.0008628127696289905, 'mean_word_length': 2.9697488584474887, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6579990', 'n_tokens_mistral': 1949, 'n_tokens_neox': 1898, 'n_words': 564}