def print_lines(self, var: Variable, size: str, indent_lvl: int) -> None: """Print the content of a var that holds in one or more lines""" if var.fits_in_one_line(self.input.structs): self.print_line(var, size, indent_lvl) else: if var.type.main == TypeEnum.STRUCT: struct = self.input.get_struct(var.type.struct_name) struct = self.input.get_struct(var.type.struct_name) for f_name, f_type, f_size in struct.fields_name_type_size( f"{var.name}.{{}}", var_name): self.print_lines(Variable(f_name, "", f_type), f_size, indent_lvl) else: assert var.type.main == TypeEnum.LIST assert var.type.encapsulated is not None index = self.iterator.new_it() self.method.append( "{0}for (int {1} = 0; {1} < {2}; ++{1}) {{".format( " " * self.indentation * indent_lvl, index, size)) self.print_lines( Variable(f"{var.name}[{index}]", "", var.type.encapsulated), var_name(var.type.encapsulated.size), indent_lvl + 1, ) self.method.append(" " * self.indentation * indent_lvl + "}") self.iterator.pop_it()
def read_lines( self, var: Variable, size: str, already_allocated: bool = False, ) -> List[str]: """Read one or several lines and store them into the right place(s)""" lines = [] if var.type.main == TypeEnum.LIST and not already_allocated: lines.append(f"{var.name} = make({type_str(var.type)}, {size})") if var.fits_in_one_line(self.input.structs): return lines + self.read_line(var.name, size, var.type) if var.type.main == TypeEnum.STRUCT: struct = self.input.get_struct(var.type.struct_name) for f_name, f_type, f_size in struct.fields_name_type_size( var.name + ".{}", var_name ): lines.extend(self.read_lines(Variable(f_name, "", f_type), f_size)) return lines assert var.type.main == TypeEnum.LIST assert var.type.encapsulated is not None inner_name = self.iterator.new_it() lines.append(f"for {inner_name} := range {var.name} {{") lines.extend( INDENTATION + i for i in self.read_lines( Variable(f"{var.name}[{inner_name}]", "", var.type.encapsulated), var_name(var.type.encapsulated.size), ) ) lines.append("}") self.iterator.pop_it() return lines
def read_lines(self, decl: bool, var: Variable, size: str, indent_lvl: int) -> List[str]: # pylint: disable=too-many-arguments # pylint: disable=too-many-locals """Read one or several lines and store them into the right place(s)""" if var.fits_in_one_line(self.input.structs): return self.read_line(decl, var.name, var.type, indent_lvl) indent = INDENTATION * indent_lvl if var.type.main == TypeEnum.STRUCT: lines = [ indent + "{}{} = new {}();".format( class_name(var.type.struct_name) + " " if decl else "", var.name, class_name(var.type.struct_name), ) ] struct = self.input.get_struct(var.type.struct_name) for f_name, f_type, f_size in struct.fields_name_type_size( f"{var.name}.{{}}", var_name): lines.extend( self.read_lines(False, Variable(f_name, "", f_type), f_size, indent_lvl)) return lines assert var.type.main == TypeEnum.LIST assert var.type.encapsulated is not None far_inner_type = var.type.encapsulated list_suffix = "" while far_inner_type.main == TypeEnum.LIST: assert far_inner_type.encapsulated is not None far_inner_type = far_inner_type.encapsulated list_suffix += "[]" lines = [ "{}{}{} = new {}[{}]{};".format( indent, (type_str(var.type) + " ") if decl else "", var.name, type_str(far_inner_type), size, list_suffix, ) ] index = self.iterator.new_it() self.words.push_scope() lines.append("{0}for (int {1} = 0; {1} < {2}; ++{1}) {{".format( indent, index, size)) lines.extend( self.read_lines( False, Variable(f"{var.name}[{index}]", "", var.type.encapsulated), var_name(var.type.encapsulated.size), indent_lvl + 1, )) self.words.pop_scope() self.iterator.pop_it() return lines + [indent + "}"]
def read_var(self, var: Variable, in_error_context: bool = False) -> str: """Return a Rust command for parsing a variable""" name = var_name(var.name) unwrap_method = "?" if in_error_context else None if var.fits_in_one_line(self.input.structs): read_method = self.read_line(var.type, 1, var.name, unwrap_method) else: read_method = "\n".join(self.read_lines(name, var.type, 1, unwrap_method)) return f" let {name} = {read_method};"
def read_lines(var: Variable, decl: str, size: str, input_data: Input, words: WordsName) -> List[str]: """Generate the Ruby code to read the lines for a given type""" if var.fits_in_one_line(input_data.structs): return read_line(var.name, decl, var.type, input_data, words) if var.type.main == TypeEnum.LIST: assert var.type.encapsulated is not None lines = [ decl.format("()" if var.name[0] == "@" else "[]"), "for (1..{}) {{".format(size), ] words.push_scope() array_name = var.name.replace("{", "{{").replace("}", "}}") if array_name[0] != "@": array_name = "@{{" + array_name + "}}" lines.extend([ INDENTATION + i for i in read_lines( Variable("$" + var.name[1:] + "[-1]", "", var.type.encapsulated), "push({}, {{}});".format(array_name), size_name(var.type.encapsulated.size), input_data, words, ) ]) words.pop_scope() return lines + ["}"] assert var.type.main == TypeEnum.STRUCT struct = input_data.get_struct(var.type.struct_name) sizes = [size_name(field.type.size) for field in struct.fields] if struct.is_sized_struct(): sizes = ["", f"{var.name}{{'{struct.fields[0].name}'}}"] lines = [decl.format("()" if var.name[0] == "%" else "{}")] for (field, f_size) in zip(struct.fields, sizes): f_name = f"${var.name[1:]}{{'{field.name}'}}" lines.extend( read_lines( Variable(f_name, "", field.type), f_name.replace("{", "{{").replace("}", "}}") + " = {};", f_size, input_data, words, )) return lines
def generate_lines(self, var: Variable) -> List[str]: """Generate the raw input for a type""" if var.fits_in_one_line(self.input.structs): return [self.generate_line(var.name, var.type, var.constraints)] if var.type.main == TypeEnum.LIST: assert var.type.encapsulated inner = Variable("", "", var.type.encapsulated) inner.constraints = var.constraints lines = [] for _ in range(self.eval_var(var.type.size)): lines.extend(self.generate_lines(inner)) return lines if var.type.main == TypeEnum.STRUCT: struct = self.input.get_struct(var.type.struct_name) lines = [] for field in struct.fields: lines.extend(self.generate_lines(field)) return lines assert False return []
def print_lines( self, var: Variable, size: str, indent_lvl: int, ) -> List[str]: """Print the content of a var that holds in one or more lines""" if var.fits_in_one_line(self.input.structs): return [ INDENTATION * indent_lvl + self.print_line(var.name, var.type) ] if var.type.main == TypeEnum.STRUCT: struct = self.input.get_struct(var.type.struct_name) lines = [] for f_name, f_type, f_size in struct.fields_name_type_size( f"{var.name}.{{}}", var_name): lines.extend( self.print_lines(Variable(f_name, "", f_type), f_size, indent_lvl)) return lines assert var.type.main == TypeEnum.LIST assert var.type.encapsulated is not None index = self.iterator.new_it() self.words.push_scope() lines = [ "{0}for (int {1} = 0; {1} < {2}; ++{1}) {{".format( INDENTATION * indent_lvl, index, size) ] lines.extend( self.print_lines( Variable(f"{var.name}[{index}]", "", var.type.encapsulated), var_name(var.type.encapsulated.size), indent_lvl + 1, )) lines.append(INDENTATION * indent_lvl + "}") self.words.pop_scope() self.iterator.pop_it() return lines
def read_lines(self, decl: bool, var: Variable, size: str, indent_lvl: int) -> List[str]: # pylint: disable=too-many-arguments """Generate the Javascript code to read the lines for a given type""" if var.fits_in_one_line(self.input.structs): return self.read_line(decl, var.name, var.type, size, indent_lvl) indent = INDENTATION * indent_lvl if var.type.main == TypeEnum.LIST: assert var.type.encapsulated is not None lines = [indent + f"{'const ' if decl else ''}{var.name} = [];"] iterator = self.iterator.new_it() inner_name = self.iterator.new_it() lines.append(indent + "for (let {0} = 0; {0} < {1}; {0}++) {{".format( iterator, size)) self.words.push_scope() lines.extend( self.read_lines( True, Variable(inner_name, "", var.type.encapsulated), var_name(var.type.encapsulated.size), indent_lvl + 1, )) lines.append(indent + INDENTATION + f"{var.name}.push({inner_name});") self.words.pop_scope() self.iterator.pop_it() self.iterator.pop_it() return lines + [indent + "}"] assert var.type.main == TypeEnum.STRUCT struct = self.input.get_struct(var.type.struct_name) lines = [indent + f"{'const ' if decl else ''}{var.name} = {{}};"] for f_name, f_type, f_size in struct.fields_name_type_size( f"{var.name}.{{}}", var_name): lines.extend( self.read_lines(False, Variable(f_name, "", f_type), f_size, indent_lvl)) return lines
def read_lines( var: Variable, size: str, input_data: Input, iterator: IteratorName ) -> List[str]: """Generate the Lua code to read the lines for a given type""" if var.fits_in_one_line(input_data.structs): return read_line(var.name, var.type, input_data, iterator) if var.type.main == TypeEnum.LIST: assert var.type.encapsulated is not None inner = iterator.new_it() lines = read_lines( Variable(f"{var.name}[{inner}]", "", var.type.encapsulated), var_name(var.type.encapsulated.size), input_data, iterator, ) iterator.pop_it() return ( [f"{var.name} = {{}}", f"for {inner} = 1, {size} do"] + [INDENTATION + i for i in lines] + ["end"] ) assert var.type.main == TypeEnum.STRUCT struct = input_data.get_struct(var.type.struct_name) lines = [var.name + " = {}"] for i, field in enumerate(struct.fields): f_size = var_name(field.type.size) if i == 1 and struct.is_sized_struct(): f_size = f'{var.name}["{struct.fields[0].name}"]' lines.extend( read_lines( Variable(f'{var.name}["{field.name}"]', "", field.type), f_size, input_data, iterator, ) ) return lines