From 846a9839d66544c55e2cf95b46d6cc2861b81595 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Thu, 12 Jun 2025 17:50:22 -0400 Subject: [PATCH] add llist fns; fix missing colors bug; filter works on sets; other improvements --- prelude.ld | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/prelude.ld b/prelude.ld index 06b09f3..77aec1f 100644 --- a/prelude.ld +++ b/prelude.ld @@ -247,6 +247,7 @@ fn foldr { & TODO: optimize these with base :conj! fn map { "Maps a function over a list: returns a new list with elements that are the result of applying the function to each element in the original list. E.g., `map ([1, 2, 3], inc) &=> [2, 3, 4]`." + (f as :fn) -> map (f, _) (f as :fn, xs) -> { fn mapper (prev, curr) -> append (prev, f (curr)) fold (mapper, xs, []) @@ -258,18 +259,21 @@ fn map { } fn filter { - "Takes a list and a predicate function, and returns a new list with only the items that produce truthy values when the function is called on them. E.g., `filter ([1, 2, 3, 4], odd?) &=> [1, 3]`." - (p? as :fn, xs) -> { + "Takes a list and a predicate function, and returns a new list with only the items that produce truthy values when the function is called on them. E.g., `filter ([1, 2, 3, 4], odd?) &=> [1, 3]`. Also works on sets." + (p? as :fn) -> filter(p?, _) + (p? as :fn, xs as list) -> { fn filterer (filtered, x) -> if p? (x) then append (filtered, x) else filtered fold (filterer, xs, []) } + (p? as :fn, xs as :set) -> do xs > list > filter (p?, _) > set } fn keep { "Takes a list and returns a new list with any `nil` values omitted." - (xs) -> filter (some?, xs) + (xs as :list) -> filter (some?, xs) + (xs as :set) -> filter (some?, xs) } fn append { @@ -313,6 +317,7 @@ fn contains? { "Returns true if a set or list contains a value." (value, s as :set) -> bool (base :get (s, value)) (value, l as :list) -> contains? (value, set (list)) + (key, d as :dict) -> do d > key > some? } fn omit { @@ -1114,6 +1119,7 @@ let colors = #{ :black (0, 0, 0, 255) :silver (192, 192, 192, 255) :gray (128, 128, 128, 255) + :grey (128, 128, 128, 255) :white (255, 255, 255, 255) :maroon (128, 0, 0, 255) :red (255, 0, 0, 255) @@ -1129,6 +1135,8 @@ let colors = #{ :aqua (0, 255, 255, 255) } +let colours = colors + & the initial turtle state let turtle_init = #{ :position (0, 0) & let's call this the origin for now @@ -1196,12 +1204,13 @@ let pd! = pendown! fn pencolor! { "Changes the turtle's pen color. Takes a single grayscale value, an rgb tuple, or an rgba tuple. Alias: pc!" - (color as :keyword) -> add_command! ((:pencolor, color)) + (color as :keyword) -> if contains? (colors, color) then add_command! ((:pencolor, color)) else panic! "Ludus doesn't know about the color {color}" (gray as :number) -> add_command! ((:pencolor, (gray, gray, gray, 255))) ((r as :number, g as :number, b as :number)) -> add_command! ((:pencolor, (r, g, b, 255))) ((r as :number, g as :number, b as :number, a as :number)) -> add_command! ((:pencolor, (r, g, b, a))) } +let pencolour! = pencolor! let pc! = pencolor! fn penwidth! { @@ -1213,7 +1222,7 @@ let pw! = penwidth! fn background! { "Sets the background color behind the turtle and path. Alias: bg!" - (color as :keyword) -> add_command! ((:background, color)) + (color as :keyword) -> if contains? (colors, color) then add_command! ((:background, color)) else panic! "Ludus doesn't know about the color {color}" (gray as :number) -> add_command! ((:background, (gray, gray, gray, 255))) ((r as :number, g as :number, b as :number)) -> add_command! ((:background, (r, g, b, 255))) ((r as :number, g as :number, b as :number, a as :number)) -> add_command! ((:background, (r, g, b, a))) @@ -1322,6 +1331,26 @@ fn penwidth { () -> do turtle_state > unbox > :penwidth } +fn cons { + "Old-timey lisp `cons`. `Cons`tructs a tuple out of two arguments." + (x, y) -> (x, y) +} + +fn car { + "Old-timey lisp `car`. Stands for 'contents of the address register.' Returns the first element in a `cons`ed pair (or any two-tuple)." + ((x, _)) -> x +} + +fn cdr { + "Old-timey list `cdr`. Stands for 'contents of the decrement register.' Returns the second element in a `cons`ed pair, usually representing the rest of the list." + ((_, x)) -> x +} + +fn llist { + "Makes an old-timey linked list of its arguments, of LISt Processor fame." + (...xs) -> foldr (cons, xs, nil) +} + box state = nil pkg Prelude { @@ -1345,12 +1374,15 @@ pkg Prelude { bool? & bool box? & boxes butlast & lists strings tuples + car & llist + cdr & llist ceil & math chars & strings clear! & turtles coll? & dicts lists sets tuples colors & turtles concat & string list set + cons & llist contains? & list set cos & math count & string list set tuple dict