defvar0.patch
diff --git a/ac.scm b/ac.scm index 3f1663b..65b95d7 100644 --- a/ac.scm +++ b/ac.scm @@ -188,10 +188,15 @@ (define (ac-global-name s) (string->symbol (string-append "_" (symbol->string s)))) +(define _defined-var* (make-hash-table 'equal)) + +(define (defined-var? s) + (not (ar-false? (hash-table-get _defined-var* s #f)))) + (define (ac-var-ref s env) - (if (lex? s env) - s - (ac-global-name s))) + (cond ((lex? s env) s) + ((defined-var? s) (list (ac-global-name s))) + (#t (ac-global-name s)))) ; quasiquote @@ -366,6 +371,7 @@ (cond ((eqv? a 'nil) (err "Can't rebind nil")) ((eqv? a 't) (err "Can't rebind t")) ((lex? a env) `(set! ,a zz)) + ((defined-var? a) `(,(ac-global-name a) zz)) (#t `(namespace-set-variable-value! ',(ac-global-name a) zz))) 'zz))
defvar0.arc
; Have to use ac-set-global here, as using = or assign would invoke ; our own previously defined settor when defvar was called on the same ; variable twice. (mac defvar (name impl) `(do (ac-set-global ',name ,impl) (set (defined-var* ',name)) nil)) (mac defvar-impl (name) (let gname (ac-global-name name) `(ac-scheme ,gname))) (mac undefvar (name) `(do (wipe (defined-var* ',name)) (wipe ,name))) ; idea: extend def and mac to call undefvar so that a defvar can be ; redefined as a function or a macro? ; ; Is there a reason why we need to store the defvar's implementation ; procedure in the global variable namespace? A reason not to?
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:
arc> (def foo ()
(prn "This is foo, I'm going to return 5.")
5)
#<procedure: foo>
arc> (defvar a foo)
nil
arc> (+ a 3)
This is foo, I'm going to return 5.
8
foo is now providing the implementation for the global variable a; when the variable is used in an expression, foo is called and the value of the variable is what is returned by foo.
If the variable is set, the implementing function is called with a single argument, the value the variable is being set to:
arc> (def foo args
(if args
(prn "Being set to " (car args) ".")
(do (prn "Returning 5.")
5)))
#<procedure: foo>
arc> (defvar a foo)
nil
arc> (++ a)
Returning 5.
Being set to 6.
6
wget http://ycombinator.com/arc/arc3.tar tar xf arc3.tar cd arc3 wget -O - http://hacks.catdancer.ws/ac0.patch | patch wget -O - http://hacks.catdancer.ws/defvar0.patch | patch wget http://hacks.catdancer.ws/ac0.arc wget http://hacks.catdancer.ws/defvar0.arc mzscheme -m -f as.scm (load "ac0.arc") (load "defvar0.arc")