Jürgen Bömmels avatar Jürgen Bömmels committed f6d150f

Translation fix

While writing a test for it, I stumbled across some other error:
number? integer? et al. predicates are per R5RS applicable to all
scheme objects not just numbers. Fixed this too.

Comments (0)

Files changed (3)

scheme/procedure.py

 import py
 from scheme.object import W_Root, W_Boolean, W_Pair, W_Symbol, \
         W_Number, W_Real, W_Integer, W_List, W_Character, W_Vector, \
-        Body, W_Procedure, W_Promise, plst2lst, w_undefined, \
+        Body, W_Procedure, W_String, W_Promise, plst2lst, w_undefined, \
         SchemeSyntaxError, SchemeQuit, WrongArgType, WrongArgsNumber, \
         w_nil
 
     def predicate(self, w_obj):
         raise NotImplementedError
 
-class IntegerP(PredicateNumber):
+class NumberP(W_Procedure):
+    # number? & Friends are applicable to any schemetype
+    # not just numbers
+    _symbol_name = "number?"
+
+    def procedure(self, ctx, lst):
+        if len(lst) != 1:
+            raise WrongArgsNumber
+
+        w_obj = lst[0]
+        if not isinstance(w_obj, W_Number):
+            return W_Boolean(False)
+
+        return W_Boolean(self.predicate(w_obj))
+
+    def predicate(self, w_obj):
+        return True
+
+class IntegerP(NumberP):
     _symbol_name = "integer?"
 
     def predicate(self, w_obj):
 
         return True
 
-class RealP(PredicateNumber):
+class RealP(NumberP):
     _symbol_name = "real?"
 
     def predicate(self, w_obj):
 class RationalP(RealP):
     _symbol_name = "rational?"
 
-class NumberP(PredicateNumber):
-    _symbol_name = "number?"
-
-    def predicate(self, w_obj):
-        return isinstance(w_obj, W_Number)
-
 class ComplexP(NumberP):
     _symbol_name = "complex?"
 
         return w_obj.round() % 2 == 0
 
 ##
-# Type Pradicates
+# Type Predicates
 ##
 class TypePredicate(W_Procedure):
     def procedure(self, ctx, lst):
     def predicate(self, w_obj):
         return w_obj is w_nil
 
+
 ##
 # Input/Output procedures
 ##

scheme/test/test_eval.py

     assert eval_noctx("(number? 42)").to_boolean()
     assert eval_noctx("(number? 42.1)").to_boolean()
 
-    py.test.raises(WrongArgType, eval_noctx, "(number? 'a)" )
+    assert eval_noctx("(number? 'a)").to_boolean() is False
 
 def test_exactness():
     assert eval_noctx("(exact? 42)").to_boolean()

scheme/test/test_scheme_level.py

   '()
 ))
 """)
+
+def test_typepredicates():
+    run_with_assert(r"""
+(define some-objs
+  (list #f #t 1 1.0 'symbol "string" #\c '(1 2) '() char? '#() '#(1 2)))   
+(assert (equal?
+  (map (lambda (test-func) (map test-func some-objs))
+    (list boolean? number? symbol? string? char? pair? null? procedure? vector?))
+  ;; #f #t 1 1.0 'symbol "string" #\c '(1 2) '() char? '#() '#(1 2)
+  '((#t #t #f #f #f      #f       #f  #f     #f  #f    #f   #f) ; boolean?
+    (#f #f #t #t #f      #f       #f  #f     #f  #f    #f   #f) ; number?
+    (#f #f #f #f #t      #f       #f  #f     #f  #f    #f   #f) ; symbol?
+    (#f #f #f #f #f      #t       #f  #f     #f  #f    #f   #f) ; string?
+    (#f #f #f #f #f      #f       #t  #f     #f  #f    #f   #f) ; char?
+    (#f #f #f #f #f      #f       #f  #t     #f  #f    #f   #f) ; pair?
+    (#f #f #f #f #f      #f       #f  #f     #t  #f    #f   #f) ; null?
+    (#f #f #f #f #f      #f       #f  #f     #f  #t    #f   #f) ; procedure?
+    (#f #f #f #f #f      #f       #f  #f     #f  #f    #t   #t)); vector?
+))
+""")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.