def func_map_has_key(self, key: int or str) -> bool: try: return key in self.func_map except: eh.print_and_exit("cannot use a list as key ([" + ", ".join( [("'" + str(x) + "'") if type(x) == str else str(x) for x in key]) + "])", self.is_test)
def __eval_at(self, token): try: evald = self.__eval(token[1]) if not type_helper.is_string( token[1]) else token[1][1:-1] return evald[token[2]] except: eh.print_and_exit("invalid index for (at " + str(token[1]) + " " + str(token[2]) + ")")
def __parse_until(self, tokens: list, terminator: str) -> list: try: self.element_count += 1 parsed_tokens = [] while tokens[0] != terminator: parsed_tokens.append(self.parse(tokens)) tokens.pop(0) return parsed_tokens except: eh.print_and_exit("unable to find function terminator: \"" + terminator + "\"")
def __eval_func(self, func_name: str, args: list): func_copy = self.world.get_func_copy(func_name) if len(args) != len(func_copy["args"]): eh.print_and_exit( "func (" + func_name + "): invalid argument count!", self.is_test) return for index, item in enumerate(func_copy["args"]): utility.replace_in_list(func_copy["source"], item, args[index]) return_eval = self.__eval(func_copy["source"]) self.world.remove_vars(self.__get_remove_vars(func_copy["source"])) return return_eval
def __eval_literal(self, token: int or str or float) -> int or str or float: if type_helper.is_keyword(token): return token else: if type(token) == int or type(token) == float: return token elif type_helper.is_string(token): return token[1:-1] else: if self.world.map_has_key(token): return self.world.get_value(token) elif self.world.func_map_has_key(token): return self.__eval_func(token, []) elif token == "putln": print() else: eh.print_and_exit("variable undefined: " + token, self.is_test)
def __eval_math(self, token: list): arg_one = self.__eval(token[1]) arg_two = self.__eval(token[2]) if utility.is_two_different_types(str, arg_one, arg_two): eh.print_and_exit( "invalid math expression: {0} {1} {2} -> " "({3} {4} {5})".format(token[0], type(arg_one).__name__, type(arg_two).__name__, token[0], arg_one, arg_two), self.is_test) return self.world.get_value(token[0])(self.__eval(token[1]), self.__eval(token[2])) if utility.is_two_different_types(int, arg_one, arg_two): arg_one = float(arg_one) arg_two = float(arg_two) return self.world.get_value(token[0])(arg_one, arg_two)
def main(): file_name = __get_file_name(sys.argv) file_ext = __get_file_extension(file_name) if file_ext != ".fyp": eh.print_and_exit("error: invalid file extension: must be .fyp") if not __file_exists(file_name): eh.print_and_exit("error: file does not exist!") _file = open(file_name) _lex = lexer.Lexer(' '.join( [line.rstrip("\n") for line in _file if not __is_comment(line)])) _tokens = _lex.tokenize().tokens is_test = False if len(_tokens) > 1 and _tokens[2] == "test": is_test = True _tokens = _tokens[0:2] + _tokens[3:] _parser = parser_.Parser(_tokens) _eval = evaluator.Evaluator(_parser, is_test) if _eval.tokens[0] != "begin": eh.print_and_exit("error: first function must be 'begin'!") _eval.eval()
def __eval_len(self, token: list or str or int): loop_count = self.__eval(token[1]) if type(loop_count) == int: eh.print_and_exit("invalid len of integer!", self.is_test) else: return len(loop_count.replace("'", ""))
def get_value(self, key) -> int or str: try: return self.__map[key] except: eh.print_and_exit("key (" + str(key) + "): key does not exist!", self.is_test)
def get_func(self, key: str): try: return self.func_map[key] except: eh.print_and_exit("func (" + key + "): func does not exist!", self.is_test)