Skip to content
This repository has been archived by the owner on Dec 29, 2018. It is now read-only.

Commit

Permalink
Refactor constructor pattern parser/compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomohiro Matsuyama committed Nov 17, 2012
1 parent 5fb0dc6 commit 24af190
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 332 deletions.
92 changes: 46 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -43,6 +41,8 @@ specifiers are defined as follows:

and-pattern ::= (and PATTERN*)

constructor-pattern ::= (NAME ARG*)

derived-pattern ::= (NAME PATTERN*)

### Constant-Pattern
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
23 changes: 16 additions & 7 deletions contrib/ppcre.lisp
Original file line number Diff line number Diff line change
@@ -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))))
92 changes: 46 additions & 46 deletions optima.asd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -42,6 +40,8 @@ specifiers are defined as follows:
and-pattern ::= (and PATTERN*)
constructor-pattern ::= (NAME ARG*)
derived-pattern ::= (NAME PATTERN*)
### Constant-Pattern
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 24af190

Please sign in to comment.