def t_cons(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type new = node["elements"]["e1"] list = node["elements"]["e2"] list_type = infer_type(environment, list) if isList(list_type): new_type = infer_type(environment, new) empty = TYPE.LIST(TYPE.EMPTY) list_of = innerType(list_type) if new_type == empty and list_type == empty: return empty if new_type != empty and TYPE.EMPTY in list_type: return TYPE.LIST(new_type) elif (new_type == list_of) or (new_type == TYPE.UNDEFINED): return list_type elif new_type != empty and TYPE.UNDEFINED in list_type: return TYPE.LIST(new_type) else: return TYPE.ERROR else: return TYPE.ERROR
def t_if(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type elem1 = node["elements"]["e1"] elem2 = node["elements"]["e2"] elem3 = node["elements"]["e3"] tipo1 = infer_type(environment, elem1) tipo2 = infer_type(environment, elem2) tipo3 = infer_type(environment, elem3) if (tipo1 == TYPE.BOOL) or (tipo1 == TYPE.UNDEFINED): if (tipo2 == tipo3): return tipo2 elif (tipo2 == TYPE.UNDEFINED): return tipo3 elif (tipo3 == TYPE.UNDEFINED): return tipo2 else: return TYPE.ERROR else: return TYPE.ERROR
def t_letrec(environment, term): from main import infer_type if not parameters_are_valid(environment, term): return TYPE.ERROR if not environment: environment = {} function_name = term['elements']['function_name'] input_type = term['elements']['type1'] output_type = term['elements']['type2'] param_name = term['elements']['param']['elements']['e1'] e1 = term['elements']['e1'] e2 = term['elements']['e2'] environment[function_name] = TYPE.FUNC(input_type, output_type) type_e2 = infer_type(environment, e2) environment[param_name] = input_type type_e1 = infer_type(environment, e1) if type_e2 == TYPE.ERROR or type_e1 == TYPE.ERROR: return TYPE.ERROR if type_e1 == output_type or type_e1 == TYPE.UNDEFINED: return type_e2 return TYPE.ERROR
def t_logic(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type elem1 = node["elements"]["e1"] elem2 = node["elements"]["e2"] tipo1 = infer_type(environment, elem1) tipo2 = infer_type(environment, elem2) if (((tipo1 == TYPE.INT) and (tipo2 == TYPE.INT)) or ((tipo1 == TYPE.UNDEFINED) and (tipo2 == TYPE.INT)) or ((tipo1 == TYPE.INT) and (tipo2 == TYPE.UNDEFINED)) or ((tipo1 == TYPE.UNDEFINED) and (tipo2 == TYPE.UNDEFINED))): if ((node["elements"]["e3"] == ">") or (node["elements"]["e3"] == "<") or (node["elements"]["e3"] == "==") or (node["elements"]["e3"] == "!=") or (node["elements"]["e3"] == "=<") or (node["elements"]["e3"] == ">=")): return TYPE.BOOL else: return TYPE.ERROR else: return TYPE.ERROR
def t_app(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type term = infer_type(environment, node["elements"]["e1"]) if term == TYPE.UNDEFINED: return TYPE.ERROR expected_parameter, ending_index = get_expected_parameter(term) received_parameter = infer_type(environment, node["elements"]["e2"]) if expected_parameter == received_parameter or received_parameter == TYPE.UNDEFINED: result = apply_parameter(term, ending_index) return result else: return TYPE.ERROR
def t_tl(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type list = node["elements"]["e1"] list_type = infer_type(environment, list) if isList(list_type): return list_type else: return TYPE.ERROR
def t_let(environment, node): from main import infer_type if node and "elements" in node: elements = node["elements"] else: return TYPE.ERROR if "e1" in elements and "e2" in elements and "e3" in elements and "e4" in elements: param = elements["e3"] param_type = elements["e4"] e1 = elements["e1"] e2 = elements["e2"] else: return TYPE.ERROR if infer_type(environment, e1) == param_type: if not environment: environment = {} environment[param] = param_type return infer_type(environment, e2) return TYPE.ERROR
def t_arithm(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type elem1 = node["elements"]["e1"] elem2 = node["elements"]["e2"] tipo1 = infer_type(environment, elem1) tipo2 = infer_type(environment, elem2) if (((tipo1 == TYPE.INT) and (tipo2 == TYPE.INT)) or ((tipo1 == TYPE.UNDEFINED) and (tipo2 == TYPE.INT)) or ((tipo1 == TYPE.INT) and (tipo2 == TYPE.UNDEFINED)) or ((tipo1 == TYPE.UNDEFINED) and (tipo2 == TYPE.UNDEFINED))): if (node["elements"]["e3"] == "+") or (node["elements"]["e3"] == "-") or (node["elements"]["e3"] == "*"): return TYPE.INT else: return TYPE.ERROR else: return TYPE.ERROR
def test_0(self): node_raise = { "description": "traise", "elements": { "e1": "raise" } } node_add = { "description": "tarithm", "elements": { "e1": { "description": "tint", "elements": { "e1": "2" } }, "e2": { "description": "tvar", "elements": { "e1": "x" } }, "e3": "+" } } node_function = { "description": "tfun", "elements": { "e1": "x", "e2": TYPE.INT, "e3": node_add } } node_app = { "description": "tapp", "elements": { "e1": node_function, "e2": node_raise } } assert infer_type({}, node_app) == TYPE.INT
def t_fun(environment, node): if not validParameters(environment, node): return TYPE.ERROR from main import infer_type parameter = node["elements"]["e1"] parameter_type = node["elements"]["e2"] environment[parameter] = parameter_type body_type = infer_type(environment, node["elements"]["e3"]) if body_type != TYPE.ERROR and parameter_type != TYPE.ERROR and parameter_type != TYPE.UNDEFINED: return TYPE.FUNC(parameter_type, body_type) return TYPE.ERROR
} } } } node_normal = {"description": "tint", "elements": {"e1": "5"}} node_clausula = {"description": "tbool", "elements": {"e1": "true"}} node_root = { "description": "tif", "elements": { "e1": { "description": "tbool", "elements": { "e1": "true" } }, "e2": node_if_son, "e3": { "description": "tint", "elements": { "e1": "5" } } } } # print(infer_type({}, node_if_son)) print(infer_type({}, node_root))
"e1": { "description": "tvar", "elements": { "e1": "f" } }, "e2": { "description": "tint", "elements": { "e1": "4" } } } } node = { "description": "tletrec", "elements": { "function_name": "f", "type1": TYPE.INT, "type2": TYPE.INT, "param": param, "e1": e1, "e2": e2 } } # Input: let rec f: INT -> INT = (fn x: INT => x) in f 4 # Output: INT print(infer_type({}, node))