|
9 | 9 | (require (lib "foreign.ss")) |
10 | 10 | (unsafe!) |
11 | 11 |
|
| 12 | +(define main-namespace (current-namespace)) |
| 13 | + |
12 | 14 | (define (ac-global-name s) |
13 | 15 | (string->symbol (string-append "_" (symbol->string s)))) |
14 | 16 |
|
|
22 | 24 | (defarc arc-name scheme-name))) |
23 | 25 | ((defarc arc-name scheme-name) |
24 | 26 | (define (scheme-name . args) |
25 | | - (apply (namespace-variable-value (ac-global-name 'arc-name)) args))) |
| 27 | + |
| 28 | + ; The following 'parameterize has been added. See the note at |
| 29 | + ; 'arc-exec, below. |
| 30 | + ; |
| 31 | + (apply (parameterize ((current-namespace main-namespace)) |
| 32 | + (namespace-variable-value (ac-global-name 'arc-name))) |
| 33 | + args))) |
26 | 34 | ((defarc name) |
27 | 35 | (defarc name name)))) |
28 | 36 |
|
|
424 | 432 | ((eqv? a 't) (err "Can't rebind t")) |
425 | 433 | ((lex? a env) `(set! ,a zz)) |
426 | 434 | ((ac-defined-var? a) `(,(ac-global-name a) zz)) |
427 | | - (#t `(namespace-set-variable-value! ',(ac-global-name a) |
428 | | - zz))) |
| 435 | + |
| 436 | + ; The following has been changed from |
| 437 | + ; 'namespace-set-variable-value! to 'set!. See |
| 438 | + ; the note at 'arc-exec, below. |
| 439 | + ; |
| 440 | + (#t `(set! ,(ac-global-name a) zz))) |
429 | 441 | 'zz)) |
430 | 442 | (err "First arg to set must be a symbol" a))) |
431 | 443 |
|
|
475 | 487 | ((and (pair? fn) (eqv? (car fn) 'fn)) |
476 | 488 | `(,(ac fn env) ,@(ac-args (cadr fn) args env))) |
477 | 489 | ((and (ar-bflag 'direct-calls) (symbol? fn) (not (lex? fn env)) (bound? fn) |
478 | | - (procedure? (namespace-variable-value (ac-global-name fn)))) |
| 490 | + |
| 491 | + ; The following has been changed from using |
| 492 | + ; 'namespace-variable-value to using 'arc-eval. See |
| 493 | + ; the note at 'arc-exec, below. |
| 494 | + ; |
| 495 | + (procedure? (arc-eval fn))) |
479 | 496 | (ac-global-call fn args env)) |
480 | 497 | (#t |
481 | 498 | `((ar-coerce ,(ac fn env) 'fn) |
|
490 | 507 |
|
491 | 508 | (define (ac-macro? fn) |
492 | 509 | (if (symbol? fn) |
493 | | - (let ((v (namespace-variable-value (ac-global-name fn) |
494 | | - #t |
495 | | - (lambda () #f)))) |
| 510 | + |
| 511 | + ; The following has been changed from using |
| 512 | + ; 'namespace-variable-value to using 'bound? and 'arc-eval. See |
| 513 | + ; the note at 'arc-exec, below. |
| 514 | + ; |
| 515 | + (let ((v (and (bound? fn) (arc-eval fn)))) |
496 | 516 | (if (and v |
497 | 517 | (ar-tagged? v) |
498 | 518 | (eq? (ar-type v) 'mac)) |
|
1128 | 1148 | ; top level read-eval-print |
1129 | 1149 | ; tle kept as a way to get a break loop when a scheme err |
1130 | 1150 |
|
| 1151 | +; To make namespace and module handling more seamless (see |
| 1152 | +; lib/ns.arc), we use Racket's 'set! even for undefined variables, |
| 1153 | +; rather than using 'namespace-set-variable-value! for all Arc |
| 1154 | +; globals. This makes it possible to parameterize the value of |
| 1155 | +; 'current-namespace without getting odd behavior, and it makes it |
| 1156 | +; possible to assign to imported module variables and use |
| 1157 | +; assignment-aware syntax transformers (particularly those made with |
| 1158 | +; Racket's 'make-set!-transformer and 'make-rename-transformer). |
| 1159 | +; |
| 1160 | +; However, by default 'set! is disallowed when the variable is |
| 1161 | +; undefined, and we have to use the 'compile-allow-set!-undefined |
| 1162 | +; parameter to go against that default. Rather than sprinkling |
| 1163 | +; (parameterize ...) forms all over the code and trying to keep them |
| 1164 | +; in sync, we put them all in this function, and we use this function |
| 1165 | +; instead of 'eval when executing the output of 'ac. |
| 1166 | +; |
| 1167 | +; In the same spirit, several other uses of 'namespace-variable-value |
| 1168 | +; and 'namespace-set-variable-value! have been changed to more direct |
| 1169 | +; versions ((set! ...) forms and direct variable references) or less |
| 1170 | +; direct versions (uses of full 'arc-eval) depending on how their |
| 1171 | +; behavior should change when a module import or syntax obstructs the |
| 1172 | +; original meaning of the variable. Some have instead been kept |
| 1173 | +; around, but surrounded by (parameterize ...) forms so they're tied |
| 1174 | +; the main namespace. Another utility changed in this spirit is |
| 1175 | +; 'bound?, which should now be able to see variables which are bound |
| 1176 | +; as Racket syntax. |
| 1177 | +; |
| 1178 | +(define (arc-exec racket-expr) |
| 1179 | + (eval (parameterize ((compile-allow-set!-undefined #t)) |
| 1180 | + (compile racket-expr)))) |
| 1181 | + |
1131 | 1182 | (define (arc-eval expr) |
1132 | | - (eval (ac expr '()))) |
| 1183 | + (arc-exec (ac expr '()))) |
1133 | 1184 |
|
1134 | 1185 | (define (tle) |
1135 | 1186 | (display "Arc> ") |
|
1167 | 1218 | (when interactive? |
1168 | 1219 | (arc-write (ac-denil val)) |
1169 | 1220 | (newline)) |
1170 | | - (namespace-set-variable-value! '_that val) |
1171 | | - (namespace-set-variable-value! '_thatexpr expr) |
| 1221 | + |
| 1222 | + ; The following 'parameterize has been added. See the |
| 1223 | + ; note at 'arc-exec, above. |
| 1224 | + ; |
| 1225 | + (parameterize ((current-namespace main-namespace)) |
| 1226 | + (namespace-set-variable-value! '_that val) |
| 1227 | + (namespace-set-variable-value! '_thatexpr expr)) |
1172 | 1228 | (tl2 interactive?))))))) |
1173 | 1229 |
|
1174 | 1230 | (define (aload1 p) |
|
1204 | 1260 | (if (eof-object? x) |
1205 | 1261 | #t |
1206 | 1262 | (let ((scm (ac x '()))) |
1207 | | - (eval scm) |
| 1263 | + (arc-exec scm) |
1208 | 1264 | (pretty-print scm op) |
1209 | 1265 | (newline op) |
1210 | 1266 | (newline op) |
|
1227 | 1283 | (xdef macex1 (lambda (e) (ac-macex (ac-denil e) 'once))) |
1228 | 1284 |
|
1229 | 1285 | (xdef eval (lambda (e) |
1230 | | - (eval (ac (ac-denil e) '())))) |
| 1286 | + (arc-eval (ac-denil e)))) |
1231 | 1287 |
|
1232 | 1288 | ; If an err occurs in an on-err expr, no val is returned and code |
1233 | 1289 | ; after it doesn't get executed. Not quite what I had in mind. |
|
1310 | 1366 | (define (nth-set! lst n val) |
1311 | 1367 | (x-set-car! (list-tail lst n) val)) |
1312 | 1368 |
|
1313 | | -; rewrite to pass a (true) gensym instead of #f in case var bound to #f |
1314 | | - |
1315 | 1369 | (define (bound? arcname) |
1316 | | - (namespace-variable-value (ac-global-name arcname) |
1317 | | - #t |
1318 | | - (lambda () #f))) |
| 1370 | + (with-handlers ((exn:fail:syntax? (lambda (e) #t)) |
| 1371 | + (exn:fail:contract:variable? (lambda (e) #f))) |
| 1372 | + (namespace-variable-value (ac-global-name arcname)) |
| 1373 | + #t)) |
1319 | 1374 |
|
1320 | 1375 | (xdef bound (lambda (x) (tnil (bound? x)))) |
1321 | 1376 |
|
|
0 commit comments