Fully add repeat form

This commit is contained in:
Scott Richmond 2023-12-08 15:27:49 -05:00
parent b285047d60
commit bc5cc37cc1
2 changed files with 32 additions and 13 deletions

View File

@ -228,7 +228,7 @@
(defp loop-expr group order-1 [(quiet :loop) tuple (quiet :with) (defp loop-expr group order-1 [(quiet :loop) tuple (quiet :with)
(flat (choice :loop-body [fn-clause compound-loop]))]) (flat (choice :loop-body [fn-clause compound-loop]))])
(defp repeat-expr group order-1 [(quiet :repeat) (choice :word :number) block]) (defp repeat-expr group order-1 [(quiet :repeat) (choice :times [:word :number]) block])
(defp collection flat choice [struct-literal dict list-literal set-literal tuple]) (defp collection flat choice [struct-literal dict list-literal set-literal tuple])

View File

@ -8,6 +8,7 @@
[ludus.prelude :as prelude] [ludus.prelude :as prelude]
[ludus.data :as data] [ludus.data :as data]
[ludus.show :as show] [ludus.show :as show]
[ludus.error :as error]
;;[ludus.loader :as loader] ;;[ludus.loader :as loader]
[clojure.pprint :as pp] [clojure.pprint :as pp]
[clojure.set] [clojure.set]
@ -674,8 +675,6 @@
(vswap! ctx update-ctx {name ref}) (vswap! ctx update-ctx {name ref})
ref))) ref)))
(defn- interpret-repeat [ast ctx] :TODO)
(defn- interpret-loop [ast ctx] (defn- interpret-loop [ast ctx]
(let [data (:data ast) (let [data (:data ast)
tuple (interpret-ast (first data) ctx) tuple (interpret-ast (first data) ctx)
@ -803,6 +802,18 @@
(vswap! ctx update-ctx {name ns}) (vswap! ctx update-ctx {name ns})
ns)))) ns))))
;; TODO: make this more robust: can dotimes choke on numbers Ludus passes in?
;; TODO:
(defn- interpret-repeat [ast ctx]
(let [data (:data ast)
times-expr (-> data first :data first)
times (if (= :word (:type times-expr))
(resolve-word times-expr ctx)
(-> times-expr :data first))
block (second data)]
(if (not (number? times)) (throw (ex-info (str "Repeat needs a number, not a " (base/get-type times)) {})))
(dotimes [_ times] (interpret-ast block ctx))))
(defn- interpret-literal [ast] (-> ast :data first)) (defn- interpret-literal [ast] (-> ast :data first))
(defn interpret-ast [ast ctx] (defn interpret-ast [ast ctx]
@ -836,8 +847,6 @@
:ref-expr (interpret-ref ast ctx) :ref-expr (interpret-ref ast ctx)
;:when-expr (interpret-ast (-> ast :data first) ctx)
:recur-call :recur-call
{::data/recur true :args (interpret-ast (-> ast :data first) ctx)} {::data/recur true :args (interpret-ast (-> ast :data first) ctx)}
@ -900,6 +909,9 @@
(def ludus-prelude (def ludus-prelude
(let [scanned (scanner/scan prelude/prelude) (let [scanned (scanner/scan prelude/prelude)
parsed (p/apply-parser g/script (:tokens scanned)) parsed (p/apply-parser g/script (:tokens scanned))
; _ (println "Parse status: " (:status parsed))
; _ (if (= :err (:status parsed))
; (throw (ex-info (error/parse-error prelude/prelude parsed) {})))
base-ctx (volatile! {::parent (volatile! {"base" base/base})}) base-ctx (volatile! {::parent (volatile! {"base" base/base})})
interpreted (interpret-ast parsed base-ctx) interpreted (interpret-ast parsed base-ctx)
namespace (dissoc interpreted ::data/type ::data/name ::data/struct) namespace (dissoc interpreted ::data/type ::data/name ::data/struct)
@ -964,19 +976,26 @@
:message (ex-message e)} :message (ex-message e)}
)))) ))))
;; repl
(do
(def source "1 2") ;; repl
(comment
(println "***********")
(def source "
let times = 1.3
repeat times { print! (:foo) }
")
(def tokens (-> source scanner/scan :tokens)) (def tokens (-> source scanner/scan :tokens))
(def ast (p/apply-parser g/script tokens)) (def ast (p/apply-parser g/script tokens))
;(def result (interpret-safe source ast {})) (def result (interpret-safe source ast {}))
(-> ast prettify-ast println) ;(-> ast prettify-ast println)
;(-> ast show/show-pattern println) (println result)
result
) )