mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +02:00
Syntax objects are comparable with equal?
* libguile/eq.c (scm_equal_p, scm_raw_ihash): Add cases for syntax objects, which should be comparable with equal?. * test-suite/tests/syntax.test ("syntax objects"): Add tests.
This commit is contained in:
parent
02cf38514d
commit
2e5f7d8f6d
3 changed files with 53 additions and 0 deletions
|
@ -33,6 +33,7 @@
|
|||
#include "libguile/vectors.h"
|
||||
#include "libguile/hashtab.h"
|
||||
#include "libguile/bytevectors.h"
|
||||
#include "libguile/syntax.h"
|
||||
|
||||
#include "libguile/struct.h"
|
||||
#include "libguile/goops.h"
|
||||
|
@ -362,6 +363,16 @@ scm_equal_p (SCM x, SCM y)
|
|||
case scm_tc7_vector:
|
||||
case scm_tc7_wvect:
|
||||
return scm_i_vector_equal_p (x, y);
|
||||
case scm_tc7_syntax:
|
||||
if (scm_is_false (scm_equal_p (scm_syntax_wrap (x),
|
||||
scm_syntax_wrap (y))))
|
||||
return SCM_BOOL_F;
|
||||
if (scm_is_false (scm_equal_p (scm_syntax_module (x),
|
||||
scm_syntax_module (y))))
|
||||
return SCM_BOOL_F;
|
||||
x = scm_syntax_expression (x);
|
||||
y = scm_syntax_expression (y);
|
||||
goto tailrecurse;
|
||||
}
|
||||
|
||||
/* Otherwise just return false. Dispatching to the generic is the wrong thing
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "libguile/ports.h"
|
||||
#include "libguile/strings.h"
|
||||
#include "libguile/symbols.h"
|
||||
#include "libguile/syntax.h"
|
||||
#include "libguile/vectors.h"
|
||||
|
||||
#include "libguile/validate.h"
|
||||
|
@ -333,6 +334,14 @@ scm_raw_ihash (SCM obj, size_t depth)
|
|||
h ^= scm_raw_ihash (scm_c_vector_ref (obj, h % len), i);
|
||||
return h;
|
||||
}
|
||||
case scm_tc7_syntax:
|
||||
{
|
||||
unsigned long h;
|
||||
h = scm_raw_ihash (scm_syntax_expression (obj), depth);
|
||||
h ^= scm_raw_ihash (scm_syntax_wrap (obj), depth);
|
||||
h ^= scm_raw_ihash (scm_syntax_module (obj), depth);
|
||||
return h;
|
||||
}
|
||||
case scm_tcs_cons_imcar:
|
||||
case scm_tcs_cons_nimcar:
|
||||
if (depth)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
(define-module (test-suite test-syntax)
|
||||
#:use-module (ice-9 regex)
|
||||
#:use-module (ice-9 local-eval)
|
||||
#:use-module ((system syntax) #:select (syntax?))
|
||||
#:use-module (test-suite lib))
|
||||
|
||||
|
||||
|
@ -1617,6 +1618,38 @@
|
|||
(length #'(x …))))
|
||||
env))))
|
||||
|
||||
(with-test-prefix "syntax objects"
|
||||
(let ((interpreted (eval '#'(foo bar baz) (current-module)))
|
||||
(interpreted-bis (eval '#'(foo bar baz) (current-module)))
|
||||
(compiled ((@ (system base compile) compile) '#'(foo bar baz)
|
||||
#:env (current-module))))
|
||||
;; Guile's expander doesn't wrap lists.
|
||||
(pass-if "interpreted syntax object?"
|
||||
(and (list? interpreted)
|
||||
(and-map syntax? interpreted)))
|
||||
(pass-if "compiled syntax object?"
|
||||
(and (list? compiled)
|
||||
(and-map syntax? compiled)))
|
||||
|
||||
(pass-if "interpreted syntax objects are not vectors"
|
||||
(not (vector? interpreted)))
|
||||
(pass-if "compiled syntax objects are not vectors"
|
||||
(not (vector? compiled)))
|
||||
|
||||
(pass-if-equal "syntax objects comparable with equal? (eval/eval)"
|
||||
interpreted interpreted-bis)
|
||||
(pass-if-equal "syntax objects comparable with equal? (eval/compile)"
|
||||
interpreted compiled)
|
||||
|
||||
(pass-if-equal "syntax objects hash the same (eval/eval)"
|
||||
(hash interpreted most-positive-fixnum)
|
||||
(hash interpreted-bis most-positive-fixnum))
|
||||
|
||||
(pass-if-equal "syntax objects hash the same (eval/compile)"
|
||||
(hash interpreted most-positive-fixnum)
|
||||
(hash compiled most-positive-fixnum))))
|
||||
|
||||
|
||||
;;; Local Variables:
|
||||
;;; eval: (put 'pass-if-syntax-error 'scheme-indent-function 1)
|
||||
;;; eval: (put 'with-ellipsis 'scheme-indent-function 1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue