Add slice, fix bugs
This commit is contained in:
parent
30fa4e9d97
commit
14862c3ba9
|
@ -137,6 +137,10 @@
|
||||||
::data/type ::data/clj
|
::data/type ::data/clj
|
||||||
:body nth})
|
:body nth})
|
||||||
|
|
||||||
|
(def slice {:name "slice"
|
||||||
|
::data/type ::data/clj
|
||||||
|
:body subvec})
|
||||||
|
|
||||||
(def types {
|
(def types {
|
||||||
:keyword
|
:keyword
|
||||||
#?(
|
#?(
|
||||||
|
@ -402,6 +406,7 @@
|
||||||
:extern extern
|
:extern extern
|
||||||
:rest rest-
|
:rest rest-
|
||||||
:nth nth-
|
:nth nth-
|
||||||
|
:slice slice
|
||||||
:count count-
|
:count count-
|
||||||
:into into-
|
:into into-
|
||||||
:to_vec to_vec
|
:to_vec to_vec
|
||||||
|
|
|
@ -648,7 +648,7 @@
|
||||||
(let [data (:data ast)
|
(let [data (:data ast)
|
||||||
word (first data)
|
word (first data)
|
||||||
ns (resolve-word word ctx)]
|
ns (resolve-word word ctx)]
|
||||||
(println "use: " ns)
|
; (println "use: " ns)
|
||||||
(if (not (= (::data/type ns) ::data/ns))
|
(if (not (= (::data/type ns) ::data/ns))
|
||||||
(throw (ex-info (str "`use` may only use namespaces; " (-> word :data first) " is not a namespace") {:ast ast}))
|
(throw (ex-info (str "`use` may only use namespaces; " (-> word :data first) " is not a namespace") {:ast ast}))
|
||||||
(let [ns-entries (dissoc ns ::data/type ::data/name ::data/struct)
|
(let [ns-entries (dissoc ns ::data/type ::data/name ::data/struct)
|
||||||
|
|
|
@ -14,13 +14,20 @@ fn inc {
|
||||||
fn dec {
|
fn dec {
|
||||||
"Decrements a number."
|
"Decrements a number."
|
||||||
(x as :number) -> base :dec (x)
|
(x as :number) -> base :dec (x)
|
||||||
(x) -> report (x)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nth {
|
fn nth {
|
||||||
"Returns the element at index n of a list or tuple. Zero-indexed: the first element is at index 0."
|
"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 :list, n as :number) -> when {
|
||||||
(xs as :tuple, n as :number) -> base :nth (xs, inc (n))
|
neg? (n) -> nil
|
||||||
|
gte? (n, count (xs)) -> nil
|
||||||
|
else -> base :nth (xs, inc (n))
|
||||||
|
}
|
||||||
|
(xs as :tuple, n as :number) -> when {
|
||||||
|
neg? (n) -> nil
|
||||||
|
gte? (n, count (xs)) -> nil
|
||||||
|
else -> base :nth (xs, inc (n))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn first {
|
fn first {
|
||||||
|
@ -33,9 +40,33 @@ fn second {
|
||||||
(xs) -> nth (xs, 1)
|
(xs) -> nth (xs, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn last {
|
||||||
|
"Returns the last element of a list or tuple."
|
||||||
|
(xs) -> nth (xs, sub (count (xs), 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn butlast {
|
||||||
|
"Returns a list, omitting the last element."
|
||||||
|
(xs as :list) -> base :slice (xs, sub (count (xs), 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slice {
|
||||||
|
"Returns a slice of a list, representing a sub-list."
|
||||||
|
(xs as :list, end as :number) -> slice (xs, 0, end)
|
||||||
|
(xs as :list, start as :number, end as :number) -> when {
|
||||||
|
gte? (start, end) -> []
|
||||||
|
gt? (end, count (xs)) -> slice (xs, start, count (xs))
|
||||||
|
neg? (start) -> slice (xs, 0, end)
|
||||||
|
else -> {
|
||||||
|
let slice = base :slice (xs, inc (start), inc (end))
|
||||||
|
base :into ([], slice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn count {
|
fn count {
|
||||||
"Returns the number of elements in a collection (including string)."
|
"Returns the number of elements in a collection (including string)."
|
||||||
(xs as :list) -> dec (base :count (report(xs)))
|
(xs as :list) -> dec (base :count (xs))
|
||||||
(xs as :tuple) -> dec (base :count (xs))
|
(xs as :tuple) -> dec (base :count (xs))
|
||||||
(xs as :dict) -> base :count (xs)
|
(xs as :dict) -> base :count (xs)
|
||||||
(xs as :string) -> base :count (xs)
|
(xs as :string) -> base :count (xs)
|
||||||
|
@ -118,14 +149,14 @@ fn concat {
|
||||||
(xs, ys, ...zs) -> fold (concat, zs, concat(xs, ys))
|
(xs, ys, ...zs) -> fold (concat, zs, concat(xs, ys))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report {
|
fn report! {
|
||||||
"Prints a value, then returns it."
|
"Prints a value, then returns it."
|
||||||
(x) -> {
|
(x) -> {
|
||||||
print (x)
|
print! (x)
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
(msg as :string, x) -> {
|
(msg as :string, x) -> {
|
||||||
print (concat (msg, show (x)))
|
print! (concat (msg, show (x)))
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,18 +646,38 @@ let turtle_init = #{
|
||||||
& the first member of each tuple is the command
|
& the first member of each tuple is the command
|
||||||
ref turtle_commands = []
|
ref turtle_commands = []
|
||||||
|
|
||||||
|
ref last_command = ()
|
||||||
|
|
||||||
& give ourselves a ref for current turtle state
|
& give ourselves a ref for current turtle state
|
||||||
ref turtle_state = turtle_init
|
ref turtle_state = turtle_init
|
||||||
|
|
||||||
& and a list of turtle states
|
& and a list of turtle states
|
||||||
ref turtle_states = [turtle_init]
|
ref turtle_states = [turtle_init]
|
||||||
|
|
||||||
|
ref p5_calls = [
|
||||||
|
(:background, 0)
|
||||||
|
]
|
||||||
|
|
||||||
|
fn add_call! (call) -> update! (p5_calls, conj (_, call))
|
||||||
|
|
||||||
fn add_command! (command) -> {
|
fn add_command! (command) -> {
|
||||||
update! (turtle_commands, append (_, command))
|
update! (turtle_commands, append (_, command))
|
||||||
|
make! (last_command, command)
|
||||||
let current_state = deref (turtle_state)
|
let current_state = deref (turtle_state)
|
||||||
let new_state = apply_command (current_state, command)
|
let new_state = apply_command (current_state, command)
|
||||||
update! (turtle_states, append (_, new_state))
|
update! (turtle_states, append (_, new_state))
|
||||||
make! (turtle_state, new_state)
|
make! (turtle_state, new_state)
|
||||||
|
render_command! ()
|
||||||
|
:ok
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_command! () -> {
|
||||||
|
let cmd = first (command)
|
||||||
|
let state = deref (turtle_state)
|
||||||
|
let #{position, heading, pendown, color, penwidth, visible} = state
|
||||||
|
match cmd with {
|
||||||
|
:forward -> :todo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forward! {
|
fn forward! {
|
||||||
|
@ -748,7 +799,7 @@ fn apply_command {
|
||||||
|
|
||||||
fn turtle/p5 {
|
fn turtle/p5 {
|
||||||
"Takes a list of turtle states and returns a list of p5 calls that will render the turtle states."
|
"Takes a list of turtle states and returns a list of p5 calls that will render the turtle states."
|
||||||
() -> :todo
|
() -> :todo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -763,6 +814,9 @@ ns prelude {
|
||||||
second
|
second
|
||||||
rest
|
rest
|
||||||
nth
|
nth
|
||||||
|
last
|
||||||
|
butlast
|
||||||
|
slice
|
||||||
count
|
count
|
||||||
append
|
append
|
||||||
fold
|
fold
|
||||||
|
@ -775,7 +829,7 @@ ns prelude {
|
||||||
show
|
show
|
||||||
prn!
|
prn!
|
||||||
type
|
type
|
||||||
report
|
report!
|
||||||
concat
|
concat
|
||||||
deref
|
deref
|
||||||
make!
|
make!
|
||||||
|
|
Loading…
Reference in New Issue
Block a user