diff options
| -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) | 
