Lots of progress
This commit is contained in:
parent
3f865a64d7
commit
bc7565926a
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
||||||
target/
|
target/stale
|
||||||
|
target/js
|
||||||
|
target/classes
|
||||||
classes/
|
classes/
|
||||||
checkouts/
|
checkouts/
|
||||||
profiles.clj
|
profiles.clj
|
||||||
|
|
64
prelude.ld
64
prelude.ld
|
@ -1,64 +0,0 @@
|
||||||
& this file, uniquely, gets `base` loaded. See src/ludus/base.cljc for exports
|
|
||||||
|
|
||||||
fn first {
|
|
||||||
"Returns the first element of a list or tuple."
|
|
||||||
(xs as :list) -> extern (:first, xs)
|
|
||||||
(xs as :tuple) -> extern (:second, xs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn nth {
|
|
||||||
"Returns the element at index n of a list or tuple. Zero-indexed: the first element is at index 0."
|
|
||||||
(xs as :list, n as :number) -> extern (:nth, xs, n)
|
|
||||||
(xs as :tuple, n as :number) -> extern (:nth, xs, extern (:inc, n))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn count {
|
|
||||||
"Returns the number of elements in a list or tuple."
|
|
||||||
(xs as :list) -> extern (count, xs)
|
|
||||||
(xs as :tuple) -> extern (:dec, extern (:count, xs))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list {
|
|
||||||
"Takes a tuple, and returns it as a list."
|
|
||||||
(xs as :tuple) -> extern (:into, [], extern (:rest, xs))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fold {
|
|
||||||
"Folds a collection."
|
|
||||||
(f as :function, xs as :list) -> extern (:reduce, f, xs)
|
|
||||||
(f as :function, root, xs as :list) -> extern (:reduce, f, root, xs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn conj {
|
|
||||||
"Adds an element to a list. Short for conjoin."
|
|
||||||
() -> []
|
|
||||||
(xs as :list) -> xs
|
|
||||||
(xs as :list, x) -> extern (:conj, xs, x)
|
|
||||||
& (xs, x, ...ys) -> extern (:conj, xs, x, ...ys)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ludus/add {
|
|
||||||
"Adds numbers."
|
|
||||||
() -> 0
|
|
||||||
(x as :number) -> x
|
|
||||||
(x as :number, y as :number) -> add (x, y)
|
|
||||||
(x as :number, y as :number, ...zs) -> fold (ludus/add, add (x, y), zs)
|
|
||||||
}
|
|
||||||
|
|
||||||
ns math {
|
|
||||||
:add ludus/add
|
|
||||||
}
|
|
||||||
|
|
||||||
print ("From Prelude, hello.")
|
|
||||||
|
|
||||||
ns prelude {
|
|
||||||
first
|
|
||||||
nth
|
|
||||||
conj
|
|
||||||
fold
|
|
||||||
list
|
|
||||||
}
|
|
||||||
|
|
||||||
print (prelude)
|
|
||||||
|
|
||||||
prelude
|
|
|
@ -63,7 +63,7 @@
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body dec})
|
:body dec})
|
||||||
|
|
||||||
(def ld-not {:name "not"
|
(def not- {:name "not"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body not})
|
:body not})
|
||||||
|
|
||||||
|
@ -118,10 +118,6 @@
|
||||||
(get map key default)
|
(get map key default)
|
||||||
default)))})
|
default)))})
|
||||||
|
|
||||||
(def first- {:name "first"
|
|
||||||
::data/type ::data/clj
|
|
||||||
:body (fn [v] (second v))})
|
|
||||||
|
|
||||||
(def rest- {:name "rest"
|
(def rest- {:name "rest"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn [v]
|
:body (fn [v]
|
||||||
|
@ -129,17 +125,7 @@
|
||||||
|
|
||||||
(def nth- {:name "nth"
|
(def nth- {:name "nth"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn
|
:body nth})
|
||||||
([i, xs]
|
|
||||||
(cond
|
|
||||||
(> 0 i) nil
|
|
||||||
(contains? xs (inc i)) (nth xs (inc i))
|
|
||||||
:else nil))
|
|
||||||
([i, xs, default]
|
|
||||||
(cond
|
|
||||||
(> 0 i) default
|
|
||||||
(contains? xs (inc i)) (nth xs (inc i))
|
|
||||||
:else default)))})
|
|
||||||
|
|
||||||
(def types {
|
(def types {
|
||||||
:keyword
|
:keyword
|
||||||
|
@ -160,6 +146,12 @@
|
||||||
:cljs js/Number
|
:cljs js/Number
|
||||||
)
|
)
|
||||||
|
|
||||||
|
:integer
|
||||||
|
#?(
|
||||||
|
:clj java.lang.Integer
|
||||||
|
:cljs js/Number
|
||||||
|
)
|
||||||
|
|
||||||
:string
|
:string
|
||||||
#?(
|
#?(
|
||||||
:clj java.lang.String
|
:clj java.lang.String
|
||||||
|
@ -202,6 +194,8 @@
|
||||||
|
|
||||||
(= (:double types) t) :number
|
(= (:double types) t) :number
|
||||||
|
|
||||||
|
(= (:integer types) t) :number
|
||||||
|
|
||||||
(= (:string types) t) :string
|
(= (:string types) t) :string
|
||||||
|
|
||||||
(= (:boolean types) t) :boolean
|
(= (:boolean types) t) :boolean
|
||||||
|
@ -220,6 +214,7 @@
|
||||||
::data/ns :ns)
|
::data/ns :ns)
|
||||||
(::data/dict value) :dict
|
(::data/dict value) :dict
|
||||||
(::data/struct value) :struct
|
(::data/struct value) :struct
|
||||||
|
(::data/ref value) :ref
|
||||||
:else :none
|
:else :none
|
||||||
))))
|
))))
|
||||||
|
|
||||||
|
@ -255,35 +250,73 @@
|
||||||
|
|
||||||
(def count- {:name "count"
|
(def count- {:name "count"
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body (fn [xs] (dec (count xs)))})
|
:body count})
|
||||||
|
|
||||||
|
(def into- {:name "into"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body into})
|
||||||
|
|
||||||
|
(def to_vec {:name "to_vec"
|
||||||
|
::data/type ::data.clj
|
||||||
|
:body (fn [xs] (into [] xs))})
|
||||||
|
|
||||||
|
(def fold {:name "fold"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body reduce})
|
||||||
|
|
||||||
|
(def map- {:name "map"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body map})
|
||||||
|
|
||||||
|
(def prn- {:name "raw"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body println})
|
||||||
|
|
||||||
|
(def concat- {:name "concat"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body (fn [xs ys]
|
||||||
|
(if (= ::data/list (first xs))
|
||||||
|
(into [::data/list] (concat (rest xs) (rest ys)))
|
||||||
|
(into #{} (concat xs ys))))})
|
||||||
|
|
||||||
|
(def str- {:name "str"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body str})
|
||||||
|
|
||||||
(def base {
|
(def base {
|
||||||
"id" id
|
:id id
|
||||||
"eq" eq
|
:eq eq
|
||||||
"add" add
|
:add add
|
||||||
"print" print-
|
:print print-
|
||||||
"sub" sub
|
:sub sub
|
||||||
"mult" mult
|
:mult mult
|
||||||
"div" div
|
:div div
|
||||||
"gt" gt
|
:gt gt
|
||||||
"gte" gte
|
:gte gte
|
||||||
"lt" lt
|
:lt lt
|
||||||
"lte" lte
|
:lte lte
|
||||||
"inc" inc-
|
:inc inc-
|
||||||
"dec" dec-
|
:dec dec-
|
||||||
"not" not
|
:not not-
|
||||||
"show" show
|
:show show
|
||||||
"deref" deref-
|
:deref deref-
|
||||||
"set!" set!-
|
:set! set!-
|
||||||
"and" and-
|
:and and-
|
||||||
"or" or-
|
:or or-
|
||||||
"assoc" assoc-
|
:assoc assoc-
|
||||||
"conj" conj-
|
:conj conj-
|
||||||
"get" get-
|
:get get-
|
||||||
"type" type-
|
:type type-
|
||||||
"extern" extern
|
:extern extern
|
||||||
"first" first-
|
:rest rest-
|
||||||
"rest" rest-
|
:nth nth-
|
||||||
"nth" nth-
|
:count count-
|
||||||
"count" count-
|
:into into-
|
||||||
|
:to_vec to_vec
|
||||||
|
:fold fold
|
||||||
|
:map map
|
||||||
|
:panic! panic!
|
||||||
|
:prn prn-
|
||||||
|
:concat concat-
|
||||||
|
:str str-
|
||||||
})
|
})
|
|
@ -19,8 +19,8 @@
|
||||||
;; that's for later, tho
|
;; that's for later, tho
|
||||||
(defn- ludus-resolve [key ctx-vol]
|
(defn- ludus-resolve [key ctx-vol]
|
||||||
(let [ctx @ctx-vol]
|
(let [ctx @ctx-vol]
|
||||||
(println "Resolving " key)
|
;(println "Resolving " key " in context " (keys ctx))
|
||||||
(println "Current context: " (keys ctx))
|
;(println "Current context: " (keys ctx))
|
||||||
;(println "Parent context: " (keys (if (::parent ctx) (deref (::parent ctx)) {})))
|
;(println "Parent context: " (keys (if (::parent ctx) (deref (::parent ctx)) {})))
|
||||||
(if (contains? ctx key)
|
(if (contains? ctx key)
|
||||||
(get ctx key)
|
(get ctx key)
|
||||||
|
@ -473,7 +473,7 @@
|
||||||
(interpret-ast body fn-ctx)))
|
(interpret-ast body fn-ctx)))
|
||||||
(recur (first clauses) (rest clauses))))
|
(recur (first clauses) (rest clauses))))
|
||||||
|
|
||||||
(throw (ex-info "Match Error: No match found" {:ast (:ast lfn)})))))
|
(throw (ex-info (str "Match Error: No match found for " (show/show args) " in function " (:name lfn)) {:ast (:ast lfn)})))))
|
||||||
|
|
||||||
(keyword? lfn)
|
(keyword? lfn)
|
||||||
(if (= 2 (count args))
|
(if (= 2 (count args))
|
||||||
|
@ -488,7 +488,7 @@
|
||||||
(kw target)))
|
(kw target)))
|
||||||
(throw (ex-info "Called keywords take a single argument" {:ast lfn})))
|
(throw (ex-info "Called keywords take a single argument" {:ast lfn})))
|
||||||
|
|
||||||
:else (throw (ex-info "I don't know how to call that" {:ast lfn}))))
|
:else (throw (ex-info (str "I don't know how to call " (show/show lfn)) {:ast lfn}))))
|
||||||
|
|
||||||
(defn- interpret-args [args ctx]
|
(defn- interpret-args [args ctx]
|
||||||
;(println "interpreting arg" args)
|
;(println "interpreting arg" args)
|
||||||
|
@ -873,7 +873,7 @@
|
||||||
(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))
|
||||||
base-ctx (volatile! {::parent (volatile! 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)
|
||||||
context (ns->ctx namespace)]
|
context (ns->ctx namespace)]
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
(ns ludus.prelude)
|
|
||||||
|
|
||||||
(def prelude (slurp "prelude.ld"))
|
|
9
src/ludus/prelude.cljc
Normal file
9
src/ludus/prelude.cljc
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
(ns ludus.prelude
|
||||||
|
#?(:cljs (:require [shadow.resource :as r]))
|
||||||
|
)
|
||||||
|
|
||||||
|
(def prelude
|
||||||
|
#?(
|
||||||
|
:clj (slurp "src/ludus/prelude.ld")
|
||||||
|
:cljs (r/inline "prelude.ld")
|
||||||
|
))
|
158
src/ludus/prelude.ld
Normal file
158
src/ludus/prelude.ld
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
& this file, uniquely, gets `base` loaded as context. See src/ludus/base.cljc for exports
|
||||||
|
|
||||||
|
fn rest {
|
||||||
|
"Returns all but the first element of a list, as a list."
|
||||||
|
(xs as :list) -> base :rest (xs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inc {
|
||||||
|
"Increments a number."
|
||||||
|
(x as :number) -> base :inc (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dec {
|
||||||
|
"Decrements a number."
|
||||||
|
(x as :number) -> base :dec (x)
|
||||||
|
(x) -> report (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nth {
|
||||||
|
"Returns the element at index n of a list or tuple. Zero-indexed: the first element is at index 0."
|
||||||
|
(xs as :list, n as :number) -> base :nth (xs, inc(n))
|
||||||
|
(xs as :tuple, n as :number) -> base :nth (xs, inc (n))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first {
|
||||||
|
"Returns the first element of a list or tuple."
|
||||||
|
(xs) -> nth (xs, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn second {
|
||||||
|
"Returns the second element of a list or tuple."
|
||||||
|
(xs) -> nth (xs, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count {
|
||||||
|
"Returns the number of elements in a collection (including string)."
|
||||||
|
(xs as :list) -> dec (base :count (report(xs)))
|
||||||
|
(xs as :tuple) -> dec (base :count (xs))
|
||||||
|
(xs as :dict) -> base :count (xs)
|
||||||
|
(xs as :string) -> base :count (xs)
|
||||||
|
(xs as :set) -> base :count (xs)
|
||||||
|
(xs as :struct) -> dec (base :count (xs))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn list {
|
||||||
|
"Takes a tuple, and returns it as a list."
|
||||||
|
(xs as :tuple) -> base :into ([], base :rest (xs))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold {
|
||||||
|
"Folds a list."
|
||||||
|
(f as :fn, xs as :list) -> fold (f, xs, f ())
|
||||||
|
(f as :fn, xs as :list, root) -> loop (root, first (xs), rest (xs)) with {
|
||||||
|
(prev, curr, []) -> f (prev, curr)
|
||||||
|
(prev, curr, remaining) -> recur (
|
||||||
|
f (prev, curr)
|
||||||
|
first (remaining)
|
||||||
|
rest (remaining)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map {
|
||||||
|
"Maps over a list."
|
||||||
|
(f as :fn, xs) -> {
|
||||||
|
fn mapper (prev, curr) -> conj (prev, f (curr))
|
||||||
|
fold (mapper, xs, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn conj {
|
||||||
|
"Adds an element to a list or set. Short for conjoin."
|
||||||
|
() -> []
|
||||||
|
(xs as :list) -> xs
|
||||||
|
(xs as :list, x) -> base :conj (xs, x)
|
||||||
|
(xs as :set) -> xs
|
||||||
|
(xs as :set, x) -> base :conj (xs, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add {
|
||||||
|
"Adds numbers."
|
||||||
|
() -> 0
|
||||||
|
(x as :number) -> x
|
||||||
|
(x as :number, y as :number) -> base :add (x, y)
|
||||||
|
(x as :number, y as :number, ...zs) -> fold (base :add, add (x, y), zs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print {
|
||||||
|
"Sends a text representation of a Ludus value to stdout."
|
||||||
|
(x) -> base :print (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show {
|
||||||
|
"Returns a text representation of a Ludus value as a string."
|
||||||
|
(x) -> base :show (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type {
|
||||||
|
"Returns a keyword representing the type of the value passed in."
|
||||||
|
(x) -> base :type (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prn {
|
||||||
|
"Prints the underlying Clojure data structure of a Ludus value."
|
||||||
|
(x) -> base :prn (x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn concat {
|
||||||
|
"Combines two lists, strings, or sets."
|
||||||
|
(x as :string, y as :string) -> base :str (x, y)
|
||||||
|
(xs as :list, ys as :list) -> base :concat (xs, ys)
|
||||||
|
(xs as :set, ys as :set) -> base :concat (xs, ys)
|
||||||
|
(xs, ys, ...zs) -> fold (concat, zs, concat(xs, ys))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report {
|
||||||
|
"Prints a value, then returns it."
|
||||||
|
(x) -> {
|
||||||
|
print (x)
|
||||||
|
x
|
||||||
|
}
|
||||||
|
(msg as :string, x) -> print (concat (msg, show (x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deref {
|
||||||
|
"Resolves a ref into a value."
|
||||||
|
(r as :ref) -> base :deref (r)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set! {
|
||||||
|
"Sets the value of a ref."
|
||||||
|
(r as :ref, value) -> base :set! (r, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
ns prelude {
|
||||||
|
first
|
||||||
|
second
|
||||||
|
rest
|
||||||
|
nth
|
||||||
|
count
|
||||||
|
conj
|
||||||
|
fold
|
||||||
|
map
|
||||||
|
list
|
||||||
|
inc
|
||||||
|
dec
|
||||||
|
add
|
||||||
|
print
|
||||||
|
show
|
||||||
|
prn
|
||||||
|
type
|
||||||
|
report
|
||||||
|
concat
|
||||||
|
deref
|
||||||
|
set!
|
||||||
|
}
|
||||||
|
|
||||||
|
prelude
|
|
@ -35,6 +35,10 @@
|
||||||
(js/fill 155))
|
(js/fill 155))
|
||||||
(js/ellipse js/mouseX js/mouseY 80 80))
|
(js/ellipse js/mouseX js/mouseY 80 80))
|
||||||
|
|
||||||
|
(defn init []
|
||||||
(doto js/window
|
(doto js/window
|
||||||
(o/set "setup" setup)
|
(o/set "setup" setup)
|
||||||
(o/set "draw" draw))
|
(o/set "draw" draw)))
|
||||||
|
|
||||||
|
(o/set js/window "ludus_init" init)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user