diff options
Diffstat (limited to 'neb/__init__.py')
| -rw-r--r-- | neb/__init__.py | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/neb/__init__.py b/neb/__init__.py index dd7245a..42e1d00 100644 --- a/neb/__init__.py +++ b/neb/__init__.py @@ -3,6 +3,7 @@ from .parser import parse from .exceptions import * from .typeclass import TypeEnum, is_subtype_of from .structs import * +from copy import deepcopy def interpret(exprs, env, ns=None): ret = None @@ -15,9 +16,21 @@ def evaluate(expr, env, ns=None): return expr elif isinstance(expr, Symbol) or isinstance(expr, Type): if env.contains(expr.name): - return evaluate(env.get(expr.name), env, ns) + if isinstance(expr, Type) and expr.inner is not None: + typecopy = deepcopy(env.get(expr.name)) + inner = env.get(f"{expr.inner}") + typecopy.name.inner = inner + return evaluate(typecopy, env, ns) + else: + return evaluate(env.get(expr.name), env, ns) elif ns is not None and env.contains(f"{ns}/{expr.name}"): - return evaluate(env.get(f"{ns}/{expr.name}"), env, ns) + if isinstance(expr, Type) and expr.inner is not None: + typecopy = deepcopy(env.get(f"{ns}/{expr.name}")) + inner = env.get(f"{expr.inner}") + typecopy.name.inner = inner + return evaluate(typecopy, env, ns) + else: + return evaluate(env.get(f"{ns}/{expr.name}"), env, ns) else: if isinstance(expr, Symbol): raise NebPanic(f"no such symbol: {expr}") @@ -46,7 +59,8 @@ class Function: self.body = body self.args = args self.many = many - self.type_ = TypeEnum.ANY # TODO no it's not + #self.type_ = TypeEnum.ANY # TODO no it's not + self.type_ = Type(":any") # TODO no it's not self.return_type = Type(":any") def describe(self, name=None): @@ -82,8 +96,7 @@ class Function: ret.append(param) continue ev = evaluate(param, env, ns) - expected_name = f"{arg.type_}" - expected_type = env.get(expected_name) + expected_type = evaluate(arg.type_, env, ns) valid = expected_type.validate_type(ev, env, ns) if not valid.value: exp = f"{arg.type_}" @@ -146,9 +159,11 @@ class UserFunction(Function): prev_type = False elif isinstance(param, Type) and not prev_type and not first: if many is None: - args[-1].type_ = param.name + #args[-1].type_ = param.name + args[-1].type_ = param else: - many.type_ = param.name + #many.type_ = param.name + many.type_ = param prev_type = True else: raise NebPanic("invalid :func signature", param) @@ -171,7 +186,7 @@ class UserFunction(Function): class TypeWrap: def __init__(self, name, parent, is_func): - self.name = name + self.name = ALL_TYPES[name] self.parent = parent self.is_func = is_func self.type_ = TypeEnum.TYPE @@ -180,15 +195,16 @@ class TypeWrap: # if it's an any type, it's valid if self.parent is None: return Bool(True) - if isinstance(self.is_func, UserFunction): - valid = self.is_func.call(Expr([None, target]), env, ns) + if isinstance(self.is_func, Function): + valid = self.is_func.call(Expr([self.name, target]), env, ns) else: - valid = self.is_func(None, [target], env, ns) + valid = self.is_func(self.name, [target], env, ns) if valid.value == True: return valid - parent_type = env.get(f"{target.type_}") + + parent_type = env.get(target.type_.name) while valid.value != True and parent_type.parent is not None: - parent_type = env.get(f"{parent_type.parent}") + parent_type = env.get(parent_type.parent.name.name) valid = Bool(self.name == parent_type.name) # TODO wrong return valid @@ -200,4 +216,9 @@ class NebType(TypeWrap): pass class UserType(TypeWrap): - pass + + def __init__(self, name, parent, is_func): + if name in ALL_TYPES: + raise NebPanic(f"already a type called {name}") + ALL_TYPES[name] = Type(name) + super().__init__(name, parent, is_func) |
