disallow shadowing, remove all shadowing from Prelude.

This commit is contained in:
Scott Richmond 2024-07-19 16:48:11 -04:00
parent 2ec95c8f33
commit 7467bc8867
3 changed files with 57 additions and 52 deletions

View File

@ -50,8 +50,8 @@ fn ordered? {
fn assoc? { fn assoc? {
"Returns true if a value is an associative collection: a dict or a pkg." "Returns true if a value is an associative collection: a dict or a pkg."
(assoc as :dict) -> true (d as :dict) -> true
(assoc as :pkg) -> true (p as :pkg) -> true
(_) -> false (_) -> false
} }
@ -293,8 +293,8 @@ fn set? {
fn contains? { fn contains? {
"Returns true if a set or list contains a value." "Returns true if a set or list contains a value."
(value, set as :set) -> bool (base :get (set, value)) (value, s as :set) -> bool (base :get (s, value))
(value, list as :list) -> contains? (value, set (list)) (value, l as :list) -> contains? (value, set (list))
} }
fn omit { fn omit {
@ -345,8 +345,8 @@ fn string {
(x as :string) -> x (x as :string) -> x
(x) -> show (x) (x) -> show (x)
(x, ...xs) -> loop (x, xs) with { (x, ...xs) -> loop (x, xs) with {
(out, [x]) -> concat (out, show (x)) (out, [y]) -> concat (out, show (y))
(out, [x, ...xs]) -> recur (concat (out, show (x)), xs) (out, [y, ...ys]) -> recur (concat (out, show (y)), ys)
} }
} }
@ -423,9 +423,9 @@ fn words {
(str as :string) -> { (str as :string) -> {
let no_punct = strip (str) let no_punct = strip (str)
let strs = split (no_punct, " ") let strs = split (no_punct, " ")
fn worder (list, str) -> if empty? (str) fn worder (l, s) -> if empty? (s)
then list then l
else append (list, str) else append (l, s)
fold (worder, strs, []) fold (worder, strs, [])
} }
} }
@ -744,31 +744,31 @@ fn or {
fn assoc { fn assoc {
"Takes a dict, key, and value, and returns a new dict with the key set to value." "Takes a dict, key, and value, and returns a new dict with the key set to value."
() -> #{} () -> #{}
(dict as :dict) -> dict (d as :dict) -> d
(dict as :dict, key as :keyword, value) -> base :assoc (dict, key, value) (d as :dict, k as :keyword, val) -> base :assoc (d, k, val)
(dict as :dict, (key as :keyword, value)) -> base :assoc (dict, key, value) (d as :dict, (k as :keyword, val)) -> base :assoc (d, k, val)
} }
fn dissoc { fn dissoc {
"Takes a dict and a key, and returns a new dict with the key and associated value omitted." "Takes a dict and a key, and returns a new dict with the key and associated value omitted."
(dict as :dict) -> dict (d as :dict) -> d
(dict as :dict, key as :keyword) -> base :dissoc (dict, key) (d as :dict, k as :keyword) -> base :dissoc (d, k)
} }
fn update { fn update {
"Takes a dict, key, and function, and returns a new dict with the key set to the result of applying the function to original value held at the key." "Takes a dict, key, and function, and returns a new dict with the key set to the result of applying the function to original value held at the key."
(dict as :dict) -> dict (d as :dict) -> d
(dict as :dict, key as :keyword, updater as :fn) -> base :assoc (dict, key, updater (get (key, dict))) (d as :dict, k as :keyword, updater as :fn) -> base :assoc (d, k, updater (get (k, d)))
} }
fn keys { fn keys {
"Takes a dict and returns a list of keys in that dict." "Takes a dict and returns a list of keys in that dict."
(dict as :dict) -> do dict > list > map (first, _) (d as :dict) -> do d > list > map (first, _)
} }
fn values { fn values {
"Takes a dict and returns a list of values in that dict." "Takes a dict and returns a list of values in that dict."
(dict) -> do dict > list > map (second, _) (d as :dict) -> do d > list > map (second, _)
} }
fn diff { fn diff {
@ -801,28 +801,28 @@ fn diff {
& TODO: consider merging `get` and `at` & TODO: consider merging `get` and `at`
fn get { fn get {
"Takes a key, dict, and optional default value; returns the value at key. If the value is not found, returns nil or the default value." "Takes a key, dict, and optional default value; returns the value at key. If the value is not found, returns nil or the default value."
(key as :keyword) -> get (key, _) (k as :keyword) -> get (k, _)
(key as :keyword, dict as :dict) -> get (key, dict, nil) (k as :keyword, d as :dict) -> get (k, d, nil)
(key as :keyword, dict as :dict, default) -> base :get (key, dict, default) (k as :keyword, d as :dict, default) -> base :get (k, d, default)
} }
& TODO: add sets to this? & TODO: add sets to this?
fn has? { fn has? {
"Takes a key and a dict, and returns true if there is a non-`nil` value stored at the key." "Takes a key and a dict, and returns true if there is a non-`nil` value stored at the key."
(key as :keyword) -> has? (key, _) (k as :keyword) -> has? (k, _)
(key as :keyword, dict as :dict) -> do dict > key > nil? (k as :keyword, d as :dict) -> do d> k > nil?
} }
fn dict { fn dict {
"Takes a list or tuple of (key, value) tuples and returns it as a dict. Returns dicts unharmed." "Takes a list or tuple of (key, value) tuples and returns it as a dict. Returns dicts unharmed."
(dict as :dict) -> dict (d as :dict) -> d
(list as :list) -> fold (assoc, list) (l as :list) -> fold (assoc, l)
(tup as :tuple) -> do tup > list > dict (t as :tuple) -> do t > list > dict
} }
fn dict? { fn dict? {
"Returns true if a value is a dict." "Returns true if a value is a dict."
(dict as :dict) -> true (d as :dict) -> true
(_) -> false (_) -> false
} }
@ -869,10 +869,10 @@ fn tan {
fn rotate { fn rotate {
"Rotates a vector by an angle. Default angle measure is turns. An optional keyword argument specifies the units of the angle passed in." "Rotates a vector by an angle. Default angle measure is turns. An optional keyword argument specifies the units of the angle passed in."
((x, y), angle) -> rotate ((x, y), angle, :turns) ((x, y), a) -> rotate ((x, y), a, :turns)
((x, y), angle, units as :keyword) -> ( ((x, y), a, units as :keyword) -> (
sub (mult (x, cos (angle, units)), mult (y, sin (angle, units))) sub (mult (x, cos (a, units)), mult (y, sin (a, units)))
add (mult (x, sin (angle, units)), mult (y, cos (angle, units))) add (mult (x, sin (a, units)), mult (y, cos (a, units)))
) )
} }
@ -917,21 +917,21 @@ fn atan/2 {
} }
fn mod { fn mod {
"Returns the modulus of num and div. Truncates towards negative infinity. Panics if div is 0." "Returns the modulus of x and y. Truncates towards negative infinity. Panics if y is 0."
(num as :number, 0) -> panic! "Division by zero." (x as :number, 0) -> panic! "Division by zero."
(num as :number, div as :number) -> base :mod (num, div) (x as :number, y as :number) -> base :mod (x, y)
} }
fn mod/0 { fn mod/0 {
"Returns the modulus of num and div. Truncates towards negative infinity. Returns 0 if div is 0." "Returns the modulus of x and y. Truncates towards negative infinity. Returns 0 if y is 0."
(num as :number, 0) -> 0 (x as :number, 0) -> 0
(num as :number, div as :number) -> base :mod (num, div) (x as :number, y as :number) -> base :mod (x, y)
} }
fn mod/safe { fn mod/safe {
"Returns the modulus of num and div in a result tuple, or an error if div is 0. Truncates towards negative infinity." "Returns the modulus of x and y in a result tuple, or an error if y is 0. Truncates towards negative infinity."
(num as :number, 0) -> (:err, "Division by zero.") (x as :number, 0) -> (:err, "Division by zero.")
(num as :number, div as :number) -> (:ok, base :mod (num, div)) (x as :number, y as :number) -> (:ok, base :mod (x, y))
} }
fn square { fn square {
@ -1143,10 +1143,10 @@ fn render_turtle! () -> {
:position (x, y) :position (x, y)
pendown? pendown?
...} = state ...} = state
let first = mult ((0, 1), turtle_radius) let origin = mult ((0, 1), turtle_radius)
let (x1, y1) = first let (x1, y1) = origin
let (x2, y2) = rotate (first, turtle_angle) let (x2, y2) = rotate (origin, turtle_angle)
let (x3, y3) = rotate (first, neg (turtle_angle)) let (x3, y3) = rotate (origin, neg (turtle_angle))
add_call! ((:push)) add_call! ((:push))
add_call! ((:translate, x, y)) add_call! ((:translate, x, y))
add_call! ((:rotate, turn/rad (heading))) add_call! ((:rotate, turn/rad (heading)))
@ -1295,8 +1295,8 @@ fn heading/vector {
"Takes a turtle heading, and returns a unit vector of that heading." "Takes a turtle heading, and returns a unit vector of that heading."
(heading) -> { (heading) -> {
& 0 is 90º/0.25T, 0.25 is 180º/0.5T, 0.5 is 270º/0.75T, 0.75 is 0º/0T & 0 is 90º/0.25T, 0.25 is 180º/0.5T, 0.5 is 270º/0.75T, 0.75 is 0º/0T
let angle = add (heading, 0.25) let a = add (heading, 0.25)
(cos (angle), sin (angle)) (cos (a), sin (a))
} }
} }

View File

@ -51,11 +51,14 @@
(-> out j/encode string) (-> out j/encode string)
) )
(comment # (comment
# (do (do
# (def start (os/clock)) # (def start (os/clock))
(def source ` (def source `
doc! (add) let foo = :bar
{
let foo = :baz
}
`) `)
(def out (-> source (def out (-> source
ludus ludus

View File

@ -157,10 +157,12 @@ Deferred until a later iteration of Ludus:
(def ast (validator :ast)) (def ast (validator :ast))
(def name (ast :data)) (def name (ast :data))
(def ctx (validator :ctx)) (def ctx (validator :ctx))
(when (has-key? ctx name) ### XXX TODO: this resolution should ONLY be for userspace, NOT prelude
(def {:line line :input input} (get-in ctx [name :token])) (def resolved (resolve-name ctx name))
(when resolved
(def {:line line :input input} resolved)
(array/push (validator :errors) (array/push (validator :errors)
{:node ast :msg (string "name is already bound on line " {:node ast :msg (string "name " name " is already bound on line "
line " of " input)})) line " of " input)}))
(set (ctx name) ast) (set (ctx name) ast)
# (pp ctx) # (pp ctx)