Basically wire the things up!

This commit is contained in:
Scott Richmond 2023-12-04 00:41:57 -05:00
parent 17592149f1
commit c9ccffa067
7 changed files with 105 additions and 40 deletions

View File

@ -1 +1,2 @@
(ns ludus.data)

View File

@ -895,7 +895,7 @@
interpreted (interpret-ast parsed base-ctx)
namespace (dissoc interpreted ::data/type ::data/name ::data/struct)
context (ns->ctx namespace)]
;(println context)
(println "Prelude fully loaded.")
context))
; ;; TODO: update this to use new parser pipeline & new AST representation
@ -939,9 +939,10 @@
{:result :error :ctx (volatile! orig-ctx)})))))
(defn interpret-safe [source parsed ctx]
(try
(let [base-ctx (volatile! {::parent (volatile! (merge ludus-prelude ctx))})]
(interpret-ast parsed base-ctx))
(try
(println "Running source: " source)
(interpret-ast parsed base-ctx)
(catch #?(:clj Throwable :cljs js/Object) e
(println "Ludus panicked!")
(println "On line" (get-in (ex-data e) [:ast :token :line]))
@ -949,7 +950,7 @@
(println (ex-message e))
(pp/pprint (ex-data e))
(throw e)
)))
))))
;; repl
(comment

42
src/ludus/node.cljc Normal file
View File

@ -0,0 +1,42 @@
(ns ludus.node
(:require [ludus.interpreter :as i]
[ludus.grammar :as g]
[ludus.parser :as p]
[ludus.scanner :as s]
[ludus.prelude :as pre]
[ludus.show :as show]
[ludus.base :as base]
[ludus.data :as data]
)
)
(declare ld->clj)
(defn cljify [[k v]] [k (ld->clj v)])
(defn ld->clj [value]
(case (base/get-type value)
(:nil :number :string :boolean :keyword :set) value
(:list :tuple) (into [] (map ld->clj) (rest value))
(:dict :struct :ns) (into {} (map cljify) (dissoc value ::data/dict ::data/struct ::data/type ::data/name))
:ref (ld->clj @(::value value))
:fn (throw (ex-info (str "Cannot export functions from Ludus to Clojure. You tried exporting " (show/show value)) {}))))
(defn run [source]
(let [user_scanned (s/scan source)
user_tokens (:tokens user_scanned)
user_parsed (p/apply-parser g/script user_tokens)
user_result (i/interpret-safe source user_parsed {})
post_scanned (s/scan pre/postlude)
post_tokens (:tokens post_scanned)
post_parsed (p/apply-parser g/script post_tokens)
post_result (i/interpret-safe source post_parsed {})
ludus_result (assoc post_result :result user_result)
clj_result (ld->clj ludus_result)
]
#?(:clj clj_result :cljs (clj->js clj_result))
))

View File

@ -1,16 +0,0 @@
(ns ludus.node
(:require [ludus.interpreter :as i]
[ludus.grammar :as g]
[ludus.parser :as p]
[ludus.scanner :as s])
)
(defn run [source]
(let [scanned (s/scan source)
tokens (:tokens scanned)
parsed (p/apply-parser g/script tokens)
result (i/interpret-safe source parsed {})]
(clj->js {:result result
:errors []
:console []
:draw []})))

11
src/ludus/postlude.ld Normal file
View File

@ -0,0 +1,11 @@
& this file runs after any given interpretation
& the goal is to output any global state
if turtle_state() :visible? then render_turtle! () else nil
#{
& :result result is provided elsewhere
:errors [] & if we get here there are no errors
:console deref (console)
:draw deref (p5_calls)
}

View File

@ -7,3 +7,9 @@
:clj (slurp "src/ludus/prelude.ld")
:cljs (r/inline "./prelude.ld")
))
(def postlude
#?(
:clj (slurp "src/ludus/postlude.ld")
:cljs (r/inline "./postlude.ld")
))

View File

@ -125,9 +125,24 @@ fn append {
(xs as :set, x) -> base :conj (xs, x)
}
ref console = []
fn add_msg! {
"Adds a message to the console."
(msgs) -> {
let strs = map (show, msgs)
let msg = fold (concat, strs, "")
update! (console, append (_, msg))
:ok
}
}
fn print! {
"Sends a text representation of Ludus values to the console."
(...args) -> base :print (args)
(...args) -> {
base :print (args)
add_msg! (args)
}
}
fn show {
@ -694,23 +709,26 @@ let turtle_angle = 0.375
let turtle_color = (100, 100, 100, 100)
fn render_turtle! () -> {
let state = do turtle_state > deref > last
let state = do turtle_states > deref > last
if state :visible?
then {
add_call! ((:push))
let (r, g, b, a) = turtle_color
add_call! ((:fill, r, g, b, a))
add_call! ((:noStroke))
let #{heading, position} = state
let #{heading, :position (x, y)} = state
add_call! ((:translate, x, y))
add_call! ((:rotate, turn/deg (heading)))
add_call! ((:beginShape))
let head_unit = heading/vec (heading)
let head_unit = heading/vector (heading)
let first = mult (head_unit, turtle_radius)
let second = rotate (first, turtle_angle)
let third = rotate (first, neg (turtle_angle))
add_call! ((:vertex, first))
add_call! ((:vertex, second))
add_call! ((:vertx, third))
let (x1, y1) = first
let (x2, y2) = rotate (first, turtle_angle)
let (x3, y3) = rotate (first, neg (turtle_angle))
add_call! ((:vertex, x1, y1))
add_call! ((:vertex, x2, y2))
add_call! ((:vertex, x3, y3))
add_call! ((:endShape))
add_call! ((:pop))
:ok
}
@ -911,6 +929,7 @@ ns prelude {
inc
dec
print!
console
show
prn!
type
@ -991,4 +1010,5 @@ ns prelude {
heading/vector
turtle_state
p5_calls, turtle_states, turtle_commands
render_turtle!
}