bbc-basic: Add 'seq' core function.
authorBen Harris <bjh21@bjh21.me.uk>
Tue, 14 May 2019 22:17:21 +0000 (23:17 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 18 May 2019 15:33:16 +0000 (16:33 +0100)
bbc-basic/core
bbc-basic/stepA_mal.bbc

index 5c13ebd..f12e335 100644 (file)
@@ -282,6 +282,10 @@ DEF FNcore_call(fn%, args%)
     WHEN 59
       PROCcore_prepare_args("?", "macro?")
       =FNalloc_boolean(FNis_macro(args%(0)))
+    DATA seq, 60
+    WHEN 60
+      PROCcore_prepare_args("?", "seq")
+      =FNcore_seq(args%(0))
     DATA "", -1
   ENDCASE
 ERROR &40E809F1, "Call to non-existent core function"
@@ -450,6 +454,23 @@ DEF FNcore_assoc(map%, args%)
   ENDWHILE
 =map%
 
+REM  Innards of the 'seq' function
+DEF FNcore_seq(val%)
+  LOCAL s$, i%
+  IF FNis_empty(val%) OR FNis_nil(val%) THEN =FNnil
+  IF FNis_list(val%) THEN =val%
+  IF FNis_vector(val%) THEN =FNas_list(val%)
+  IF FNis_string(val%) THEN
+    s$ = FNunbox_string(val%)
+    IF s$ = "" THEN =FNnil
+    val% = FNempty
+    FOR i% = LEN(s$) TO 1 STEP -1
+      val% = FNalloc_pair(FNalloc_string(MID$(s$, i%, 1)), val%)
+    NEXT i%
+    =val%
+  ENDIF
+ERROR &40E8091F, "Argument to 'seq' must be list, vector, string, or nil"
+
 REM Local Variables:
 REM indent-tabs-mode: nil
 REM End:
index 609f862..be2ba2e 100644 (file)
@@ -24,8 +24,6 @@ DATA (def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))
 DATA (defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw "odd number of forms to cond")) (cons 'cond (rest (rest xs)))))))
 DATA (defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))
 DATA (def! *host-language* "BBC BASIC V")
-DATA (def! notimpl (fn* (& _) (throw "Not implemented")))
-DATA (def! seq     notimpl)
 DATA ""
 REPEAT
   READ form$