From 54b0f2ea841d2ce3895713415481271aa3034b30 Mon Sep 17 00:00:00 2001 From: nea Date: Tue, 15 Aug 2023 20:24:01 +0200 Subject: Add support for hex literals --- res/builtins.lisp | 3 +++ res/stdtest.lisp | 7 +++++++ src/LispParser.kt | 10 +++++++--- test/res/test.lisp | 6 ++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/res/builtins.lisp b/res/builtins.lisp index 64c59d3..19bab1f 100644 --- a/res/builtins.lisp +++ b/res/builtins.lisp @@ -28,6 +28,9 @@ (defun gt (l r) (lt r l)) (export gt) +(comment "The absolute value returns the argument if it is non negative or (- 0 arg) if it is") +(defun abs (arg) (if (lt arg 0) (- 0 arg) arg)) +(export abs) (comment "if! a strict version of a regular if, meaning it evaluates both the falsy and the truthy case, instead of only one.") (defun if! (cond ifTrue ifFalse) (if cond ifTrue ifFalse)) diff --git a/res/stdtest.lisp b/res/stdtest.lisp index 42f9c94..b7553fa 100644 --- a/res/stdtest.lisp +++ b/res/stdtest.lisp @@ -20,3 +20,10 @@ (= actual expected) (stringify "Expected" expected "got" actual))) (export test.assert-eq) + +(comment "Assert that two number arguments are equal with some tolerance. Returns a closure") +(defun test.assert-eqd (actual expected tolerance) (seq + (test.assert + (lt (abs (- expected actual)) tolerance) + (stringify "Expected" expected "got" actual "with a tolerance of" tolerance)))) +(export test.assert-eqd) diff --git a/src/LispParser.kt b/src/LispParser.kt index e005c2d..3341779 100644 --- a/src/LispParser.kt +++ b/src/LispParser.kt @@ -15,6 +15,7 @@ class LispParser private constructor(filename: String, string: String) { } val digits = "1234567890" + val hexDigits = digits + "abcdefABCDEF" val alphabet = "abcdefghijklmnopqrstuvwxyz" val validStartingIdentifiers = "-.#+*'!$%&/=?_~|^" + alphabet + alphabet.uppercase() val validIdentifiers = validStartingIdentifiers + digits @@ -62,11 +63,14 @@ class LispParser private constructor(filename: String, string: String) { fun parseNumber(): LispAst.NumberLiteral { val start = racer.idx racer.pushState() - val number = racer.consumeWhile { it.last().let { it in digits || it == '.' } } - val double = number.toDoubleOrNull() + val number = racer.consumeWhile { it.last().let { it in hexDigits || it == '.' || it == 'x' } } + var double = number.toDoubleOrNull() + if (number.startsWith("0x")) { + double = number.substring(2).toLong(16).toDouble() + } if (double == null) { racer.popState() - racer.error("Could not parse number") + racer.error("Could not parse number $number") } racer.discardState() return LispAst.NumberLiteral(racer.span(start), double) diff --git a/test/res/test.lisp b/test/res/test.lisp index b5a9f65..39c6d82 100644 --- a/test/res/test.lisp +++ b/test/res/test.lisp @@ -30,3 +30,9 @@ ((test.assert-eq (hash.get funnyhash :tesst3) nil)) )) +(test.test "Hex literals" (seq + ((test.assert-eqd 0x0 0 0.0001)) + ((test.assert-eqd 0xFF 255 0.0001)) + ((test.assert-eqd 0xFFFFFFFF 4294967295 0.0001)) + )) + -- cgit