environments.test 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046
  1. ;;;; environments.test -*- scheme -*-
  2. ;;;; Copyright (C) 2000, 2001, 2006 Free Software Foundation, Inc.
  3. ;;;;
  4. ;;;; This library is free software; you can redistribute it and/or
  5. ;;;; modify it under the terms of the GNU Lesser General Public
  6. ;;;; License as published by the Free Software Foundation; either
  7. ;;;; version 2.1 of the License, or (at your option) any later version.
  8. ;;;;
  9. ;;;; This library is distributed in the hope that it will be useful,
  10. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;;; Lesser General Public License for more details.
  13. ;;;;
  14. ;;;; You should have received a copy of the GNU Lesser General Public
  15. ;;;; License along with this library; if not, write to the Free Software
  16. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. (use-modules (ice-9 documentation))
  18. ;;;
  19. ;;; miscellaneous
  20. ;;;
  21. (define exception:unbound-symbol
  22. (cons 'misc-error "^Symbol .* not bound in environment"))
  23. (define (documented? object)
  24. (not (not (object-documentation object))))
  25. (define (folder sym val res)
  26. (cons (cons sym val) res))
  27. (define (make-observer-func)
  28. (let* ((counter 0))
  29. (lambda args
  30. (if (null? args)
  31. counter
  32. (set! counter (+ counter 1))))))
  33. (define (make-erroneous-observer-func)
  34. (let* ((func (make-observer-func)))
  35. (lambda args
  36. (if (null? args)
  37. (func)
  38. (begin
  39. (func args)
  40. (error))))))
  41. ;;;
  42. ;;; leaf-environments
  43. ;;;
  44. (with-test-prefix "leaf-environments"
  45. (with-test-prefix "leaf-environment?"
  46. (pass-if "documented?"
  47. (documented? leaf-environment?))
  48. (pass-if "non-environment-object"
  49. (not (leaf-environment? #f))))
  50. (with-test-prefix "make-leaf-environment"
  51. (pass-if "documented?"
  52. (documented? make-leaf-environment))
  53. (pass-if "produces an environment"
  54. (environment? (make-leaf-environment)))
  55. (pass-if "produces a leaf-environment"
  56. (leaf-environment? (make-leaf-environment)))
  57. (pass-if "produces always a new environment"
  58. (not (eq? (make-leaf-environment) (make-leaf-environment)))))
  59. (with-test-prefix "bound, define, ref, set!, cell"
  60. (pass-if "symbols are unbound by default"
  61. (let* ((env (make-leaf-environment)))
  62. (and (not (environment-bound? env 'a))
  63. (not (environment-bound? env 'b))
  64. (not (environment-bound? env 'c)))))
  65. (pass-if "symbol is bound after define"
  66. (let* ((env (make-leaf-environment)))
  67. (environment-bound? env 'a)
  68. (environment-define env 'a #t)
  69. (environment-bound? env 'a)))
  70. (pass-if "ref a defined symbol"
  71. (let* ((env (make-leaf-environment)))
  72. (environment-bound? env 'a)
  73. (environment-bound? env 'b)
  74. (environment-define env 'a #t)
  75. (environment-define env 'b #f)
  76. (and (environment-ref env 'a)
  77. (not (environment-ref env 'b)))))
  78. (pass-if "set! a defined symbol"
  79. (let* ((env (make-leaf-environment)))
  80. (environment-define env 'a #t)
  81. (environment-define env 'b #f)
  82. (environment-ref env 'a)
  83. (environment-ref env 'b)
  84. (environment-set! env 'a #f)
  85. (environment-set! env 'b #t)
  86. (and (not (environment-ref env 'a))
  87. (environment-ref env 'b))))
  88. (pass-if "get a read-only cell"
  89. (let* ((env (make-leaf-environment)))
  90. (environment-define env 'a #t)
  91. (let* ((cell (environment-cell env 'a #f)))
  92. (and (cdr cell)
  93. (begin
  94. (environment-set! env 'a #f)
  95. (not (cdr cell)))))))
  96. (pass-if "a read-only cell gets rebound after define"
  97. (let* ((env (make-leaf-environment)))
  98. (environment-define env 'a #t)
  99. (let* ((cell (environment-cell env 'a #f)))
  100. (environment-define env 'a #f)
  101. (not (eq? (environment-cell env 'a #f) cell)))))
  102. (pass-if "get a writable cell"
  103. (let* ((env (make-leaf-environment)))
  104. (environment-define env 'a #t)
  105. (let* ((readable (environment-cell env 'a #f))
  106. (writable (environment-cell env 'a #t)))
  107. (and (eq? readable writable)
  108. (begin
  109. (environment-set! env 'a #f)
  110. (not (cdr writable)))
  111. (begin
  112. (set-cdr! writable #t)
  113. (environment-ref env 'a))
  114. (begin
  115. (set-cdr! (environment-cell env 'a #t) #f)
  116. (not (cdr writable)))))))
  117. (pass-if "a writable cell gets rebound after define"
  118. (let* ((env (make-leaf-environment)))
  119. (environment-define env 'a #t)
  120. (let* ((cell (environment-cell env 'a #t)))
  121. (environment-define env 'a #f)
  122. (not (eq? (environment-cell env 'a #t) cell)))))
  123. (pass-if-exception "reference an unbound symbol"
  124. exception:unbound-symbol
  125. (environment-ref (make-leaf-environment) 'a))
  126. (pass-if-exception "set! an unbound symbol"
  127. exception:unbound-symbol
  128. (environment-set! (make-leaf-environment) 'a #f))
  129. (pass-if-exception "get a readable cell for an unbound symbol"
  130. exception:unbound-symbol
  131. (environment-cell (make-leaf-environment) 'a #f))
  132. (pass-if-exception "get a writable cell for an unbound symbol"
  133. exception:unbound-symbol
  134. (environment-cell (make-leaf-environment) 'a #t)))
  135. (with-test-prefix "undefine"
  136. (pass-if "undefine a defined symbol"
  137. (let* ((env (make-leaf-environment)))
  138. (environment-define env 'a 1)
  139. (environment-ref env 'a)
  140. (environment-undefine env 'a)
  141. (not (environment-bound? env 'a))))
  142. (pass-if "undefine an already undefined symbol"
  143. (environment-undefine (make-leaf-environment) 'a)
  144. #t))
  145. (with-test-prefix "fold"
  146. (pass-if "empty environment"
  147. (let* ((env (make-leaf-environment)))
  148. (eq? 'success (environment-fold env folder 'success))))
  149. (pass-if "one symbol"
  150. (let* ((env (make-leaf-environment)))
  151. (environment-define env 'a #t)
  152. (equal? '((a . #t)) (environment-fold env folder '()))))
  153. (pass-if "two symbols"
  154. (let* ((env (make-leaf-environment)))
  155. (environment-define env 'a #t)
  156. (environment-define env 'b #f)
  157. (let ((folded (environment-fold env folder '())))
  158. (or (equal? folded '((a . #t) (b . #f)))
  159. (equal? folded '((b . #f) (a . #t))))))))
  160. (with-test-prefix "observe"
  161. (pass-if "observe an environment"
  162. (let* ((env (make-leaf-environment)))
  163. (environment-observe env (make-observer-func))
  164. #t))
  165. (pass-if "observe an environment twice"
  166. (let* ((env (make-leaf-environment))
  167. (observer-1 (environment-observe env (make-observer-func)))
  168. (observer-2 (environment-observe env (make-observer-func))))
  169. (not (eq? observer-1 observer-2))))
  170. (pass-if "definition of an undefined symbol"
  171. (let* ((env (make-leaf-environment))
  172. (func (make-observer-func)))
  173. (environment-observe env func)
  174. (environment-define env 'a 1)
  175. (eqv? (func) 1)))
  176. (pass-if "definition of an already defined symbol"
  177. (let* ((env (make-leaf-environment)))
  178. (environment-define env 'a 1)
  179. (let* ((func (make-observer-func)))
  180. (environment-observe env func)
  181. (environment-define env 'a 1)
  182. (eqv? (func) 1))))
  183. (pass-if "set!ing of a defined symbol"
  184. (let* ((env (make-leaf-environment)))
  185. (environment-define env 'a 1)
  186. (let* ((func (make-observer-func)))
  187. (environment-observe env func)
  188. (environment-set! env 'a 1)
  189. (eqv? (func) 0))))
  190. (pass-if "undefining a defined symbol"
  191. (let* ((env (make-leaf-environment)))
  192. (environment-define env 'a 1)
  193. (let* ((func (make-observer-func)))
  194. (environment-observe env func)
  195. (environment-undefine env 'a)
  196. (eqv? (func) 1))))
  197. (pass-if "undefining an already undefined symbol"
  198. (let* ((env (make-leaf-environment))
  199. (func (make-observer-func)))
  200. (environment-observe env func)
  201. (environment-undefine env 'a)
  202. (eqv? (func) 0)))
  203. (pass-if "unobserve an active observer"
  204. (let* ((env (make-leaf-environment))
  205. (func (make-observer-func))
  206. (observer (environment-observe env func)))
  207. (environment-unobserve observer)
  208. (environment-define env 'a 1)
  209. (eqv? (func) 0)))
  210. (pass-if "unobserve an inactive observer"
  211. (let* ((env (make-leaf-environment))
  212. (func (make-observer-func))
  213. (observer (environment-observe env func)))
  214. (environment-unobserve observer)
  215. (environment-unobserve observer)
  216. #t)))
  217. (with-test-prefix "observe-weak"
  218. (pass-if "observe an environment"
  219. (let* ((env (make-leaf-environment)))
  220. (environment-observe-weak env (make-observer-func))
  221. #t))
  222. (pass-if "observe an environment twice"
  223. (let* ((env (make-leaf-environment))
  224. (observer-1 (environment-observe-weak env (make-observer-func)))
  225. (observer-2 (environment-observe-weak env (make-observer-func))))
  226. (not (eq? observer-1 observer-2))))
  227. (pass-if "definition of an undefined symbol"
  228. (let* ((env (make-leaf-environment))
  229. (func (make-observer-func)))
  230. (environment-observe-weak env func)
  231. (environment-define env 'a 1)
  232. (eqv? (func) 1)))
  233. (pass-if "definition of an already defined symbol"
  234. (let* ((env (make-leaf-environment)))
  235. (environment-define env 'a 1)
  236. (let* ((func (make-observer-func)))
  237. (environment-observe-weak env func)
  238. (environment-define env 'a 1)
  239. (eqv? (func) 1))))
  240. (pass-if "set!ing of a defined symbol"
  241. (let* ((env (make-leaf-environment)))
  242. (environment-define env 'a 1)
  243. (let* ((func (make-observer-func)))
  244. (environment-observe-weak env func)
  245. (environment-set! env 'a 1)
  246. (eqv? (func) 0))))
  247. (pass-if "undefining a defined symbol"
  248. (let* ((env (make-leaf-environment)))
  249. (environment-define env 'a 1)
  250. (let* ((func (make-observer-func)))
  251. (environment-observe-weak env func)
  252. (environment-undefine env 'a)
  253. (eqv? (func) 1))))
  254. (pass-if "undefining an already undefined symbol"
  255. (let* ((env (make-leaf-environment))
  256. (func (make-observer-func)))
  257. (environment-observe-weak env func)
  258. (environment-undefine env 'a)
  259. (eqv? (func) 0)))
  260. (pass-if "unobserve an active observer"
  261. (let* ((env (make-leaf-environment))
  262. (func (make-observer-func))
  263. (observer (environment-observe-weak env func)))
  264. (environment-unobserve observer)
  265. (environment-define env 'a 1)
  266. (eqv? (func) 0)))
  267. (pass-if "unobserve an inactive observer"
  268. (let* ((env (make-leaf-environment))
  269. (func (make-observer-func))
  270. (observer (environment-observe-weak env func)))
  271. (environment-unobserve observer)
  272. (environment-unobserve observer)
  273. #t))
  274. (pass-if "weak observer gets collected"
  275. (gc)
  276. (let* ((env (make-leaf-environment))
  277. (func (make-observer-func)))
  278. (environment-observe-weak env func)
  279. (gc)
  280. (environment-define env 'a 1)
  281. (if (not (eqv? (func) 0))
  282. (throw 'unresolved) ; note: conservative scanning
  283. #t))))
  284. (with-test-prefix "erroneous observers"
  285. (pass-if "update continues after error"
  286. (let* ((env (make-leaf-environment))
  287. (func-1 (make-erroneous-observer-func))
  288. (func-2 (make-erroneous-observer-func)))
  289. (environment-observe env func-1)
  290. (environment-observe env func-2)
  291. (catch #t
  292. (lambda ()
  293. (environment-define env 'a 1)
  294. #f)
  295. (lambda args
  296. (and (eq? (func-1) 1)
  297. (eq? (func-2) 1))))))))
  298. ;;;
  299. ;;; leaf-environment based eval-environments
  300. ;;;
  301. (with-test-prefix "leaf-environment based eval-environments"
  302. (with-test-prefix "eval-environment?"
  303. (pass-if "documented?"
  304. (documented? eval-environment?))
  305. (pass-if "non-environment-object"
  306. (not (eval-environment? #f)))
  307. (pass-if "leaf-environment-object"
  308. (not (eval-environment? (make-leaf-environment)))))
  309. (with-test-prefix "make-eval-environment"
  310. (pass-if "documented?"
  311. (documented? make-eval-environment))
  312. (let* ((local (make-leaf-environment))
  313. (imported (make-leaf-environment)))
  314. (pass-if "produces an environment"
  315. (environment? (make-eval-environment local imported)))
  316. (pass-if "produces an eval-environment"
  317. (eval-environment? (make-eval-environment local imported)))
  318. (pass-if "produces always a new environment"
  319. (not (eq? (make-eval-environment local imported)
  320. (make-eval-environment local imported))))))
  321. (with-test-prefix "eval-environment-local"
  322. (pass-if "documented?"
  323. (documented? eval-environment-local))
  324. (pass-if "returns local"
  325. (let* ((local (make-leaf-environment))
  326. (imported (make-leaf-environment))
  327. (env (make-eval-environment local imported)))
  328. (eq? (eval-environment-local env) local))))
  329. (with-test-prefix "eval-environment-imported"
  330. (pass-if "documented?"
  331. (documented? eval-environment-imported))
  332. (pass-if "returns imported"
  333. (let* ((local (make-leaf-environment))
  334. (imported (make-leaf-environment))
  335. (env (make-eval-environment local imported)))
  336. (eq? (eval-environment-imported env) imported))))
  337. (with-test-prefix "bound, define, ref, set!, cell"
  338. (pass-if "symbols are unbound by default"
  339. (let* ((local (make-leaf-environment))
  340. (imported (make-leaf-environment))
  341. (env (make-eval-environment local imported)))
  342. (and (not (environment-bound? env 'a))
  343. (not (environment-bound? env 'b))
  344. (not (environment-bound? env 'c)))))
  345. (with-test-prefix "symbols bound in imported"
  346. (pass-if "binding is visible"
  347. (let* ((local (make-leaf-environment))
  348. (imported (make-leaf-environment))
  349. (env (make-eval-environment local imported)))
  350. (environment-bound? env 'a)
  351. (environment-define imported 'a #t)
  352. (environment-bound? env 'a)))
  353. (pass-if "ref works"
  354. (let* ((local (make-leaf-environment))
  355. (imported (make-leaf-environment))
  356. (env (make-eval-environment local imported)))
  357. (environment-bound? env 'a)
  358. (environment-define imported 'a #t)
  359. (environment-ref env 'a)))
  360. (pass-if "set! works"
  361. (let* ((local (make-leaf-environment))
  362. (imported (make-leaf-environment))
  363. (env (make-eval-environment local imported)))
  364. (environment-define imported 'a #f)
  365. (environment-set! env 'a #t)
  366. (environment-ref imported 'a)))
  367. (pass-if "cells are passed through"
  368. (let* ((local (make-leaf-environment))
  369. (imported (make-leaf-environment))
  370. (env (make-eval-environment local imported)))
  371. (environment-define imported 'a #t)
  372. (let* ((imported-cell (environment-cell imported 'a #f))
  373. (env-cell (environment-cell env 'a #f)))
  374. (eq? env-cell imported-cell)))))
  375. (with-test-prefix "symbols bound in local"
  376. (pass-if "binding is visible"
  377. (let* ((local (make-leaf-environment))
  378. (imported (make-leaf-environment))
  379. (env (make-eval-environment local imported)))
  380. (environment-bound? env 'a)
  381. (environment-define local 'a #t)
  382. (environment-bound? env 'a)))
  383. (pass-if "ref works"
  384. (let* ((local (make-leaf-environment))
  385. (imported (make-leaf-environment))
  386. (env (make-eval-environment local imported)))
  387. (environment-define local 'a #t)
  388. (environment-ref env 'a)))
  389. (pass-if "set! works"
  390. (let* ((local (make-leaf-environment))
  391. (imported (make-leaf-environment))
  392. (env (make-eval-environment local imported)))
  393. (environment-define local 'a #f)
  394. (environment-set! env 'a #t)
  395. (environment-ref local 'a)))
  396. (pass-if "cells are passed through"
  397. (let* ((local (make-leaf-environment))
  398. (imported (make-leaf-environment))
  399. (env (make-eval-environment local imported)))
  400. (environment-define local 'a #t)
  401. (let* ((local-cell (environment-cell local 'a #f))
  402. (env-cell (environment-cell env 'a #f)))
  403. (eq? env-cell local-cell)))))
  404. (with-test-prefix "symbols bound in local and imported"
  405. (pass-if "binding is visible"
  406. (let* ((local (make-leaf-environment))
  407. (imported (make-leaf-environment))
  408. (env (make-eval-environment local imported)))
  409. (environment-bound? env 'a)
  410. (environment-define imported 'a #t)
  411. (environment-define local 'a #f)
  412. (environment-bound? env 'a)))
  413. (pass-if "ref works"
  414. (let* ((local (make-leaf-environment))
  415. (imported (make-leaf-environment))
  416. (env (make-eval-environment local imported)))
  417. (environment-define imported 'a #f)
  418. (environment-define local 'a #t)
  419. (environment-ref env 'a)))
  420. (pass-if "set! changes local"
  421. (let* ((local (make-leaf-environment))
  422. (imported (make-leaf-environment))
  423. (env (make-eval-environment local imported)))
  424. (environment-define imported 'a #f)
  425. (environment-define local 'a #f)
  426. (environment-set! env 'a #t)
  427. (environment-ref local 'a)))
  428. (pass-if "set! does not touch imported"
  429. (let* ((local (make-leaf-environment))
  430. (imported (make-leaf-environment))
  431. (env (make-eval-environment local imported)))
  432. (environment-define imported 'a #t)
  433. (environment-define local 'a #t)
  434. (environment-set! env 'a #f)
  435. (environment-ref imported 'a)))
  436. (pass-if "cells from local are passed through"
  437. (let* ((local (make-leaf-environment))
  438. (imported (make-leaf-environment))
  439. (env (make-eval-environment local imported)))
  440. (environment-define local 'a #t)
  441. (let* ((local-cell (environment-cell local 'a #f))
  442. (env-cell (environment-cell env 'a #f)))
  443. (eq? env-cell local-cell)))))
  444. (with-test-prefix "defining symbols"
  445. (pass-if "symbols are bound in local after define"
  446. (let* ((local (make-leaf-environment))
  447. (imported (make-leaf-environment))
  448. (env (make-eval-environment local imported)))
  449. (environment-define env 'a #t)
  450. (environment-bound? local 'a)))
  451. (pass-if "cells in local get rebound after define"
  452. (let* ((local (make-leaf-environment))
  453. (imported (make-leaf-environment))
  454. (env (make-eval-environment local imported)))
  455. (environment-define env 'a #f)
  456. (let* ((old-cell (environment-cell local 'a #f)))
  457. (environment-define env 'a #f)
  458. (let* ((new-cell (environment-cell local 'a #f)))
  459. (not (eq? new-cell old-cell))))))
  460. (pass-if "cells in imported get shadowed after define"
  461. (let* ((local (make-leaf-environment))
  462. (imported (make-leaf-environment))
  463. (env (make-eval-environment local imported)))
  464. (environment-define imported 'a #f)
  465. (environment-define env 'a #t)
  466. (environment-ref local 'a))))
  467. (let* ((local (make-leaf-environment))
  468. (imported (make-leaf-environment))
  469. (env (make-eval-environment local imported)))
  470. (pass-if-exception "reference an unbound symbol"
  471. exception:unbound-symbol
  472. (environment-ref env 'b))
  473. (pass-if-exception "set! an unbound symbol"
  474. exception:unbound-symbol
  475. (environment-set! env 'b #f))
  476. (pass-if-exception "get a readable cell for an unbound symbol"
  477. exception:unbound-symbol
  478. (environment-cell env 'b #f))
  479. (pass-if-exception "get a writable cell for an unbound symbol"
  480. exception:unbound-symbol
  481. (environment-cell env 'b #t))))
  482. (with-test-prefix "eval-environment-set-local!"
  483. (pass-if "documented?"
  484. (documented? eval-environment-set-local!))
  485. (pass-if "new binding becomes visible"
  486. (let* ((old-local (make-leaf-environment))
  487. (new-local (make-leaf-environment))
  488. (imported (make-leaf-environment))
  489. (env (make-eval-environment old-local imported)))
  490. (environment-bound? env 'a)
  491. (environment-define new-local 'a #t)
  492. (eval-environment-set-local! env new-local)
  493. (environment-bound? env 'a)))
  494. (pass-if "existing binding is replaced"
  495. (let* ((old-local (make-leaf-environment))
  496. (new-local (make-leaf-environment))
  497. (imported (make-leaf-environment))
  498. (env (make-eval-environment old-local imported)))
  499. (environment-define old-local 'a #f)
  500. (environment-ref env 'a)
  501. (environment-define new-local 'a #t)
  502. (eval-environment-set-local! env new-local)
  503. (environment-ref env 'a)))
  504. (pass-if "undefined binding is removed"
  505. (let* ((old-local (make-leaf-environment))
  506. (new-local (make-leaf-environment))
  507. (imported (make-leaf-environment))
  508. (env (make-eval-environment old-local imported)))
  509. (environment-define old-local 'a #f)
  510. (environment-ref env 'a)
  511. (eval-environment-set-local! env new-local)
  512. (not (environment-bound? env 'a))))
  513. (pass-if "binding in imported remains shadowed"
  514. (let* ((old-local (make-leaf-environment))
  515. (new-local (make-leaf-environment))
  516. (imported (make-leaf-environment))
  517. (env (make-eval-environment old-local imported)))
  518. (environment-define imported 'a #f)
  519. (environment-define old-local 'a #f)
  520. (environment-ref env 'a)
  521. (environment-define new-local 'a #t)
  522. (eval-environment-set-local! env new-local)
  523. (environment-ref env 'a)))
  524. (pass-if "binding in imported gets shadowed"
  525. (let* ((old-local (make-leaf-environment))
  526. (new-local (make-leaf-environment))
  527. (imported (make-leaf-environment))
  528. (env (make-eval-environment old-local imported)))
  529. (environment-define imported 'a #f)
  530. (environment-ref env 'a)
  531. (environment-define new-local 'a #t)
  532. (eval-environment-set-local! env new-local)
  533. (environment-ref env 'a)))
  534. (pass-if "binding in imported becomes visible"
  535. (let* ((old-local (make-leaf-environment))
  536. (new-local (make-leaf-environment))
  537. (imported (make-leaf-environment))
  538. (env (make-eval-environment old-local imported)))
  539. (environment-define imported 'a #t)
  540. (environment-define old-local 'a #f)
  541. (environment-ref env 'a)
  542. (eval-environment-set-local! env new-local)
  543. (environment-ref env 'a))))
  544. (with-test-prefix "eval-environment-set-imported!"
  545. (pass-if "documented?"
  546. (documented? eval-environment-set-imported!))
  547. (pass-if "new binding becomes visible"
  548. (let* ((local (make-leaf-environment))
  549. (old-imported (make-leaf-environment))
  550. (new-imported (make-leaf-environment))
  551. (env (make-eval-environment local old-imported)))
  552. (environment-bound? env 'a)
  553. (environment-define new-imported 'a #t)
  554. (eval-environment-set-imported! env new-imported)
  555. (environment-bound? env 'a)))
  556. (pass-if "existing binding is replaced"
  557. (let* ((local (make-leaf-environment))
  558. (old-imported (make-leaf-environment))
  559. (new-imported (make-leaf-environment))
  560. (env (make-eval-environment local old-imported)))
  561. (environment-define old-imported 'a #f)
  562. (environment-ref env 'a)
  563. (environment-define new-imported 'a #t)
  564. (eval-environment-set-imported! env new-imported)
  565. (environment-ref env 'a)))
  566. (pass-if "undefined binding is removed"
  567. (let* ((local (make-leaf-environment))
  568. (old-imported (make-leaf-environment))
  569. (new-imported (make-leaf-environment))
  570. (env (make-eval-environment local old-imported)))
  571. (environment-define old-imported 'a #f)
  572. (environment-ref env 'a)
  573. (eval-environment-set-imported! env new-imported)
  574. (not (environment-bound? env 'a))))
  575. (pass-if "binding in imported remains shadowed"
  576. (let* ((local (make-leaf-environment))
  577. (old-imported (make-leaf-environment))
  578. (new-imported (make-leaf-environment))
  579. (env (make-eval-environment local old-imported)))
  580. (environment-define local 'a #t)
  581. (environment-define old-imported 'a #f)
  582. (environment-ref env 'a)
  583. (environment-define new-imported 'a #t)
  584. (eval-environment-set-imported! env new-imported)
  585. (environment-ref env 'a)))
  586. (pass-if "binding in imported gets shadowed"
  587. (let* ((local (make-leaf-environment))
  588. (old-imported (make-leaf-environment))
  589. (new-imported (make-leaf-environment))
  590. (env (make-eval-environment local old-imported)))
  591. (environment-define local 'a #t)
  592. (environment-ref env 'a)
  593. (environment-define new-imported 'a #f)
  594. (eval-environment-set-imported! env new-imported)
  595. (environment-ref env 'a))))
  596. (with-test-prefix "undefine"
  597. (pass-if "undefine an already undefined symbol"
  598. (let* ((local (make-leaf-environment))
  599. (imported (make-leaf-environment))
  600. (env (make-eval-environment local imported)))
  601. (environment-undefine env 'a)
  602. #t))
  603. (pass-if "undefine removes a binding from local"
  604. (let* ((local (make-leaf-environment))
  605. (imported (make-leaf-environment))
  606. (env (make-eval-environment local imported)))
  607. (environment-define local 'a #t)
  608. (environment-undefine env 'a)
  609. (not (environment-bound? local 'a))))
  610. (pass-if "undefine does not influence imported"
  611. (let* ((local (make-leaf-environment))
  612. (imported (make-leaf-environment))
  613. (env (make-eval-environment local imported)))
  614. (environment-define imported 'a #t)
  615. (environment-undefine env 'a)
  616. (environment-bound? imported 'a)))
  617. (pass-if "undefine an imported symbol does not undefine it"
  618. (let* ((local (make-leaf-environment))
  619. (imported (make-leaf-environment))
  620. (env (make-eval-environment local imported)))
  621. (environment-define imported 'a #t)
  622. (environment-undefine env 'a)
  623. (environment-bound? env 'a)))
  624. (pass-if "undefine unshadows an imported symbol"
  625. (let* ((local (make-leaf-environment))
  626. (imported (make-leaf-environment))
  627. (env (make-eval-environment local imported)))
  628. (environment-define imported 'a #t)
  629. (environment-define local 'a #f)
  630. (environment-undefine env 'a)
  631. (environment-ref env 'a))))
  632. (with-test-prefix "fold"
  633. (pass-if "empty environment"
  634. (let* ((local (make-leaf-environment))
  635. (imported (make-leaf-environment))
  636. (env (make-eval-environment local imported)))
  637. (eq? 'success (environment-fold env folder 'success))))
  638. (pass-if "one symbol in local"
  639. (let* ((local (make-leaf-environment))
  640. (imported (make-leaf-environment))
  641. (env (make-eval-environment local imported)))
  642. (environment-define local 'a #t)
  643. (equal? '((a . #t)) (environment-fold env folder '()))))
  644. (pass-if "one symbol in imported"
  645. (let* ((local (make-leaf-environment))
  646. (imported (make-leaf-environment))
  647. (env (make-eval-environment local imported)))
  648. (environment-define imported 'a #t)
  649. (equal? '((a . #t)) (environment-fold env folder '()))))
  650. (pass-if "shadowed symbol"
  651. (let* ((local (make-leaf-environment))
  652. (imported (make-leaf-environment))
  653. (env (make-eval-environment local imported)))
  654. (environment-define local 'a #t)
  655. (environment-define imported 'a #f)
  656. (equal? '((a . #t)) (environment-fold env folder '()))))
  657. (pass-if "one symbol each"
  658. (let* ((local (make-leaf-environment))
  659. (imported (make-leaf-environment))
  660. (env (make-eval-environment local imported)))
  661. (environment-define local 'a #t)
  662. (environment-define imported 'b #f)
  663. (let ((folded (environment-fold env folder '())))
  664. (or (equal? folded '((a . #t) (b . #f)))
  665. (equal? folded '((b . #f) (a . #t))))))))
  666. (with-test-prefix "observe"
  667. (pass-if "observe an environment"
  668. (let* ((local (make-leaf-environment))
  669. (imported (make-leaf-environment))
  670. (env (make-eval-environment local imported)))
  671. (environment-observe env (make-observer-func))
  672. #t))
  673. (pass-if "observe an environment twice"
  674. (let* ((local (make-leaf-environment))
  675. (imported (make-leaf-environment))
  676. (env (make-eval-environment local imported))
  677. (observer-1 (environment-observe env (make-observer-func)))
  678. (observer-2 (environment-observe env (make-observer-func))))
  679. (not (eq? observer-1 observer-2))))
  680. (pass-if "definition of an undefined symbol"
  681. (let* ((local (make-leaf-environment))
  682. (imported (make-leaf-environment))
  683. (env (make-eval-environment local imported))
  684. (func (make-observer-func)))
  685. (environment-observe env func)
  686. (environment-define env 'a 1)
  687. (eqv? (func) 1)))
  688. (pass-if "definition of an already defined symbol"
  689. (let* ((local (make-leaf-environment))
  690. (imported (make-leaf-environment))
  691. (env (make-eval-environment local imported)))
  692. (environment-define env 'a 1)
  693. (let* ((func (make-observer-func)))
  694. (environment-observe env func)
  695. (environment-define env 'a 1)
  696. (eqv? (func) 1))))
  697. (pass-if "set!ing of a defined symbol"
  698. (let* ((local (make-leaf-environment))
  699. (imported (make-leaf-environment))
  700. (env (make-eval-environment local imported)))
  701. (environment-define env 'a 1)
  702. (let* ((func (make-observer-func)))
  703. (environment-observe env func)
  704. (environment-set! env 'a 1)
  705. (eqv? (func) 0))))
  706. (pass-if "undefining a defined symbol"
  707. (let* ((local (make-leaf-environment))
  708. (imported (make-leaf-environment))
  709. (env (make-eval-environment local imported)))
  710. (environment-define env 'a 1)
  711. (let* ((func (make-observer-func)))
  712. (environment-observe env func)
  713. (environment-undefine env 'a)
  714. (eqv? (func) 1))))
  715. (pass-if "undefining an already undefined symbol"
  716. (let* ((local (make-leaf-environment))
  717. (imported (make-leaf-environment))
  718. (env (make-eval-environment local imported))
  719. (func (make-observer-func)))
  720. (environment-observe env func)
  721. (environment-undefine env 'a)
  722. (eqv? (func) 0)))
  723. (pass-if "unobserve an active observer"
  724. (let* ((local (make-leaf-environment))
  725. (imported (make-leaf-environment))
  726. (env (make-eval-environment local imported))
  727. (func (make-observer-func))
  728. (observer (environment-observe env func)))
  729. (environment-unobserve observer)
  730. (environment-define env 'a 1)
  731. (eqv? (func) 0)))
  732. (pass-if "unobserve an inactive observer"
  733. (let* ((local (make-leaf-environment))
  734. (imported (make-leaf-environment))
  735. (env (make-eval-environment local imported))
  736. (func (make-observer-func))
  737. (observer (environment-observe env func)))
  738. (environment-unobserve observer)
  739. (environment-unobserve observer)
  740. #t)))
  741. (with-test-prefix "observe-weak"
  742. (pass-if "observe an environment"
  743. (let* ((local (make-leaf-environment))
  744. (imported (make-leaf-environment))
  745. (env (make-eval-environment local imported)))
  746. (environment-observe-weak env (make-observer-func))
  747. #t))
  748. (pass-if "observe an environment twice"
  749. (let* ((local (make-leaf-environment))
  750. (imported (make-leaf-environment))
  751. (env (make-eval-environment local imported))
  752. (observer-1 (environment-observe-weak env (make-observer-func)))
  753. (observer-2 (environment-observe-weak env (make-observer-func))))
  754. (not (eq? observer-1 observer-2))))
  755. (pass-if "definition of an undefined symbol"
  756. (let* ((local (make-leaf-environment))
  757. (imported (make-leaf-environment))
  758. (env (make-eval-environment local imported))
  759. (func (make-observer-func)))
  760. (environment-observe-weak env func)
  761. (environment-define env 'a 1)
  762. (eqv? (func) 1)))
  763. (pass-if "definition of an already defined symbol"
  764. (let* ((local (make-leaf-environment))
  765. (imported (make-leaf-environment))
  766. (env (make-eval-environment local imported)))
  767. (environment-define env 'a 1)
  768. (let* ((func (make-observer-func)))
  769. (environment-observe-weak env func)
  770. (environment-define env 'a 1)
  771. (eqv? (func) 1))))
  772. (pass-if "set!ing of a defined symbol"
  773. (let* ((local (make-leaf-environment))
  774. (imported (make-leaf-environment))
  775. (env (make-eval-environment local imported)))
  776. (environment-define env 'a 1)
  777. (let* ((func (make-observer-func)))
  778. (environment-observe-weak env func)
  779. (environment-set! env 'a 1)
  780. (eqv? (func) 0))))
  781. (pass-if "undefining a defined symbol"
  782. (let* ((local (make-leaf-environment))
  783. (imported (make-leaf-environment))
  784. (env (make-eval-environment local imported)))
  785. (environment-define env 'a 1)
  786. (let* ((func (make-observer-func)))
  787. (environment-observe-weak env func)
  788. (environment-undefine env 'a)
  789. (eqv? (func) 1))))
  790. (pass-if "undefining an already undefined symbol"
  791. (let* ((local (make-leaf-environment))
  792. (imported (make-leaf-environment))
  793. (env (make-eval-environment local imported))
  794. (func (make-observer-func)))
  795. (environment-observe-weak env func)
  796. (environment-undefine env 'a)
  797. (eqv? (func) 0)))
  798. (pass-if "unobserve an active observer"
  799. (let* ((local (make-leaf-environment))
  800. (imported (make-leaf-environment))
  801. (env (make-eval-environment local imported))
  802. (func (make-observer-func))
  803. (observer (environment-observe-weak env func)))
  804. (environment-unobserve observer)
  805. (environment-define env 'a 1)
  806. (eqv? (func) 0)))
  807. (pass-if "unobserve an inactive observer"
  808. (let* ((local (make-leaf-environment))
  809. (imported (make-leaf-environment))
  810. (env (make-eval-environment local imported))
  811. (func (make-observer-func))
  812. (observer (environment-observe-weak env func)))
  813. (environment-unobserve observer)
  814. (environment-unobserve observer)
  815. #t))
  816. (pass-if "weak observer gets collected"
  817. (gc)
  818. (let* ((local (make-leaf-environment))
  819. (imported (make-leaf-environment))
  820. (env (make-eval-environment local imported))
  821. (func (make-observer-func)))
  822. (environment-observe-weak env func)
  823. (gc)
  824. (environment-define env 'a 1)
  825. (if (not (eqv? (func) 0))
  826. (throw 'unresolved) ; note: conservative scanning
  827. #t))))
  828. (with-test-prefix "erroneous observers"
  829. (pass-if "update continues after error"
  830. (let* ((local (make-leaf-environment))
  831. (imported (make-leaf-environment))
  832. (env (make-eval-environment local imported))
  833. (func-1 (make-erroneous-observer-func))
  834. (func-2 (make-erroneous-observer-func)))
  835. (environment-observe env func-1)
  836. (environment-observe env func-2)
  837. (catch #t
  838. (lambda ()
  839. (environment-define env 'a 1)
  840. #f)
  841. (lambda args
  842. (and (eq? (func-1) 1)
  843. (eq? (func-2) 1))))))))
  844. ;;;
  845. ;;; leaf-environment based import-environments
  846. ;;;
  847. (with-test-prefix "leaf-environment based import-environments"
  848. (with-test-prefix "import-environment?"
  849. (pass-if "documented?"
  850. (documented? import-environment?))
  851. (pass-if "non-environment-object"
  852. (not (import-environment? #f)))
  853. (pass-if "leaf-environment-object"
  854. (not (import-environment? (make-leaf-environment))))
  855. (pass-if "eval-environment-object"
  856. (let* ((local (make-leaf-environment))
  857. (imported (make-leaf-environment))
  858. (env (make-eval-environment local imported)))
  859. (not (import-environment? (make-leaf-environment))))))
  860. (with-test-prefix "make-import-environment"
  861. (pass-if "documented?"
  862. (documented? make-import-environment))))