aboutsummaryrefslogtreecommitdiff
path: root/neb/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'neb/__init__.py')
-rw-r--r--neb/__init__.py49
1 files changed, 35 insertions, 14 deletions
diff --git a/neb/__init__.py b/neb/__init__.py
index 7296c58..0542d0d 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
@@ -179,15 +194,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
@@ -199,4 +215,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)