diff options
| author | mryouse | 2022-05-12 01:58:05 +0000 |
|---|---|---|
| committer | mryouse | 2022-05-12 01:58:05 +0000 |
| commit | d75ab6f5ef14cab3c2ad3841258656e217d36043 (patch) | |
| tree | fdc1a44b17f5611168c4c7a28ed47f92a4ddaad0 | |
| parent | bb09a338814e1ab6e77451a0cedf61341a4d75c8 (diff) | |
refactor types using inheritance
| -rw-r--r-- | lexer.py | 12 | ||||
| -rw-r--r-- | runner.py | 2 | ||||
| -rw-r--r-- | std.py | 114 | ||||
| -rw-r--r-- | tokens.py | 68 |
4 files changed, 106 insertions, 90 deletions
@@ -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 = "" @@ -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: @@ -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() @@ -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) |
