def __init__(self, name, vartype, value, vector_size=None): self.name = name # Variable offset in memory, set by the compiler state self.offset = None self.length = 1 # 'vector_size' should be None for non-vector types self.is_vector = vector_size is not None if self.is_vector: if vector_size < 1: raise ValueError('Vector size must be ≥ 1') self.value = Operand.get_csv(value) self.length = vector_size # One value is OK with any vector size, 'dup()' is assumed if len(self.value) != 1 and self.length != len(self.value): raise ValueError( f'Specified vector length ({self.length}) and supplied ' f'values count ({len(self.value)}) do not match') else: # Not a vector, so save its single value self.value = value.strip() # Name and vector handled, now define the type self.type = vartype # Type defined, now determine its code self.is_constant = vartype == 'const' if self.is_constant: if self.is_vector: raise ValueError('Cannot define a constant vector') self.typecode = None else: if vartype == 'byte': self.typecode = 'DB' self.size = 8 elif vartype == 'short': self.typecode = 'DW' self.size = 16 elif vartype == 'string': if self.is_vector: raise ValueError('Cannot define a vector of strings') self.typecode = 'DB' self.size = 8 self.value, self.length = self.escape_string(value) else: raise ValueError(f'Unknown variable type "{vartype}"')
def get_operands(self, csv): """Converts the possibly comma separated values to a list of operands (inmediate, registers and variables """ if isinstance(csv, list): return [ v if isinstance(v, Operand) else Operand(self, v) for v in csv ] if isinstance(csv, Operand): return [csv] return [Operand(self, v) for v in Operand.get_csv(csv)]
def __init__(self, name, params, returns=None, mangle=True): # Convert a comma separated list to normal parameters if required self.params = Operand.get_csv(params) # Name mangling, add as many underscores as parameter count if mangle: self.name = self.mangle(name, len(self.params)) else: self.name = name # Where the value is returned self.returns = returns # Used to store the code of the function self.code = []
def variable(c, m): """Variable or constant definition. For instance: byte little = 42 short big = 1234 byte[5] vector1 byte[] vector2 = 1, 2, 3, 4, 5 const VALUE = 7 """ # TODO Perform more checks to ensure the value is correct vartype = m.group(1) vector_size = m.group(2) name = m.group(3) value = m.group(4) if not value: value = '?' if vector_size is None: # Single item variable c.add_variable(Variable(name=name, vartype=vartype, value=value)) else: # We have a vector, get the comma-separated values values = Operand.get_csv(value) # Determine its size (remove '[]' by slicing) if given vector_size = vector_size[1:-1].strip() if vector_size: vector_size = int(vector_size) else: if value == '?': raise ValueError('A list of values must be supplied when ' 'no vector size is specified') vector_size = len(values) c.add_variable( Variable(name=name, vartype=vartype, value=values, vector_size=vector_size))