from .. import TypeEnum, Environment, Arg, Builtin, evaluate, InterpretPanic, NebType, TypeWrap from ..structs import * TYPES = Environment() def interpretIsBool(symbol, args, env, ns): return Bool(isinstance(args[0], Bool)) TYPES.register("bool?", Builtin("bool?", interpretIsBool, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsFloat(symbol, args, env, ns): return Bool(isinstance(args[0], Float)) TYPES.register("float?", Builtin("float?", interpretIsFloat, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsNumber(symbol, args, env, ns): ret = isinstance(args[0], Int) or isinstance(args[0], Float) return Bool(ret) TYPES.register("number?", Builtin("number?", interpretIsNumber, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsInt(symbol, args, env, ns): return Bool(isinstance(args[0], Int)) TYPES.register("int?", Builtin("int?", interpretIsInt, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsList(symbol, args, env, ns): # if it's not a list, we're done if not isinstance(args[0], List): return Bool(False) # if the symbol isn't a type, we're done elif not isinstance(symbol, Type): return Bool(True) inner = symbol.inner if inner is None or inner.name == ":any": return Bool(True) inner_func = env.get(inner.name).is_func for arg in args[0].args: if inner_func(inner, [arg], env, ns).value is False: return Bool(False) #if not isinstance(arg, String): # return Bool(False) return Bool(True) TYPES.register("list?", Builtin("list?", interpretIsList, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsString(symbol, args, env, ns): return Bool(isinstance(args[0], String)) TYPES.register("string?", Builtin("string?", interpretIsString, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretStringToInt(symbol, args, env, ns): try: val = int(args[0].value) return Int(val) except: raise InterpretPanic(symbol, "can't convert to an :int", args[0]) TYPES.register("string->int", Builtin("string->int", interpretStringToInt, [Arg("arg", TypeEnum.STRING)], return_type=Type(":int"))) def interpretToString(symbol, args, env, ns): item = args[0] if isinstance(item, String): return item elif isinstance(item, Literal): return String(str(item)) else: return String(f"{item}") TYPES.register("->string", Builtin("->string", interpretToString, [Arg("arg", TypeEnum.ANY)], return_type=Type(":string"))) def interpretTypeOf(symbol, args, env, ns): return Type(f"{args[0].type_}") TYPES.register("typeof", Builtin("typeof", interpretTypeOf, [Arg("candidate", TypeEnum.ANY)])) def interpretIsAny(symbol, args, env, ns): return Bool(True) TYPES.register("any?", Builtin("any?", interpretIsAny, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsLiteral(symbol, args, env, ns): return Bool(isinstance(args[0], Literal)) TYPES.register("literal?", Builtin("literal?", interpretIsLiteral, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) def interpretIsListOfString(symbol, args, env, ns): if not isinstance(args[0], List): return Bool(False) for arg in args[0].args: if not isinstance(arg, String): return Bool(False) return Bool(True) TYPES.register("list-of-string?", Builtin("list-of-string?", interpretIsListOfString, [Arg("arg", TypeEnum.ANY)], return_type=Type(":bool"))) # add types to env any_type = NebType(":any", None, interpretIsAny) literal_type = NebType(":literal", any_type, interpretIsLiteral) string_type = NebType(":string", literal_type, interpretIsString) #list_type = NebType(":list", any_type, interpretIsList) bracket_type = NebType(":[]", any_type, interpretIsList) bool_type = NebType(":bool", literal_type, interpretIsBool) number_type = NebType(":number", literal_type, interpretIsNumber) int_type = NebType(":int", number_type, interpretIsInt) float_type = NebType(":float", number_type, interpretIsFloat) #list_of_string_type = NebType(":[:string]", list_type, interpretIsListOfString) TYPES.register(":any", any_type) TYPES.register(":literal", literal_type) TYPES.register(":string", string_type) #TYPES.register(":list", list_type) TYPES.register(":[]", bracket_type) TYPES.register(":bool", bool_type) TYPES.register(":number", number_type) TYPES.register(":int", int_type) TYPES.register(":float", float_type) #TYPES.register(":[:string]", list_of_string_type)