diff --git a/PRIMITIVES.md b/PRIMITIVES.md index b86bc33..ef22df7 100644 --- a/PRIMITIVES.md +++ b/PRIMITIVES.md @@ -70,6 +70,7 @@ Note that functions have their names mangled a little bit ("-" is converted to " * Type checking functions: * `char?`, `cons?`, `float?`, `int?`, `lambda?`, `nil?`, and `str?`. + * The `numeric?` primitive will return true for ints, floats, and characters. * mathematical operations `*`, `+`, `-`, and `/`. * These work against integers, floating point numbers, or mixed operands. * (Integer) comparison operations diff --git a/compiler/compiler.go b/compiler/compiler.go index f9ca940..dc79ef7 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -270,6 +270,8 @@ func (c *Compiler) asmName(name string) string { return "lambdap" case "nil?": return "nilp" + case "numeric?": + return "numericp" case "str?": return "strp" } diff --git a/compiler/template.tmpl b/compiler/template.tmpl index a7f335b..c6cb9f4 100644 --- a/compiler/template.tmpl +++ b/compiler/template.tmpl @@ -242,6 +242,23 @@ strp: jmp is_type +;; numeric? +numericp: + mov rax, rdi + GET_TAG_BITS rax + call is_numeric + cmp rax, 0 + jnz .true +.nil: + xor rax, rax + TAG_NIL_REG rax + ret +.true: + mov rax, 1 + TAG_INTEGER_REG rax + ret + + ;; Internal helper is_numeric: cmp rax,TAG_ID_INTEGER diff --git a/test/numeric.lisp b/test/numeric.lisp new file mode 100644 index 0000000..1d24cff --- /dev/null +++ b/test/numeric.lisp @@ -0,0 +1,8 @@ +(defun main () + (println (numeric? 3)) + (println (numeric? 3.0)) + (println (numeric? #\a)) + (println (numeric? (lambda (x) x))) + (println (numeric? nil)) + (println (numeric? (list 3 4 ))) + (println (numeric? "string"))) diff --git a/test/numeric.test.expected b/test/numeric.test.expected new file mode 100644 index 0000000..b7dda17 --- /dev/null +++ b/test/numeric.test.expected @@ -0,0 +1,7 @@ +1 +1 +1 + + + +