Permalink
Browse files

Refactor constructor pattern parser/compiler

  • Loading branch information...
1 parent 5fb0dc6 commit 24af190ca372a6f52b726cc30d0e9b4a9aa63e80 Tomohiro Matsuyama committed Nov 17, 2012
Showing with 484 additions and 332 deletions.
  1. +46 −46 README.md
  2. +16 −7 contrib/ppcre.lisp
  3. +46 −46 optima.asd
  4. +50 −51 src/compiler.lisp
  5. +313 −179 src/pattern.lisp
  6. +8 −2 src/runtime.lisp
  7. +5 −1 test/suite.lisp
View
@@ -18,11 +18,11 @@ specifiers are defined as follows:
pattern-specifier ::= constant-pattern
| variable-pattern
| place-pattern
- | constructor-pattern
| guard-pattern
| not-pattern
| or-pattern
| and-pattern
+ | constructor-pattern
| derived-pattern
constant-pattern ::= t | nil
@@ -33,8 +33,6 @@ specifiers are defined as follows:
place-pattern ::= (place SYMBOL)
- constructor-pattern ::= (NAME ARG*)
-
guard-pattern ::= (guard PATTERN TEST-FORM)
not-pattern ::= (not PATTERN)
@@ -43,6 +41,8 @@ specifiers are defined as follows:
and-pattern ::= (and PATTERN*)
+ constructor-pattern ::= (NAME ARG*)
+
derived-pattern ::= (NAME PATTERN*)
### Constant-Pattern
@@ -82,6 +82,49 @@ Examples:
c
=> (2 . 2)
+### Guard-Pattern
+
+A guard-pattern is a special pattern that also tests whether TEST-FORM
+satisfies in the current matching context.
+
+Examples:
+
+ (match 1 ((guard x (eql x 2)) t))
+ => NIL
+ (match 1 ((guard x (eql x 1)) t))
+ => T
+
+### Not-Pattern
+
+A not-pattern matches a value that is not matched with sub-PATTERN.
+
+Examples:
+
+ (match 1 ((not 2) 3)) => 3
+ (match 1 ((not (not 1)) 1)) => 1
+
+### Or-Pattern
+
+An or-pattern matches a value that is matched with one of
+sub-PATTERNs. There is a restriction that every pattern of
+sub-PATTERNs must have same set of variables.
+
+Examples:
+
+ (match '(2 . 1) ((or (cons 1 x) (cons 2 x)) x))
+ => 1
+
+### And-Pattern
+
+An and-pattern matches a value that is matched with all of
+sub-PATTERNs. The most common use case is to match a value and bind
+the value to a variable.
+
+Examples:
+
+ (match 1 ((and 1 x) x))
+ => 1
+
### Constructor-Pattern
A constructor-pattern matches not a value itself but a structure of
@@ -222,49 +265,6 @@ Examples:
((p- name age) (list name age)))
=> ("foo" 30)
-### Guard-Pattern
-
-A guard-pattern is a special pattern that also tests whether TEST-FORM
-satisfies in the current matching context.
-
-Examples:
-
- (match 1 ((guard x (eql x 2)) t))
- => NIL
- (match 1 ((guard x (eql x 1)) t))
- => T
-
-### Not-Pattern
-
-A not-pattern matches a value that is not matched with sub-PATTERN.
-
-Examples:
-
- (match 1 ((not 2) 3)) => 3
- (match 1 ((not (not 1)) 1)) => 1
-
-### Or-Pattern
-
-An or-pattern matches a value that is matched with one of
-sub-PATTERNs. There is a restriction that every pattern of
-sub-PATTERNs must have same set of variables.
-
-Examples:
-
- (match '(2 . 1) ((or (cons 1 x) (cons 2 x)) x))
- => 1
-
-### And-Pattern
-
-An and-pattern matches a value that is matched with all of
-sub-PATTERNs. The most common use case is to match a value and bind
-the value to a variable.
-
-Examples:
-
- (match 1 ((and 1 x) x))
- => 1
-
### Derived-Pattern
A derived-pattern is a pattern that is defined with DEFPATTERN. There
View
@@ -1,10 +1,19 @@
(in-package :optima.contrib)
+(defstruct (ppcre-pattern (:include optima::constructor-pattern)
+ (:constructor make-ppcre-pattern (regex &rest subpatterns)))
+ regex)
+
+(defmethod optima::destructor-equal ((x ppcre-pattern) (y ppcre-pattern))
+ (equal (ppcre-pattern-regex x) (ppcre-pattern-regex y)))
+
+(defmethod optima::destructor-predicate-form ((pattern ppcre-pattern) var)
+ (values `(nth-value 1 (ppcre:scan-to-strings ,(ppcre-pattern-regex pattern) ,var)) t))
+
+(defmethod optima::destructor-forms ((pattern ppcre-pattern) var)
+ (loop for i from 0 below (optima::constructor-pattern-arity pattern)
+ collect `(optima::%svref ,var ,i)))
+
(defmethod optima::parse-constructor-pattern ((name (eql 'ppcre)) &rest args)
- (destructuring-bind (re . patterns) args
- (optima::make-constructor-pattern
- :specifier `(ppcre ,@args)
- :signature `(ppcre ,re)
- :arguments (mapcar #'optima::parse-pattern patterns)
- :predicate (lambda (var) (values `(nth-value 1 (ppcre:scan-to-strings ,re ,var)) t))
- :accessor (lambda (var i) `(svref ,var ,i)))))
+ (apply #'make-ppcre-pattern (first args)
+ (mapcar #'optima::parse-pattern (rest args))))
View
@@ -17,11 +17,11 @@ specifiers are defined as follows:
pattern-specifier ::= constant-pattern
| variable-pattern
| place-pattern
- | constructor-pattern
| guard-pattern
| not-pattern
| or-pattern
| and-pattern
+ | constructor-pattern
| derived-pattern
constant-pattern ::= t | nil
@@ -32,8 +32,6 @@ specifiers are defined as follows:
place-pattern ::= (place SYMBOL)
- constructor-pattern ::= (NAME ARG*)
-
guard-pattern ::= (guard PATTERN TEST-FORM)
not-pattern ::= (not PATTERN)
@@ -42,6 +40,8 @@ specifiers are defined as follows:
and-pattern ::= (and PATTERN*)
+ constructor-pattern ::= (NAME ARG*)
+
derived-pattern ::= (NAME PATTERN*)
### Constant-Pattern
@@ -81,6 +81,49 @@ Examples:
c
=> (2 . 2)
+### Guard-Pattern
+
+A guard-pattern is a special pattern that also tests whether TEST-FORM
+satisfies in the current matching context.
+
+Examples:
+
+ (match 1 ((guard x (eql x 2)) t))
+ => NIL
+ (match 1 ((guard x (eql x 1)) t))
+ => T
+
+### Not-Pattern
+
+A not-pattern matches a value that is not matched with sub-PATTERN.
+
+Examples:
+
+ (match 1 ((not 2) 3)) => 3
+ (match 1 ((not (not 1)) 1)) => 1
+
+### Or-Pattern
+
+An or-pattern matches a value that is matched with one of
+sub-PATTERNs. There is a restriction that every pattern of
+sub-PATTERNs must have same set of variables.
+
+Examples:
+
+ (match '(2 . 1) ((or (cons 1 x) (cons 2 x)) x))
+ => 1
+
+### And-Pattern
+
+An and-pattern matches a value that is matched with all of
+sub-PATTERNs. The most common use case is to match a value and bind
+the value to a variable.
+
+Examples:
+
+ (match 1 ((and 1 x) x))
+ => 1
+
### Constructor-Pattern
A constructor-pattern matches not a value itself but a structure of
@@ -221,49 +264,6 @@ Examples:
((p- name age) (list name age)))
=> (\"foo\" 30)
-### Guard-Pattern
-
-A guard-pattern is a special pattern that also tests whether TEST-FORM
-satisfies in the current matching context.
-
-Examples:
-
- (match 1 ((guard x (eql x 2)) t))
- => NIL
- (match 1 ((guard x (eql x 1)) t))
- => T
-
-### Not-Pattern
-
-A not-pattern matches a value that is not matched with sub-PATTERN.
-
-Examples:
-
- (match 1 ((not 2) 3)) => 3
- (match 1 ((not (not 1)) 1)) => 1
-
-### Or-Pattern
-
-An or-pattern matches a value that is matched with one of
-sub-PATTERNs. There is a restriction that every pattern of
-sub-PATTERNs must have same set of variables.
-
-Examples:
-
- (match '(2 . 1) ((or (cons 1 x) (cons 2 x)) x))
- => 1
-
-### And-Pattern
-
-An and-pattern matches a value that is matched with all of
-sub-PATTERNs. The most common use case is to match a value and bind
-the value to a variable.
-
-Examples:
-
- (match 1 ((and 1 x) x))
- => 1
-
### Derived-Pattern
A derived-pattern is a pattern that is defined with DEFPATTERN. There
Oops, something went wrong.

0 comments on commit 24af190

Please sign in to comment.