diff options
-rw-r--r-- | autoload.c | 2 | ||||
-rw-r--r-- | stdlib/place.tl | 7 | ||||
-rw-r--r-- | txr.1 | 48 |
3 files changed, 56 insertions, 1 deletions
@@ -105,7 +105,7 @@ static val place_set_entries(val fun) lit("push"), lit("pop"), lit("swap"), lit("shift"), lit("rotate"), lit("test-set"), lit("test-clear"), lit("compare-swap"), lit("test-inc"), lit("test-dec"), - lit("pushnew"), lit("del"), lit("lset"), lit("upd"), + lit("pushnew"), lit("del"), lit("lset"), lit("upd"), lit("ensure"), lit("defplace"), lit("define-place-macro"), lit("define-modify-macro"), lit("placelet"), lit("placelet*"), lit("read-once"), lit("define-accessor"), lit("with-slots"), diff --git a/stdlib/place.tl b/stdlib/place.tl index 5d601834..fba9a8d6 100644 --- a/stdlib/place.tl +++ b/stdlib/place.tl @@ -374,6 +374,13 @@ ^(placelet ((,pl ,place)) (set ,pl (call (opip ,*opip-args) ,pl))))) +(defmacro ensure (:env env place init-expr) + (with-gensyms (existing) + (with-update-expander (getter setter) place env + ^(iflet ((,existing (,getter))) + ,existing + (,setter ,init-expr))))) + (defmacro defplace (place-destructuring-args body-sym (getter-sym setter-sym update-body) : ((ssetter-sym clobber-body)) @@ -14384,6 +14384,19 @@ value into and returns .codn t . +.meIP (ensure < place << init-expr ) +If the place is +.codn nil , +evaluates +.codn init-expr , +stores that value into +.meta place +and returns it. +Otherwise, returns the value of +.meta place +without changing its value or evaluating +.codn init-expr . + .meIP (inc < place <> [ delta ]) Increments .meta place @@ -42858,6 +42871,41 @@ expression, stores the resulting value into and returns .codn t . +.coNP Macro @ ensure +.synb +.mets (ensure < place << init-expr ) +.syne +.desc +The +.code ensure +macro examines the value of +.metn place . + +If the current value is +.codn nil , +then +.meta init-expr +is evaluated. The value is stored in +.meta place +and becomes the result of the +.code ensure +form. + +If the value of +.meta place +is other than +.codn nil , +then the form yields that value. +In this case, +.meta init-expr +isn't evaluated, and +.meta place +isn't modified. + +The +.meta place +expression is evaluated only once to determine the place. + .coNP Macros @ inc and @ dec .synb .mets (inc < place <> [ delta ]) |