diff options
| -rw-r--r-- | neb.py | 20 | ||||
| -rw-r--r-- | neb/std/boolean.py | 24 | ||||
| -rw-r--r-- | repl.neb | 35 |
3 files changed, 63 insertions, 16 deletions
@@ -4,6 +4,16 @@ import sys import readline +class NebCompleter: + + def __init__(self, syntax): + self.syntax = syntax + + def complete(self, text, state): + results = [x for x in self.syntax if x.startswith(text)] + [None] + return results[state] + + def build_std(repl=False): GLOBALS = Environment() global_dict = { **BOOLEAN.environment, @@ -34,6 +44,11 @@ def debug(prev_lexed, prev_parsed): def repl(): env = build_std(True) + + readline.parse_and_bind("tab: complete") + cmp = NebCompleter(env.environment.keys()) + readline.set_completer(cmp.complete) + print("### neb :)(:") print("version: < 0") idx = 1 @@ -65,6 +80,11 @@ def repl(): def run_file(filename): env = build_std(True) + + readline.parse_and_bind("tab: complete") + cmp = NebCompleter(env.environment.keys()) + readline.set_completer(cmp.complete) + with open(filename, "r") as fil: data = fil.read() diff --git a/neb/std/boolean.py b/neb/std/boolean.py index e716a87..e480656 100644 --- a/neb/std/boolean.py +++ b/neb/std/boolean.py @@ -1,17 +1,27 @@ -from .. import TypeEnum, Environment, Arg, Builtin, evaluate, InterpretPanic +from .. import TypeEnum, Environment, Arg, Builtin, evaluate, InterpretPanic, TypeWrap from ..structs import * BOOLEAN = Environment() def interpretEq(symbol, args, env, ns): - # NOTE this currently only works for literals - # compare types because 0 != #false in neb - if type(args[0]) == type(args[1]) and args[0].value == args[1].value: - return Bool(True) - else: + # TODO this is a bit hacky + if (isinstance(args[0], Type) or isinstance(args[0], TypeWrap)) and \ + (isinstance(args[1], Type) or isinstance(args[1], TypeWrap)): + if args[0].name == args[1].name: + return Bool(True) + else: + return Bool(False) + elif type(args[0]) != type(args[1]): return Bool(False) + elif isinstance(args[0], Literal): + if args[0].value == args[1].value: + return Bool(True) + else: + return Bool(False) + else: + raise InterpretPanic(symbol, "unknown comparison type", args[0]) -eq_arg = Arg("value", TypeEnum.LITERAL) +eq_arg = Arg("value", TypeEnum.ANY) BOOLEAN.register("eq?", Builtin("eq?", interpretEq, [eq_arg, eq_arg], return_type=Type(":bool"))) @@ -26,18 +26,35 @@ (print "version: < 0") (def next-cmd-num 1) - (func evaluate-cmd (cmd) - (def evaluated (parse-neb cmd)) - (print (concat "=> " (->string evaluated))) - (redef next-cmd-num (+ 1 next-cmd-num)) - (redef _history_ (append _history_ cmd))) + + (func get-non-empty-input () + (def tmp "") + (while (eq? "" tmp) + (redef tmp (strip (read-line (prompt next-cmd-num))))) + tmp) + + (func print-result (res) + (print (concat "=> " + (if (eq? :string (typeof res)) + (concat "\"" res "\"") + (->string res))))) ; this is the actual loop part (while #true - (def this-cmd (strip (read-line (prompt next-cmd-num)))) - (if (not (eq? "" this-cmd)) + (def this-cmd (get-non-empty-input)) + (def panicked #false) ; we may not need this two-step if there's a :panic type + (def evaluated (try - (evaluate-cmd this-cmd) - (print (concat "panic! " _panic_)))))) + (eval (parse-neb this-cmd)) + (block + (redef panicked #true) + _panic_))) + + (if panicked + (print (concat "panic! " evaluated)) + (block + (print-result evaluated) + (redef next-cmd-num (+ 1 next-cmd-num)) + (redef _history_ (append _history_ this-cmd)))))) (repl) |
