import re


class Statement:
    def __init__(self, readable_regex, state_updater):
        """Initializes a statement to match lines with
            the provided 'readable_regex'. If a match
            is found, 'state_updater' is invoked with
            the Compiler state and Match parameters
        """
        self.regex = self.recompile(readable_regex)
        self.state_updater = state_updater

    def update_if_match(self, line, compiler_state):
        """If 'line' matches this statement's regex,
            the 'compiler_state' will be updated with the
            code generated by this statement.

            Returns True if the 'compiler_state' was updated.
        """
        m = self.regex.match(line)
        if m:
            self.state_updater(compiler_state, m)
            return True
        else:
            return False

    @staticmethod
    def recompile(s):
        """Used to compile "readable" regexes, with the following changes:
            '^' and '$' will be prepended and appended, respectively

            'CSINM' -> 'INM(?: , INM)*'
            'CSVAR' -> 'VAR(?: , VAR)*'

            'INM' -> r"(?:VAR|(?:0[xbXB])?\d+[hbHB]?|'\\?.')"
            'VAR' -> '[^_\W\d](?:\w)*(?:\[\d+\])?' (for variable/register)

            '  ' (two spaces) -> r'\s+'
            ' ' (one space) -> r'\s*'

            '(?:\s*@(\w+))?' will be added to the end to allow @labelname
        """
        if 'IMN' in s:
            raise ValueError('Typo "IMN" (probably meant "INM")')

        s = s.replace('CSINM', r'(?:INM)(?: , (?:INM))*')
        s = s.replace('CSVAR', r'(?:VAR)(?: , (?:VAR))*')
        s = s.replace('INM', r"(?:&?VAR(?: \. length)?|-?(?:0[xbXB])?[\da-f]+[hbHB]?|'\\?.')")
        s = s.replace('VAR', r'[^_\W\d](?:\w)*(?: \[ [\dsdibx+\-\s]+ \])?')
        s = s.replace('  ', r'\s+')
        s = s.replace(' ', r'\s*')

        return re.compile('^' + s + '(?:\s*@(\w+))?$')
