def get_var_type(self, var_name: str, token: CToken) -> str: var_type = "" if var_name in self.variables: var_type = self.variables[var_name].c_type else: log_error(token, "Variable '" + var_name + "' does not exist.") return var_type
def parse(container, tokens: deque, container_name: str) -> str: normal_out = container.output.normal_out token: CToken var_name: str = "" list_name: str = "" list_type: str = "" tokens.popleft() # eat container_name token = tokens[0] if token.string == "_": container.parse_function(tokens) return var_name if token.string != "<": log_error(token, "Expected '<' in " + container_name + " declaration") tokens.popleft() # eat '<' list_type = tokens[0].string list_name = container.generate_definition(list_type) tokens.popleft() token = tokens[0] if token.string != ">": log_error(token, "Expected '>' in " + container_name + " declaration") tokens.popleft() # eat '>' eat_white_space(tokens) preamble = "" pointer = 0 while tokens[0].string == "*": tokens.popleft() preamble += "*" pointer += 1 # get whole var name eat_white_space(tokens) var_name = get_whole_name(tokens) # The variable should be discarded when leaving a function container.variables[var_name] = CVarData(list_type, pointer) while (token.val != Tok.semicolon and token.string != ")" and token.string != "="): token = tokens.popleft() if (var_name == ""): # Assume user just wants replacement to struct name normal_out += list_name + preamble + token.string elif (token.val == Tok.semicolon): tokens.popleft() # container_'type' name; normal_out += list_name + preamble + " " + var_name + ";\n" elif (token.val == Tok.right_paren): normal_out += list_name + preamble + " " + var_name + ")" else: normal_out += list_name + preamble + " " + var_name + " " + token.string container.output.normal_out = normal_out return var_name
def get_func_args(tokens: deque) -> List: eat_white_space(tokens) open_paren = tokens.popleft() if open_paren.val != Tok.left_paren: log_error(open_paren, "Expected an opening parenthesis") token = tokens[0] args = [] while token.string != ")": while token.string == "," or token.string.isspace(): tokens.popleft() token = tokens[0] args.append(get_func_arg(tokens)) token = tokens[0] tokens.popleft() return args
def parse_variable(self, tokens: deque, var_name: str) -> None: if tokens[0].string == "[": tokens.popleft() normal_out = self.output.normal_out normal_out += "*vector_" + self.get_var_type(var_name, tokens[0]) normal_out += "_at" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_copy(reference) normal_out += var_name + ", " token = tokens[0] if token.val == Tok.constant or token.val == Tok.identifier or token.val == Tok.char: normal_out += token.string else: log_error(token, "Expected a number or variable after '['") tokens.popleft() tokens.popleft() normal_out += ")" self.output.normal_out = normal_out else: self.output.normal_out += var_name return
def parse_function(self, tokens: deque) -> None: invalid_num_args = "Invalid number of arguments in call to" normal_out = self.output.normal_out tokens.popleft() # "eat '_' token = tokens[0] var_type = "" if token.string == "pushback": tokens.popleft() # "eat 'pushback' args = parser_utils.get_func_args(tokens) if len(args) != 2: log_error(tokens[0], invalid_num_args + "'vector_pushback'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "vector_" + var_type + "_pushback(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_address(reference) normal_out += var_name + ", " + args[1] + ")" elif token.string == "at": tokens.popleft() # "eat 'at' args = parser_utils.get_func_args(tokens) if len(args) != 2: log_error(tokens[0], invalid_num_args + "vector_at'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "*vector_" + var_type + "_at(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_copy(reference) normal_out += var_name + ", " + args[1] + ")" elif token.string == "front": tokens.popleft() # Eat 'front' args = parser_utils.get_func_args(tokens) if len(args) != 1: log_error(tokens[0], invalid_num_args + "'vector_front'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "*vector_" + var_type + "_front(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_copy(reference) normal_out += var_name + ")" elif token.string == "insert": tokens.popleft() # Eat 'insert' args = parser_utils.get_func_args(tokens) if len(args) != 3: log_error(tokens[0], invalid_num_args + "'vector_insert'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "vector_" + var_type + "_insert(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_address(reference) normal_out += var_name + ", " + args[1] + ", " + args[2] + ")" elif token.string == "free": tokens.popleft() # Eat 'free' args = parser_utils.get_func_args(tokens) if len(args) != 1: log_error(tokens[0], invalid_num_args + "'vector_free'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "vector_" + var_type + "_free(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_address(reference) normal_out += var_name + ")" elif token.string == "init": tokens.popleft() # Eat 'init' args = parser_utils.get_func_args(tokens) if len(args) != 1: log_error(tokens[0], invalid_num_args + "'vector_init'") var_name = args[0] var_type = self.get_var_type(var_name, tokens[0]) normal_out += "vector_" + var_type + "_init(" reference = self.variables[var_name].pointer normal_out += parser_utils.insert_address(reference) normal_out += var_name + ")" else: log_error(tokens[0], "Function is not supported by the vector container") token = tokens[0] while token.string != ";": normal_out += token.string tokens.popleft() token = tokens[0] normal_out += ";" tokens.popleft() self.output.normal_out = normal_out