aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--neb.py20
-rw-r--r--neb/std/boolean.py24
-rw-r--r--repl.neb35
3 files changed, 63 insertions, 16 deletions
diff --git a/neb.py b/neb.py
index 7e3380f..86c96b1 100644
--- a/neb.py
+++ b/neb.py
@@ -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")))
diff --git a/repl.neb b/repl.neb
index e8cb9b5..cc8ae06 100644
--- a/repl.neb
+++ b/repl.neb
@@ -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)