aboutsummaryrefslogtreecommitdiff
path: root/neb
diff options
context:
space:
mode:
authormryouse2022-07-27 00:43:17 +0000
committermryouse2022-07-27 00:43:17 +0000
commitaa52ae991cd7bfaebd358f7d1a9482613b82396c (patch)
treeddfe4fe51bc5280a59df970f2b13d75cf5215128 /neb
parentf2125f46a689abd037b081a17c112ec3170ee0e4 (diff)
implement {} syntax for non-empty lists
Diffstat (limited to 'neb')
-rw-r--r--neb/lexer.py6
-rw-r--r--neb/parser.py11
-rw-r--r--neb/std/types.py28
-rw-r--r--neb/structs.py11
4 files changed, 53 insertions, 3 deletions
diff --git a/neb/lexer.py b/neb/lexer.py
index 5b3fff1..e9142bb 100644
--- a/neb/lexer.py
+++ b/neb/lexer.py
@@ -21,7 +21,7 @@ keywords = {
WHITESPACE = [" ", "\n", "\t"]
-SEPARATORS = WHITESPACE + [")", "]"]
+SEPARATORS = WHITESPACE + [")", "]", "}"]
DIGITS = list("0123456789")
def lex(data):
@@ -51,6 +51,10 @@ def lex(data):
tokens.append(Token(TokenType.OPEN_BRACKET, "[", None, line))
elif char == "]":
tokens.append(Token(TokenType.CLOSE_BRACKET, "]", None, line))
+ elif char == "{":
+ tokens.append(Token(TokenType.OPEN_BRACE, "{", None, line))
+ elif char == "}":
+ tokens.append(Token(TokenType.CLOSE_BRACE, "}", None, line))
elif char == ":":
tokens.append(Token(TokenType.COLON, ":", None, line))
# numbers
diff --git a/neb/parser.py b/neb/parser.py
index 930e77e..81f7672 100644
--- a/neb/parser.py
+++ b/neb/parser.py
@@ -160,6 +160,17 @@ def parseType(token, prev, tokens):
if tokens[1+counter].type_ != TokenType.CLOSE_BRACKET:
raise ParseError("invalid type definition (expecting close bracket)", tokens[1+counter].line)
return Type(f":[]", typ), counter + 3
+
+ elif tokens[0].type_ == TokenType.OPEN_BRACE:
+ # only format currently supported:
+ # [ <type> ]
+ if tokens[1].type_ != TokenType.COLON:
+ raise ParseError("invalid type definition (expecting colon)", tokens[1].line)
+ typ, counter = parseType(tokens[1], tokens[0], tokens[2:])
+ if tokens[1+counter].type_ != TokenType.CLOSE_BRACE:
+ raise ParseError("invalid type definition (expecting close brace)", tokens[1+counter].line)
+ return Type(":{}", typ), counter + 3
+
else:
raise ParseError("invalid type definition!", tokens[0].line)
diff --git a/neb/std/types.py b/neb/std/types.py
index 7e77597..cc40066 100644
--- a/neb/std/types.py
+++ b/neb/std/types.py
@@ -62,6 +62,32 @@ islist_multi = MultiFunction("list?")
islist_multi.register(islist_func)
TYPES.register("list?", islist_multi)
+def interpretIsNonEmptyList(symbol, args, env, ns):
+
+ # if it's not a list, we're done
+ if not (isinstance(args[0], List) or isinstance(args[0], Expr)):
+ return Bool(False)
+
+ # if it's empty, we're done
+ elif len(args[0].args) == 0:
+ 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_type = env.get(f"{inner.name}")
+ for arg in args[0].args:
+ valid = inner_type.validate_type(arg, env, ns)
+ if valid.value is False:
+ return Bool(False)
+ return Bool(True)
+
+
def interpretIsString(symbol, args, env, ns):
return Bool(isinstance(args[0], String))
@@ -142,6 +168,7 @@ 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)
+brace_type = NebType(":{}", any_type, interpretIsNonEmptyList)
bool_type = NebType(":bool", literal_type, interpretIsBool)
number_type = NebType(":number", literal_type, interpretIsNumber)
int_type = NebType(":int", number_type, interpretIsInt)
@@ -154,6 +181,7 @@ TYPES.register(":literal", literal_type)
TYPES.register(":string", string_type)
#TYPES.register(":list", list_type)
TYPES.register(":[]", bracket_type)
+TYPES.register(":{}", brace_type)
TYPES.register(":bool", bool_type)
TYPES.register(":number", number_type)
TYPES.register(":int", int_type)
diff --git a/neb/structs.py b/neb/structs.py
index 51cdb34..8c643b5 100644
--- a/neb/structs.py
+++ b/neb/structs.py
@@ -13,6 +13,8 @@ class TokenType(Enum):
CLOSE_PAREN = auto()
OPEN_BRACKET = auto()
CLOSE_BRACKET = auto()
+ OPEN_BRACE = auto()
+ CLOSE_BRACE = auto()
EOF = auto()
@@ -111,10 +113,15 @@ class Type:
return f":[:any]"
else:
return f":[{self.inner}]"
+ elif self.name == ":{}":
+ if self.inner is None:
+ return ":{:any}"
+ else:
+ return ":{" + f"{self.inner}" + "}"
else:
return self.name
-_native_types = ":any :literal :string :bool :number :int :float :[] :handle :type"
+_native_types = ":any :literal :string :bool :number :int :float :[] :{} :handle :type"
ALL_TYPES = {x: Type(x) for x in _native_types.split(" ")}
class Symbol:
@@ -151,7 +158,7 @@ class NebFuncDef:
class Expr:
def __init__(self, args):
self.args = args
- self.type_ = ALL_TYPES[":[]"] # TODO no it's not
+ self.type_ = ALL_TYPES[":{}"] # TODO no it's not
def __str__(self):
return "(" + " ".join(f"{arg}" for arg in self.args) + ")"