From 810d01108110901a290aa4d4a9cdf96187430d0d Mon Sep 17 00:00:00 2001 From: mryouse Date: Wed, 22 Jun 2022 04:03:13 +0000 Subject: initial commit of user defined types! --- neb/std/core.py | 32 +++++++++++++++++++++++++++++++- neb/std/types.py | 16 ++++++++-------- 2 files changed, 39 insertions(+), 9 deletions(-) (limited to 'neb/std') diff --git a/neb/std/core.py b/neb/std/core.py index 8881468..83b164c 100644 --- a/neb/std/core.py +++ b/neb/std/core.py @@ -1,4 +1,4 @@ -from .. import TypeEnum, Environment, Arg, Builtin, UserFunction, evaluate, interpret, parse, lex, InterpretPanic +from .. import TypeEnum, Environment, Arg, Builtin, UserFunction, evaluate, interpret, parse, lex, InterpretPanic, TypeWrap, Function, UserType from ..structs import * from pathlib import Path @@ -182,3 +182,33 @@ def interpretEval(symbol, args, env, ns): eval_arg = Arg("arg", TypeEnum.ANY) CORE.register("eval", Builtin("eval", interpretEval, [eval_arg])) + +def interpretType(symbol, args, env, ns): + # (type typename parent func) + if not isinstance(args[0], Type): + raise InterpretPanic(symbol, "types must begin with a colon") + name = args[0].name # NOTE: we are not evaluating the name!! + + # TODO we may need to do namespace things here + # also, we probably shouldn't be able to rename types + + if not isinstance(args[1], TypeWrap): + raise InterpretPanic(symbol, "parent must be a valid type", args[1]) + elif not env.contains(args[1].name): + raise InterpretPanic(symbol, f"no such type {args[1]}") + parent = env.get(args[1].name) + + func = args[2] + if not isinstance(func, Function): + raise InterpretPanic(symbol, "validation must be a :func", func) + + new_type = UserType(name, parent, func) + env.register(name, new_type) + return List([]) + +type_name_arg = Arg("name", TypeEnum.ANY, lazy=True) +type_parent_arg = Arg("name", TypeEnum.ANY) +type_func_arg = Arg("func", TypeEnum.ANY) +CORE.register("type", Builtin("type", interpretType, [type_name_arg, type_parent_arg, type_func_arg])) + + diff --git a/neb/std/types.py b/neb/std/types.py index b5fb993..855a1d9 100644 --- a/neb/std/types.py +++ b/neb/std/types.py @@ -70,14 +70,14 @@ def interpretIsLiteral(symbol, args, env, ns): TYPES.register("literal?", Builtin("literal?", interpretIsLiteral, [Arg("arg", TypeEnum.ANY)])) # 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) -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) +any_type = NebType(":any", None, Builtin("any?", interpretIsAny, [Arg("arg", TypeEnum.ANY)])) +literal_type = NebType(":literal", any_type, Builtin("literal?", interpretIsLiteral, [Arg("arg", TypeEnum.ANY)])) +string_type = NebType(":string", literal_type, Builtin("string?", interpretIsString, [Arg("arg", TypeEnum.ANY)])) +list_type = NebType(":list", any_type, Builtin("list?", interpretIsList, [Arg("arg", TypeEnum.ANY)])) +bool_type = NebType(":bool", literal_type, Builtin("bool?", interpretIsBool, [Arg("arg", TypeEnum.ANY)])) +number_type = NebType(":number", literal_type, Builtin("number?", interpretIsNumber, [Arg("arg", TypeEnum.ANY)])) +int_type = NebType(":int", number_type, Builtin("int?", interpretIsInt, [Arg("arg", TypeEnum.ANY)])) +float_type = NebType(":float", number_type, Builtin("float?", interpretIsFloat, [Arg("arg", TypeEnum.ANY)])) TYPES.register(":any", any_type) TYPES.register(":literal", literal_type) -- cgit v1.2.3