Permalink
Browse files

Ready I guess?

  • Loading branch information...
1 parent 0e4bf89 commit b8213f6d050175a050c249cc37bce51d6d6e0fe0 @Hexstream committed Oct 13, 2012
Showing with 60 additions and 8 deletions.
  1. +4 −4 README
  2. +51 −0 main.lisp
  3. +2 −1 package.lisp
  4. +3 −3 parse-number-range.asd
View
8 README
@@ -1,10 +1,10 @@
Project's home: http://www.hexstreamsoft.com/projects/parse-number-range/
-Parses LOOP's somewhat complicated number range (for-as-arithmetic)
-syntax into 5 simple values: from, to, by, direction (incf or decf)
-and bound-type (:inclusive or :exclusive). Intended for easy
-implementation of similar functionality in other (saner?) constructs.
+Parses LOOP's convenient "for-as-arithmetic" syntax into 5 simple
+values: from, to, limit-kind (:inclusive, :exclusive
+or nil if unbounded), by (step) and direction (+ or -)). Intended for
+easy implementation of analogous functionality in other constructs.
This library is in the Public Domain.
View
@@ -1,2 +1,53 @@
(in-package #:parse-number-range)
+(defun parse (range &aux
+ (from 0) from-p
+ (to nil) to-p
+ (by 1) by-p
+ direction (limit-kind :unbounded))
+ '(values from to limit-kind step direction)
+ (flet ((direction (new-direction)
+ (if direction
+ (unless (eq direction new-direction)
+ (error "Conflicting directions: ~S and ~S."
+ direction new-direction))
+ (setf direction new-direction)))
+ (limit-kind (new-limit-kind)
+ (if (not (eq limit-kind :unbounded))
+ (unless (eq limit-kind new-limit-kind)
+ (error "Conflicting limit-kinds: ~S and ~S."
+ limit-kind new-limit-kind))
+ (setf limit-kind new-limit-kind)))
+ (duplicate (type)
+ (error "Duplicate ~A specification in range ~S."
+ type range)))
+ (do ((tail range (cddr tail)))
+ ((endp tail) (values from to limit-kind by (or direction '+)))
+ (destructuring-bind (key value &rest rest) tail
+ (declare (ignore rest))
+ (ecase key
+ ((:from :downfrom :upfrom)
+ (when from-p
+ (duplicate "FROM"))
+ (setf from value
+ from-p t)
+ (ecase key
+ (:from)
+ (:downfrom (direction '-))
+ (:upfrom (direction '+))))
+ ((:to :downto :upto :below :above)
+ (when to-p
+ (duplicate "TO"))
+ (setf to value
+ to-p t)
+ (ecase key
+ (:to (limit-kind :inclusive))
+ (:downto (direction '-) (limit-kind :inclusive))
+ (:upto (direction '+) (limit-kind :inclusive))
+ (:below (direction '+) (limit-kind :exclusive))
+ (:above (direction '-) (limit-kind :exclusive))))
+ (:by
+ (when by-p
+ (duplicate "BY"))
+ (setf by value
+ by-p t)))))))
View
@@ -1,2 +1,3 @@
(cl:defpackage #:parse-number-range
- (:use #:cl))
+ (:use #:cl)
+ (:export #:parse))
View
@@ -5,9 +5,9 @@
;; See the UNLICENSE file for details.
:license "Public Domain"
- :description "Parses LOOP's somewhat complicated number range (for-as-arithmetic) syntax into 5 simple values: from, to, by, direction (incf or decf) and bound-type (:inclusive or :exclusive). Intended for easy implementation of similar functionality in other (saner?) constructs."
-
- :version "0.1"
+ :description "Parses LOOP's convenient \"for-as-arithmetic\" syntax into 5 simple values: from, to, limit-kind (:inclusive, :exclusive or nil if unbounded), by (step) and direction (+ or -)). Intended for easy implementation of analogous functionality in other constructs."
+
+ :version "1.0"
:serial cl:t
:components ((:file "package")
(:file "main")))

0 comments on commit b8213f6

Please sign in to comment.