Skip to content

Commit a928f14

Browse files
committed
UNFINISHED syntax-extension: Rational float Literal
fixes #54
1 parent 703d34c commit a928f14

File tree

5 files changed

+69
-10
lines changed

5 files changed

+69
-10
lines changed

code/reader/tokens.lisp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
(:ratio-marker #b01000000)
4848
((:short-float-exponent-marker :single-float-exponent-marker
4949
:double-float-exponent-marker :long-float-exponent-marker
50-
:float-exponent-marker)
50+
:float-exponent-marker :custom-float-exponent-marker)
5151
#b10000000)))
5252

5353
(declaim (type (simple-array (unsigned-byte 8) 1) +constituent-traits+))
@@ -77,7 +77,7 @@
7777
(#\> . :alphabetic) ("Oo" . :alphadigit)
7878
(#\? . :alphabetic) ("Pp" . :alphadigit)
7979
(#\@ . :alphabetic) ("Qq" . :alphadigit)
80-
(#\[ . :alphabetic) ("Rr" . :alphadigit)
80+
(#\[ . :alphabetic) ("Rr" . (:alphadigit :custom-float-exponent-marker))
8181
(#\\ . :alphabetic) ("Ss" . (:alphadigit :short-float-exponent-marker))
8282
(#\] . :alphabetic) ("Tt" . :alphadigit)
8383
(#\^ . :alphabetic) ("Uu" . :alphadigit)
@@ -128,13 +128,14 @@
128128
;; *READ-DEFAULT-FLOAT-FORMAT* may be some other type
129129
;; specifier which the implementation chooses to allow.
130130
(t
131-
(if (subtypep default-format 'float)
131+
(if (subtypep default-format 'float) ; TODO maybe use (valid-state-value-p client '*read-default-float-format* default-format)? or is the protocol specified such that values returned by (state-value client '*read-default-float-format*) are by definition valid?
132132
default-format
133133
(values nil default-format))))))
134134
((#\f #\F) 'single-float)
135135
((#\s #\S) 'short-float)
136136
((#\d #\D) 'double-float)
137-
((#\l #\L) 'long-float)))
137+
((#\l #\L) 'long-float)
138+
((#\r #\R) :custom)))
138139

139140
(defmacro with-accumulators ((&rest specs) &body body)
140141
(loop for (name base) in specs
@@ -217,14 +218,14 @@
217218
:report 'use-replacement-float-format))
218219
(setf type 'single-float))
219220
(if exponentp
220-
(make-literal client *float-kind*
221+
(make-literal client float-kind
221222
:type type
222223
:sign sign
223224
:decimal-mantissa (decimal-mantissa)
224225
:exponent-sign exponent-sign
225226
:exponent (exponent)
226227
:decimal-exponent decimal-exponent)
227-
(make-literal client *float-kind*
228+
(make-literal client float-kind
228229
:type type
229230
:sign sign
230231
:decimal-mantissa (decimal-mantissa)

code/syntax-extensions/README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This directory contains source files each of which implements a syntax
44
extension.
55

6-
## Extended package prefix
6+
## Extended Package Prefix Syntax
77

88
Based on an
99
[SBCL extension](https://sbcl.org/manual/index.html#Extended-Package-Prefix-Syntax),
@@ -31,7 +31,7 @@ bar"))
3131
; => cl-user::bar
3232
```
3333

34-
## S-expression comments
34+
## S-expression Comments
3535

3636
A reader macro, `s-expression-comment`, that is loosely based on
3737
[SRFI 62: S-expression comments](https://srfi.schemers.org/srfi-62/srfi-62.html).
@@ -47,3 +47,10 @@ for commenting out multiple arguments or keyword arguments:
4747
While this syntax extension could be implemented as a portable
4848
library, this particular implementation uses Eclector protocols in
4949
order to produce better error messages and parse results.
50+
51+
## Decimal Syntax for Rationals
52+
53+
Based on an
54+
[SBCL extension](https://sbcl.org/manual/index.html#Decimal-Syntax-for-Rationals),
55+
the syntax `12.34R56` can be used to denote a rational number.
56+
TODO what about `*read-default-float-format*`?
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
(cl:defpackage #:eclector.syntax-extensions.rational-float
2+
(:use
3+
#:cl)
4+
5+
(:export
6+
))
7+
8+
(cl:in-package #:eclector.syntax-extensions.rational-float)
9+
10+
(defclass client ()
11+
())
12+
13+
#+TODO (defmethod eclector.reader::reader-float-format (client &optional exponent-marker)
14+
(if (eql exponent-marker #\R)
15+
'rational
16+
(call-next-method)))
17+
18+
(defmethod eclector.reader:make-literal ((client client)
19+
(class eclector.reader::float-kind)
20+
&key type sign decimal-mantissa decimal-exponent
21+
exponent-sign exponent)
22+
(case type
23+
(:custom (* (* sign decimal-mantissa)
24+
(expt 10 (- (* exponent-sign exponent) decimal-exponent))))
25+
(t (call-next-method))))
26+
27+
; eclector.reader::trait->index
28+
29+
(let ((eclector.base:*client* (make-instance 'client)))
30+
(eclector.reader:read-from-string "1.234R2"))
31+
(let ((eclector.base:*client* (make-instance 'client)))
32+
(eclector.reader:call-with-state-value
33+
eclector.base:*client*
34+
(eclector.reader:read-from-string "1R")
35+
'*read-default-float-format* :custom))
36+
;;; 1.234R2 => 617/5 (= 123.4)

eclector.syntax-extensions.asd

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
:components ((:module "syntax-extensions"
1010
:pathname "code/syntax-extensions"
1111
:components ((:file "extended-package-prefix")
12-
(:file "s-expression-comment"))))
12+
(:file "s-expression-comment")
13+
(:file "rational-float"))))
1314

1415
:in-order-to ((test-op (test-op "eclector.syntax-extensions/test"))))
1516

@@ -23,7 +24,8 @@
2324
:serial t
2425
:components ((:file "package")
2526
(:file "extended-package-prefix")
26-
(:file "s-expression-comment"))))
27+
(:file "s-expression-comment")
28+
(:file "rational-float"))))
2729

2830
:perform (test-op (operation component)
2931
(uiop:symbol-call '#:eclector.syntax-extensions.test '#:run-tests)))
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(cl:defpackage #:eclector.syntax-extensions.rational-float.test
2+
(:use
3+
#:cl
4+
#:fiveam))
5+
6+
(cl:in-package #:eclector.syntax-extensions.rational-float.test)
7+
8+
(def-suite* :eclector.syntax-extensions.rational-float
9+
:in :eclector.syntax-extensions)
10+
11+
(test smoke
12+
"TODO"
13+
(error "TODO"))

0 commit comments

Comments
 (0)