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/
|
||||
checkouts/
|
||||
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,9 +63,9 @@
|
|||
::data/type ::data/clj
|
||||
:body dec})
|
||||
|
||||
(def ld-not {:name "not"
|
||||
::data/type ::data/clj
|
||||
:body not})
|
||||
(def not- {:name "not"
|
||||
::data/type ::data/clj
|
||||
:body not})
|
||||
|
||||
(def panic! {:name "panic!"
|
||||
::data/type ::data/clj
|
||||
|
@ -118,10 +118,6 @@
|
|||
(get map key default)
|
||||
default)))})
|
||||
|
||||
(def first- {:name "first"
|
||||
::data/type ::data/clj
|
||||
:body (fn [v] (second v))})
|
||||
|
||||
(def rest- {:name "rest"
|
||||
::data/type ::data/clj
|
||||
:body (fn [v]
|
||||
|
@ -129,17 +125,7 @@
|
|||
|
||||
(def nth- {:name "nth"
|
||||
::data/type ::data/clj
|
||||
:body (fn
|
||||
([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)))})
|
||||
:body nth})
|
||||
|
||||
(def types {
|
||||
:keyword
|
||||
|
@ -160,6 +146,12 @@
|
|||
:cljs js/Number
|
||||
)
|
||||
|
||||
:integer
|
||||
#?(
|
||||
:clj java.lang.Integer
|
||||
:cljs js/Number
|
||||
)
|
||||
|
||||
:string
|
||||
#?(
|
||||
:clj java.lang.String
|
||||
|
@ -202,6 +194,8 @@
|
|||
|
||||
(= (:double types) t) :number
|
||||
|
||||
(= (:integer types) t) :number
|
||||
|
||||
(= (:string types) t) :string
|
||||
|
||||
(= (:boolean types) t) :boolean
|
||||
|
@ -220,6 +214,7 @@
|
|||
::data/ns :ns)
|
||||
(::data/dict value) :dict
|
||||
(::data/struct value) :struct
|
||||
(::data/ref value) :ref
|
||||
:else :none
|
||||
))))
|
||||
|
||||
|
@ -255,35 +250,73 @@
|
|||
|
||||
(def count- {:name "count"
|
||||
::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 {
|
||||
"id" id
|
||||
"eq" eq
|
||||
"add" add
|
||||
"print" print-
|
||||
"sub" sub
|
||||
"mult" mult
|
||||
"div" div
|
||||
"gt" gt
|
||||
"gte" gte
|
||||
"lt" lt
|
||||
"lte" lte
|
||||
"inc" inc-
|
||||
"dec" dec-
|
||||
"not" not
|
||||
"show" show
|
||||
"deref" deref-
|
||||
"set!" set!-
|
||||
"and" and-
|
||||
"or" or-
|
||||
"assoc" assoc-
|
||||
"conj" conj-
|
||||
"get" get-
|
||||
"type" type-
|
||||
"extern" extern
|
||||
"first" first-
|
||||
"rest" rest-
|
||||
"nth" nth-
|
||||
"count" count-
|
||||
:id id
|
||||
:eq eq
|
||||
:add add
|
||||
:print print-
|
||||
:sub sub
|
||||
:mult mult
|
||||
:div div
|
||||
:gt gt
|
||||
:gte gte
|
||||
:lt lt
|
||||
:lte lte
|
||||
:inc inc-
|
||||
:dec dec-
|
||||
:not not-
|
||||
:show show
|
||||
:deref deref-
|
||||
:set! set!-
|
||||
:and and-
|
||||
:or or-
|
||||
:assoc assoc-
|
||||
:conj conj-
|
||||
:get get-
|
||||
:type type-
|
||||
:extern extern
|
||||
:rest rest-
|
||||
:nth nth-
|
||||
: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
|
||||
(defn- ludus-resolve [key ctx-vol]
|
||||
(let [ctx @ctx-vol]
|
||||
(println "Resolving " key)
|
||||
(println "Current context: " (keys ctx))
|
||||
;(println "Resolving " key " in context " (keys ctx))
|
||||
;(println "Current context: " (keys ctx))
|
||||
;(println "Parent context: " (keys (if (::parent ctx) (deref (::parent ctx)) {})))
|
||||
(if (contains? ctx key)
|
||||
(get ctx key)
|
||||
|
@ -473,7 +473,7 @@
|
|||
(interpret-ast body fn-ctx)))
|
||||
(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)
|
||||
(if (= 2 (count args))
|
||||
|
@ -488,7 +488,7 @@
|
|||
(kw target)))
|
||||
(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]
|
||||
;(println "interpreting arg" args)
|
||||
|
@ -873,7 +873,7 @@
|
|||
(def ludus-prelude
|
||||
(let [scanned (scanner/scan prelude/prelude)
|
||||
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)
|
||||
namespace (dissoc interpreted ::data/type ::data/name ::data/struct)
|
||||
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/ellipse js/mouseX js/mouseY 80 80))
|
||||
|
||||
(doto js/window
|
||||
(o/set "setup" setup)
|
||||
(o/set "draw" draw))
|
||||
(defn init []
|
||||
(doto js/window
|
||||
(o/set "setup" setup)
|
||||
(o/set "draw" draw)))
|
||||
|
||||
(o/set js/window "ludus_init" init)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user