--- a/ac.scm 2009-12-05 15:37:50.000000000 -0500 +++ b/ac.scm 2009-12-05 15:51:53.000000000 -0500 @@ -227,10 +227,13 @@ acc keepsep?)))) +(defarc (ac-defined-var? s) + #f) + (define (ac-var-ref s env) - (if (lex? s env) - s - (ac-global-name s))) + (cond ((lex? s env) s) + ((ac-defined-var? s) (list (ac-global-name s))) + (#t (ac-global-name s)))) ; quasiquote @@ -414,6 +417,7 @@ (cond ((eqv? a 'nil) (err "Can't rebind nil")) ((eqv? a 't) (err "Can't rebind t")) ((lex? a env) `(set! ,a zz)) + ((ac-defined-var? a) `(,(ac-global-name a) zz)) (#t `(namespace-set-variable-value! ',(ac-global-name a) zz))) 'zz))
(= defined-variables* (table)) (def ac-defined-var? (name) (if defined-variables*.name scheme-t scheme-f)) (mac defvar (name impl) `(do (ac-set-global ',name ,impl) (set (defined-variables* ',name)) nil)) (mac defvar-impl (name) (let gname (ac-global-name name) `(scheme ,gname))) (mac undefvar (name) `(do (wipe (defined-variables* ',name)) (ac-set-global ',name nil)))
This hack provides for a way to provide your own implementation for a global variable, to say what happens when the variable is used or set:
(defvar v f)
causes the function f
to provide the implementation for the variable v
: when v
is used in an expression, f
is called with no arguments to provide the value that v
evaluates to; when v
is set, f
is called with one argument, the value v
is being set to.
arc> (defvar a (let x 5 (fn args (if args (do (prn "Being set to " (car args) ".") (= x (car args))) (do (prn "Returning " x ".") x))))) nil
arc> (++ a) Returning 5. Being set to 6. 6
Using the hackinator:
$ hack \ ycombinator.com/arc/arc3.1.tar \ awwx.ws/defarc0.patch \ awwx.ws/defarc-ac0.patch \ awwx.ws/extend0.arc \ awwx.ws/scheme0.arc \ awwx.ws/defvar1.patch \ awwx.ws/defvar2.arc
Same as Arc.