Untitled

 avatar
user_0606344
python
23 days ago
3.8 kB
4
Indexable
Never
from collections import defaultdict
from typing import List, Set


class Function:
    def __init__(self, name, argument_types, is_variadic):
        self.name = name
        self.argument_types = argument_types
        self.is_variadic = is_variadic
    
    def __repr__(self):
        return self.name

class FunctionLibrary:
    def __init__(self):
        self.functions = defaultdict(list)
        self.variadic_functions = defaultdict(list)
        
    def register(self, functions : Set[Function]) -> None:
        # list in unhashable in python 
        # convert list into set as key in hashtable
        
        for function in functions:
            print(function, tuple(function.argument_types))
            if function.is_variadic:
                self.variadic_functions[tuple(function.argument_types)].append(function)
                
            else:
                self.functions[tuple(function.argument_types)].append(function)
                
    def find_matches(self, argument_types: List[str]) -> List[Function]:
        # non variadic 的直接匹配 
        print("we are matching:", argument_types)
        non_variadic = self.functions.get(tuple(argument_types), [])
        variadic = self._get_variadic_matches(argument_types)
        
        return non_variadic + variadic
    
    def _get_variadic_matches(self, argument_types): #["String", "Integer", "Integer", "Integer"]
                                                     #  0          1         len-2         len -1
        matches = []
        # variadic 一模一样的直接配对成功
        matches.extend(self.variadic_functions[tuple(argument_types)])
        print(matches)
        i = 0
        for i in range(len(argument_types)-2, -1, -1): # i = len -2 = 4 -2  = 2  也就是last 前一个index 开始的prevs: ["String", "Integer", "Integer" 
            # 每次都要确保当前的屁股 和之前的是一致的 e.g.  。。。。 xxxxx
            if argument_types[i] != argument_types[i+1]: # i = len -2 -1 = 4 - 2 -1  = 1  砍掉一个 继续尝试前面的 prevs: ["String", "Integer", 
                                                                                        # 因为可能有无限个last重复,  ["String", "Integer",      ...,             "Integer"]
                                                                                        #                                      last0   last1...lastn-1      lastn
                break
            print("此时是i", i , "在尝试匹配", argument_types[:i+1], "matches before extend", matches)
            matches.extend(self.variadic_functions[tuple(argument_types[:i+1])])
            print("此时是i", i , "在尝试匹配", argument_types[:i+1], "matches after extend", matches)

        return matches

func_library = FunctionLibrary()
func_a = Function("func_a", ["String", "Integer", "Integer"], False)
func_b = Function("func_b", ["String", "Integer"], True)
func_c = Function("func_c", ["Integer"], True)
func_d = Function("func_d", ["Integer", "Integer"], True)
func_e = Function("func_e", ["Integer", "Integer", "Integer"], False)
func_f = Function("func_f", ["String"], False)
func_g = Function("func_g", ["Integer"], False)


func_library.register([func_a, func_b, func_c, func_d, func_e, func_f, func_g])
print(func_library.find_matches(["String"]))
print(func_library.find_matches(["Integer"]))
print(func_library.find_matches(["Integer", "Integer", "Integer", "Integer"]))
print(func_library.find_matches(["Integer", "Integer", "Integer"]))
print("test-------------------------------test")

print(func_library.find_matches(["String", "Integer", "Integer", "String"]))
print(func_library.find_matches(["String", "Integer", "Integer", "Integer"]))
print(func_library.find_matches(["String", "Integer", "Integer"]))
Leave a Comment