Skip to content

Commit 2f42517

Browse files
committed
Add boxed evaluation
1 parent 0799c96 commit 2f42517

File tree

1 file changed

+70
-3
lines changed

1 file changed

+70
-3
lines changed

ac.rkt

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
[(ssyntax? (xcar s)) (ac (cons (expand-ssyntax (car s)) (cdr s)) env)]
120120
[(eq? (xcar s) '$) (ac-$ (cadr s) env)]
121121
[(eq? (xcar s) 'quote) (list 'quote (ac-quoted (cadr s)))]
122+
((eq? (xcar s) 'lexenv) (ac-lenv (cdr s) env))
122123
[(and (eq? (xcar s) 'quasiquote)
123124
(not (ac-macro? 'quasiquote)))
124125
(ac-qq (cadr s) env)]
@@ -323,7 +324,8 @@
323324
#f)
324325

325326
(define (ac-var-ref s env)
326-
(cond [(lex? s env) s]
327+
(cond [(ac-boxed? 'get s) (ac-boxed-get s)]
328+
[(lex? s env) s]
327329
[(ac-defined-var? s) (list (ac-global-name s))]
328330
[#t (ac-global-name s)]))
329331

@@ -550,6 +552,7 @@
550552
(list 'let `([zz ,b])
551553
(cond [(eqv? a 'nil) (err "Can't rebind nil")]
552554
[(eqv? a 't) (err "Can't rebind t")]
555+
[(ac-boxed? 'set a) `(begin ,(ac-boxed-set a b) ,(ac-boxed-get a))]
553556
[(lex? a env) `(set! ,a zz)]
554557
[(ac-defined-var? a) `(,(ac-global-name a) zz)]
555558
[#t `(set! ,(ac-global-name a) zz)])
@@ -568,6 +571,52 @@
568571
(cdr exprs)
569572
env))))
570573

574+
(define (ac-lexname env)
575+
(let ((name (ac-dbname env)))
576+
(if (eqv? name #f)
577+
'fn
578+
(apply string-append
579+
(map (lambda (x) (string-append (symbol->string x) "-"))
580+
(apply append (keep pair? env)))))))
581+
582+
(define (ac-lenv args env)
583+
(ac-lexenv (ac-lexname env) env))
584+
585+
(define (ac-lexenv name env)
586+
`(list (list '*name ',name)
587+
,@(imap (lambda (var)
588+
(let ((val (gensym)))
589+
`(list ',var
590+
(lambda ,val ,var)
591+
(lambda (,val) (set! ,var ,val)))))
592+
(filter (lambda (x) (not (or (ar-false? x) (pair? x)))) env))))
593+
594+
(define boxed* '())
595+
596+
(define (ac-boxed? op name)
597+
(let ((result
598+
(when (not (ar-false? name))
599+
(when (not (ar-false? boxed*))
600+
(let ((slot (assoc name boxed*)))
601+
(case op
602+
((get) (when (and slot (>= (length slot) 2)) (cadr slot)))
603+
((set) (when (and slot (>= (length slot) 3)) (caddr slot)))
604+
(else (err "ac-boxed?: bad op" name op))))))))
605+
(if (void? result) #f result)))
606+
607+
(define (ac-boxed-set name val)
608+
(let ((setter (ac-boxed? 'set name)))
609+
(if (procedure? setter)
610+
`(,setter ,val)
611+
(err "invalid setter" name val setter))))
612+
613+
(define (ac-boxed-get name)
614+
(let ((getter (ac-boxed? 'get name)))
615+
(if (procedure? getter)
616+
`(,getter 'nil)
617+
getter)))
618+
619+
571620
; generate special fast code for ordinary two-operand
572621
; calls to the following functions. this is to avoid
573622
; calling e.g. ar-is with its &rest and apply.
@@ -1265,8 +1314,26 @@
12651314
(eval (parameterize ([compile-allow-set!-undefined #t])
12661315
(compile racket-expr))))
12671316

1268-
(define (arc-eval expr)
1269-
(arc-exec (ac expr '())))
1317+
(define (arc-eval expr . args)
1318+
(if (null? args)
1319+
(arc-exec (ac expr '()))
1320+
(apply arc-eval-boxed expr args)))
1321+
1322+
(define-syntax w/restore
1323+
(syntax-rules ()
1324+
((_ var val body ...)
1325+
(let ((w/restore-prev var)
1326+
(w/restore-val val))
1327+
(dynamic-wind (lambda () (set! var w/restore-val))
1328+
(lambda () body ...)
1329+
(lambda () (set! var w/restore-prev)))))))
1330+
1331+
(define (arc-eval-boxed expr lexenv)
1332+
(w/restore boxed* (if (or (ar-false? boxed*)
1333+
(ar-false? lexenv))
1334+
lexenv
1335+
(append lexenv boxed*))
1336+
(arc-eval expr)))
12701337

12711338
(define (tle)
12721339
(display "Arc> ")

0 commit comments

Comments
 (0)