aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormryouse2022-05-12 01:58:05 +0000
committermryouse2022-05-12 01:58:05 +0000
commitd75ab6f5ef14cab3c2ad3841258656e217d36043 (patch)
treefdc1a44b17f5611168c4c7a28ed47f92a4ddaad0
parentbb09a338814e1ab6e77451a0cedf61341a4d75c8 (diff)
refactor types using inheritance
-rw-r--r--lexer.py12
-rw-r--r--runner.py2
-rw-r--r--std.py114
-rw-r--r--tokens.py68
4 files changed, 106 insertions, 90 deletions
diff --git a/lexer.py b/lexer.py
index 85b404d..e6116cd 100644
--- a/lexer.py
+++ b/lexer.py
@@ -31,7 +31,7 @@ def lex_string(inp):
elif c == DOUBLE_QUOTE:
#return token, inp[idx + 1:]
- return NebLiteral(NebType.STRING, token), inp[idx + 1:]
+ return NebString(token), inp[idx + 1:]
else:
token += c
@@ -52,7 +52,7 @@ def lex_bool(inp):
raise Exception("invalid boolean")
#return token, inp[len(str(token)):]
- return NebLiteral(NebType.BOOL, token), inp[len(str(token)):]
+ return NebBool(token), inp[len(str(token)):]
def lex_number(inp):
@@ -61,10 +61,10 @@ def lex_number(inp):
if c in (" ", CLOSE_PAREN):
if "." in token:
#return float(token), inp[idx:]
- return NebLiteral(NebType.FLOAT, float(token)), inp[idx:]
+ return NebFloat(float(token)), inp[idx:]
else:
#return int(token), inp[idx:]
- return NebLiteral(NebType.INT, int(token)), inp[idx:]
+ return NebInt(int(token)), inp[idx:]
if c in list(DIGITS): # or c in ("-", "."):
token += c
@@ -88,10 +88,10 @@ def lex_number(inp):
if "." in token:
#return float(token), ""
- return NebLiteral(NebType.FLOAT, float(token)), ""
+ return NebFloat(float(token)), ""
else:
#return int(token), ""
- return NebLiteral(NebType.INT, int(token)), ""
+ return NebInt(int(token)), ""
def lex_symbol(inp):
token = ""
diff --git a/runner.py b/runner.py
index 69112c5..f9c8a4d 100644
--- a/runner.py
+++ b/runner.py
@@ -17,7 +17,7 @@ def evaluate(items, pop):
if not nxt.name in STD:
raise Exception(f"no such symbol: '{nxt.name}'")
this_func = STD[nxt.name]
- return evaluate(items[1:], this_func[list(this_func.keys())[0]].impl) # TODO show all
+ return evaluate(items[1:], this_func[0].impl) # TODO show all
elif isinstance(nxt, NebExpression):
return evaluate(items[1:], evaluate_expression(nxt))
else:
diff --git a/std.py b/std.py
index 8897446..1393acf 100644
--- a/std.py
+++ b/std.py
@@ -1,5 +1,4 @@
from tokens import *
-#from runner import evaluate_expression
import sys
from collections import namedtuple
@@ -9,51 +8,55 @@ STD = {}
DEBUG = True
USER = {}
+
def _get_debug():
return DEBUG
def std_exit(status=None):
out = 0 if status is None else status.value
sys.exit(out)
- return NebLiteral(NebType.BOOL, True) # this should never be reached
+ return NebBool(True) # this should never be reached
def std_print(arg):
print(arg.value)
#return [] # TODO this should return empty list
- return NebLiteral(NebType.BOOL, True)
+ return NebBool(True)
def std_debug_on():
global DEBUG
DEBUG = True
- return NebLiteral(NebType.BOOL, True)
+ return NebBool(True)
def std_debug_off():
global DEBUG
DEBUG = False
- return NebLiteral(NebType.BOOL, True)
+ return NebBool(True)
# math
def std_add(arg1, arg2):
- typ = NebType.INT
- if NebType.FLOAT in (arg1.type_, arg2.type_):
- typ = NebType.FLOAT
- return NebLiteral(typ, arg1.value + arg2.value)
+ res = arg1.value + arg2.value
+ if isinstance(arg1, NebFloat) or isinstance(arg2, NebFloat):
+ return NebFloat(res)
+ else:
+ return NebInt(res)
def std_subtract(arg1, arg2):
- typ = NebType.INT
- if NebType.FLOAT in (arg1.type_, arg2.type_):
- typ = NebType.FLOAT
- return NebLiteral(typ, arg1.value - arg2.value)
+ res = arg1.value - arg2.value
+ if isinstance(arg1, NebFloat) or isinstance(arg2, NebFloat):
+ return NebFloat(res)
+ else:
+ return NebInt(res)
def std_multiply(arg1, arg2):
- typ = NebType.INT
- if NebType.FLOAT in (arg1.type_, arg2.type_):
- typ = NebType.FLOAT
- return NebLiteral(typ, arg1.value * arg2.value)
+ res = arg1.value * arg2.value
+ if isinstance(arg1, NebFloat) or isinstance(arg2, NebFloat):
+ return NebFloat(res)
+ else:
+ return NebInt(res)
# strings
def std_concat(arg1, arg2):
- return NebLiteral(NebType.STRING, f"{arg1.value}{arg2.value}")
+ return NebString(f"{arg1.value}{arg2.value}")
# flow control
def std_if(cond, t_branch, f_branch):
@@ -61,8 +64,6 @@ def std_if(cond, t_branch, f_branch):
ret = evaluate_expression(t_branch)
else:
ret = evaluate_expression(f_branch)
- #return NebLiteral(NebType.BOOL, True)
- #return NebLiteral(, True)
return ret
def evaluate_expression(expr):
@@ -71,60 +72,57 @@ def evaluate_expression(expr):
this_func = STD[expr.symbol.name]
# try to match the signature
- in_sig = expr.in_sig()
- if in_sig in this_func:
- ret = this_func[expr.in_sig()].impl(*(expr.args))
- return ret
+ validated = 0
+ in_sig = expr.args
+ for value in this_func:
+ sig = value.func.args
+ validated = 0
+ if len(sig) != len(in_sig):
+ continue
+ for idx in range(len(sig)):
+ if isinstance(in_sig[idx], sig[idx]):
+ validated += 1
+ if validated == len(sig):
+ ret = value.impl(*(expr.args))
+ return ret
# evaluate inner expressions, if possible/necessary
for idx, arg in enumerate(expr.args):
- if arg.type_ == NebType.EXPR:
+ if isinstance(arg, NebExpression):
expr.args[idx] = evaluate_expression(arg)
return evaluate_expression(expr)
raise Exception(f"'{expr.symbol.name}' called with unknown signature: '{expr.in_sig()}'")
-def build_sig_dict(*args):
- return {arg.func.in_sig(): arg for arg in args}
-
def build_std():
- print_string = FuncImpl(NebFunction("print", [NebType.STRING], NebType.BOOL), std_print)
- STD["print"] = build_sig_dict(print_string)
+ print_string = FuncImpl(NebFunction("print", [NebString], NebString), std_print)
+ STD["print"] = [print_string]
- exit_ = FuncImpl(NebFunction("exit", [], NebType.BOOL), std_exit)
- exit_int = FuncImpl(NebFunction("exit", [NebType.INT], NebType.BOOL), std_exit)
- STD["exit"] = build_sig_dict(exit_, exit_int)
+ exit_ = FuncImpl(NebFunction("exit", [], NebBool), std_exit)
+ exit_int = FuncImpl(NebFunction("exit", [NebInt], NebBool), std_exit)
+ STD["exit"] = [exit_, exit_int]
- debug_on = FuncImpl(NebFunction("debug-on", [], NebType.BOOL), std_debug_on)
- STD["debug-on"] = build_sig_dict(debug_on)
- debug_off = FuncImpl(NebFunction("debug-off", [], NebType.BOOL), std_debug_off)
- STD["debug-off"] = build_sig_dict(debug_off)
+ debug_on = FuncImpl(NebFunction("debug-on", [], NebBool), std_debug_on)
+ STD["debug-on"] = [debug_on]
+ debug_off = FuncImpl(NebFunction("debug-off", [], NebBool), std_debug_off)
+ STD["debug-off"] = [debug_off]
# arithmetic
- add_int_int = FuncImpl(NebFunction("+", [NebType.INT, NebType.INT], NebType.INT), std_add)
- add_int_float = FuncImpl(NebFunction("+", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_add)
- add_float_int = FuncImpl(NebFunction("+", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_add)
- add_float_float = FuncImpl(NebFunction("+", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_add)
- STD["+"] = build_sig_dict(add_int_int, add_int_float, add_float_int, add_float_float)
-
- subtract_int_int = FuncImpl(NebFunction("-", [NebType.INT, NebType.INT], NebType.INT), std_subtract)
- subtract_int_float = FuncImpl(NebFunction("-", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_subtract)
- subtract_float_int = FuncImpl(NebFunction("-", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_subtract)
- subtract_float_float = FuncImpl(NebFunction("-", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_subtract)
- STD["-"] = build_sig_dict(subtract_int_int, subtract_int_float, subtract_float_int, subtract_float_float)
-
- multiply_int_int = FuncImpl(NebFunction("*", [NebType.INT, NebType.INT], NebType.INT), std_multiply)
- multiply_int_float = FuncImpl(NebFunction("*", [NebType.INT, NebType.FLOAT], NebType.FLOAT), std_multiply)
- multiply_float_int = FuncImpl(NebFunction("*", [NebType.FLOAT, NebType.INT], NebType.FLOAT), std_multiply)
- multiply_float_float = FuncImpl(NebFunction("*", [NebType.FLOAT, NebType.FLOAT], NebType.FLOAT), std_multiply)
- STD["*"] = build_sig_dict(multiply_int_int, multiply_int_float, multiply_float_int, multiply_float_float)
+ add = FuncImpl(NebFunction("+", [NebNumber, NebNumber], NebNumber), std_add)
+ STD["+"] = [add]
+
+ subtract = FuncImpl(NebFunction("-", [NebNumber, NebNumber], NebNumber), std_subtract)
+ STD["-"] = [subtract]
+
+ multiply = FuncImpl(NebFunction("*", [NebNumber, NebNumber], NebNumber), std_multiply)
+ STD["*"] = [multiply]
# strings
- concat_string_string = FuncImpl(NebFunction("concat", [NebType.STRING, NebType.STRING], NebType.STRING), std_concat)
- STD["concat"] = build_sig_dict(concat_string_string)
+ concat_string_string = FuncImpl(NebFunction("concat", [NebString, NebString], NebString), std_concat)
+ STD["concat"] = [concat_string_string]
# flow control
- if_bool_expr_expr = FuncImpl(NebFunction("if", [NebType.BOOL, NebType.EXPR, NebType.EXPR], NebType.ANY), std_if)
- STD["if"] = build_sig_dict(if_bool_expr_expr)
+ if_bool_expr_expr = FuncImpl(NebFunction("if", [NebBool, NebExpression, NebExpression], NebType.ANY), std_if)
+ STD["if"] = [if_bool_expr_expr]
build_std()
diff --git a/tokens.py b/tokens.py
index cc8e7a7..a8f6268 100644
--- a/tokens.py
+++ b/tokens.py
@@ -16,25 +16,36 @@ class NebType(Enum):
SYMBOL = auto()
def __str__(self):
- return ":" + self.name.lower()
+ return self.name.lower()
-@dataclass
-class NebToken:
- type_: NebType
+class NebBaseType:
-class NebLiteral(NebToken):
+ def __init__(self, type_name, type_):
+ self.type_name = type_name
+ self.type_ = type_
- def __init__(self, type_, value):
- super().__init__(type_)
+ def __str__(self):
+ return f":{self.type_name}"
+
+class NebAny(NebBaseType):
+ def __init__(self, type_name, type_):
+ super().__init__("any", NebType.ANY)
+
+class NebLiteral(NebBaseType):
+
+ def __init__(self, type_name, type_, value):
+ super().__init__(type_name, type_)
self.value = value
def __str__(self):
fixed = str(self.value)
- if self.type_ == NebType.BOOL:
+ #if self.type_ == NebBaseType.BOOL:
+ if isinstance(self, NebBool):
fixed = f"#{str(self.value).lower()}"
- elif self.type_ == NebType.STRING:
+ #elif self.type_ == NebBaseType.STRING:
+ elif isinstance(self, NebString):
fixed = f'"{self.value}"'
- return f"{fixed} <{self.type_}>"
+ return f"{fixed} <:{self.type_name}>"
class NebSeparator():
pass
@@ -47,19 +58,19 @@ class NebClose(NebSeparator):
def __str__(self):
return ")"
-class NebSymbol(NebToken):
+class NebSymbol(NebBaseType):
def __init__(self, name):
- super().__init__(NebType.SYMBOL)
+ super().__init__("symbol", NebType.SYMBOL)
self.name = name
def __str__(self):
return f"'{self.name}"
-class NebExpression(NebToken):
+class NebExpression(NebBaseType):
def __init__(self, symbol, args):
- super().__init__(NebType.EXPR)
+ super().__init__("expr", NebType.EXPR)
self.symbol = symbol
self.args = args
self.returns = None
@@ -71,7 +82,7 @@ class NebExpression(NebToken):
out = f"({self.symbol}"
for arg in self.args:
out += f" {arg}"
- out += f") <{self.type_}> -> <{self.out_sig()}>"
+ out += f") <:{self.type_}> -> <{self.out_sig()}>"
return out
def in_sig(self):
@@ -83,9 +94,6 @@ class NebExpression(NebToken):
else:
return ":" + self.returns.lower()
- def sig(self):
- return (self.in_sig() + " > " + self.out_sig()).strip()
-
class NebFunction():
def __init__(self, name, args, returns):
@@ -93,12 +101,22 @@ class NebFunction():
self.args = args
self.returns = returns
- def in_sig(self):
- return " ".join(":" + x.name.lower() for x in self.args)
-
- def out_sig(self):
- return ":" + self.returns.lower()
+class NebBool(NebLiteral):
+ def __init__(self, value):
+ super().__init__("bool", NebType.BOOL, value)
+
+class NebString(NebLiteral):
+ def __init__(self, value):
+ super().__init__("string", NebType.STRING, value)
+
+class NebNumber(NebLiteral):
+ pass
+
+class NebInt(NebNumber):
+ def __init__(self, value):
+ super().__init__("int", NebType.INT, value)
- def sig(self):
- return (self.in_sig() + " > " + self.out_sig()).strip()
+class NebFloat(NebNumber):
+ def __init__(self, value):
+ super().__init__("float", NebType.FLOAT, value)