| 
119 | 119 |         [(ssyntax? (xcar s)) (ac (cons (expand-ssyntax (car s)) (cdr s)) env)]  | 
120 | 120 |         [(eq? (xcar s) '$) (ac-$ (cadr s) env)]  | 
121 | 121 |         [(eq? (xcar s) 'quote) (list 'quote (ac-quoted (cadr s)))]  | 
 | 122 | +        ((eq? (xcar s) 'lexenv) (ac-lenv (cdr s) env))  | 
122 | 123 |         [(and (eq? (xcar s) 'quasiquote)  | 
123 | 124 |               (not (ac-macro? 'quasiquote)))  | 
124 | 125 |          (ac-qq (cadr s) env)]  | 
 | 
323 | 324 |   #f)  | 
324 | 325 | 
 
  | 
325 | 326 | (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]  | 
327 | 329 |         [(ac-defined-var? s) (list (ac-global-name s))]  | 
328 | 330 |         [#t                  (ac-global-name s)]))  | 
329 | 331 | 
 
  | 
 | 
550 | 552 |         (list 'let `([zz ,b])  | 
551 | 553 |                (cond [(eqv? a 'nil) (err "Can't rebind nil")]  | 
552 | 554 |                      [(eqv? a 't) (err "Can't rebind t")]  | 
 | 555 | +                     [(ac-boxed? 'set a)  `(begin ,(ac-boxed-set a b) ,(ac-boxed-get a))]  | 
553 | 556 |                      [(lex? a env) `(set! ,a zz)]  | 
554 | 557 |                      [(ac-defined-var? a) `(,(ac-global-name a) zz)]  | 
555 | 558 |                      [#t `(set! ,(ac-global-name a) zz)])  | 
 | 
568 | 571 |                      (cdr exprs)  | 
569 | 572 |                      env))))  | 
570 | 573 | 
 
  | 
 | 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 | + | 
571 | 620 | ; generate special fast code for ordinary two-operand  | 
572 | 621 | ; calls to the following functions. this is to avoid  | 
573 | 622 | ; calling e.g. ar-is with its &rest and apply.  | 
 | 
1265 | 1314 |   (eval (parameterize ([compile-allow-set!-undefined #t])  | 
1266 | 1315 |           (compile racket-expr))))  | 
1267 | 1316 | 
 
  | 
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)))  | 
1270 | 1337 | 
 
  | 
1271 | 1338 | (define (tle)  | 
1272 | 1339 |   (display "Arc> ")  | 
 | 
0 commit comments