new random seed for every run

This commit is contained in:
Scott Richmond 2024-08-01 18:00:11 -04:00
parent 7f64164078
commit db5622bccd

View File

@ -12,45 +12,72 @@
(import /src/json :as j) (import /src/json :as j)
(defn ludus [source] (defn ludus [source]
# if we can't load prelude, bail
(when (= :error prelude/pkg) (error "could not load prelude")) (when (= :error prelude/pkg) (error "could not load prelude"))
# get us a clean working slate
(def ctx @{:^parent prelude/ctx}) (def ctx @{:^parent prelude/ctx})
(def errors @[]) (def errors @[])
(var result @"") (var result @"")
(def console @"") (def console @"")
# capture all `print`s
(setdyn :out console) (setdyn :out console)
# an output table
# this will change: the shape of our output
# at the moment, there's only one stack of turtle graphics
# we will be getting more
(def out @{:errors errors :result result (def out @{:errors errors :result result
:io @{ :io @{
:stdout @{:proto [:text-stream "0.1.0"] :data console} :stdout @{:proto [:text-stream "0.1.0"] :data console}
:turtle @{:proto [:turtle-graphics "0.1.0"] :data @[]}}}) :turtle @{:proto [:turtle-graphics "0.1.0"] :data @[]}}})
### start the program
# first, scanning
(def scanned (s/scan source)) (def scanned (s/scan source))
(when (any? (scanned :errors)) (when (any? (scanned :errors))
(each err (scanned :errors) (each err (scanned :errors)
(e/scan-error err)) (e/scan-error err))
(break (-> out j/encode string))) (break (-> out j/encode string)))
# then, parsing
(def parsed (p/parse scanned)) (def parsed (p/parse scanned))
(when (any? (parsed :errors)) (when (any? (parsed :errors))
(each err (parsed :errors) (each err (parsed :errors)
(e/parse-error err)) (e/parse-error err))
(break (-> out j/encode string))) (break (-> out j/encode string)))
# then, validation
(def validated (v/valid parsed ctx)) (def validated (v/valid parsed ctx))
(when (any? (validated :errors)) (when (any? (validated :errors))
(each err (validated :errors) (each err (validated :errors)
(e/validation-error err)) (e/validation-error err))
(break (-> out j/encode string))) (break (-> out j/encode string)))
# and, finally, try interpreting the program
(try (do (try (do
# we need to do this every run or we get the very same sequence of "random" numbers every time we run a program
(math/seedrandom (os/cryptorand 8)) (math/seedrandom (os/cryptorand 8))
(set result (i/interpret (parsed :ast) ctx))) (set result (i/interpret (parsed :ast) ctx)))
([err] ([err]
(e/runtime-error err) (e/runtime-error err)
(break (-> out j/encode string)))) (break (-> out j/encode string))))
# stop capturing output
(setdyn :out stdout) (setdyn :out stdout)
# update our output table with our output
(set (out :result) (b/show result)) (set (out :result) (b/show result))
(set (((out :io) :turtle) :data) (get-in prelude/pkg [:turtle_commands :^value])) (set (((out :io) :turtle) :data) (get-in prelude/pkg [:turtle_commands :^value]))
# run the "postlude": any Ludus code that needs to run after each program
# right now this is just resetting the boxes that hold turtle commands and state
(try (try
(i/interpret prelude/post/ast ctx) (i/interpret prelude/post/ast ctx)
([err] (e/runtime-error err))) ([err] (e/runtime-error err)))
# json-encode our output table, and convert it from a buffer to a string (which we require for playing nice with WASM/C)
(-> out j/encode string)) (-> out j/encode string))
#### REPL
(comment (comment
# (do # (do
# (def start (os/clock)) # (def start (os/clock))