summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-01-21 07:38:06 -0800
committerKaz Kylheku <kaz@kylheku.com>2025-01-21 07:38:06 -0800
commit35d1c7f01f6bf2004c048ebecf12132e48454d87 (patch)
tree091e87f1c19bd6099c31c690e9a17977b862123c
parent09dca7b4aabbb22b6febbc5ec1f328abc2fc6a86 (diff)
downloadtxr-35d1c7f01f6bf2004c048ebecf12132e48454d87.tar.gz
txr-35d1c7f01f6bf2004c048ebecf12132e48454d87.tar.bz2
txr-35d1c7f01f6bf2004c048ebecf12132e48454d87.zip
get-csv: use symbols for states.
* csv.tl (get-csv): Since there are only three states, there is no jump table optimization. We might as well use keyword symbols for the states rather than integers.
-rw-r--r--stdlib/csv.tl89
1 files changed, 44 insertions, 45 deletions
diff --git a/stdlib/csv.tl b/stdlib/csv.tl
index c56d2520..f3b4f190 100644
--- a/stdlib/csv.tl
+++ b/stdlib/csv.tl
@@ -28,48 +28,47 @@
(defun get-csv (: (stream *stdin*))
(if (stringp stream)
(upd stream make-string-input-stream))
- (enumlet (rfield qfield quot)
- (let ((record (vec))
- (field (str 0))
- (state rfield)
- (done nil))
- (while (not done)
- (let ((ch (get-char stream)))
- (when (eq ch #\return)
- (let ((ch2 (get-char stream)))
- (if (eq ch2 #\newline)
- (set ch ch2)
- (if ch2
- (unget-char ch2 stream)))))
- (caseql* state
- (rfield (caseql* ch
- (#\newline (vec-push record field)
- (set done t))
- (#\, (vec-push record field)
- (set field (str 0)))
- (#\" (cond
- ((empty field)
- (set state qfield))
- (t
- (string-extend field ch))))
- (nil (vec-push record field)
- (set done t))
- (t (string-extend field ch))))
- (qfield (caseql* ch
- (#\" (set state quot))
- (nil (vec-push record field)
- (set done t))
- (t (string-extend field ch))))
- (quot (caseql* ch
- (#\, (vec-push record field)
- (set field (str 0)
- state rfield))
- (#\" (string-extend field ch)
- (set state qfield))
- (#\newline (vec-push record field)
- (set done t))
- (nil (vec-push record field)
- (set done t))
- (t (string-extend field ch)
- (set state rfield)))))))
- record)))
+ (let ((record (vec))
+ (field (str 0))
+ (state :rfield)
+ (done nil))
+ (while (not done)
+ (let ((ch (get-char stream)))
+ (when (eq ch #\return)
+ (let ((ch2 (get-char stream)))
+ (if (eq ch2 #\newline)
+ (set ch ch2)
+ (if ch2
+ (unget-char ch2 stream)))))
+ (caseq state
+ (:rfield (caseql* ch
+ (#\newline (vec-push record field)
+ (set done t))
+ (#\, (vec-push record field)
+ (set field (str 0)))
+ (#\" (cond
+ ((empty field)
+ (set state :qfield))
+ (t
+ (string-extend field ch))))
+ (nil (vec-push record field)
+ (set done t))
+ (t (string-extend field ch))))
+ (:qfield (caseql* ch
+ (#\" (set state :quot))
+ (nil (vec-push record field)
+ (set done t))
+ (t (string-extend field ch))))
+ (:quot (caseql* ch
+ (#\, (vec-push record field)
+ (set field (str 0)
+ state :rfield))
+ (#\" (string-extend field ch)
+ (set state :qfield))
+ (#\newline (vec-push record field)
+ (set done t))
+ (nil (vec-push record field)
+ (set done t))
+ (t (string-extend field ch)
+ (set state :rfield)))))))
+ record))