-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPattern.ts
54 lines (51 loc) · 1.62 KB
/
Pattern.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { Matcher } from './Matcher';
export abstract class Pattern {
public abstract toString(parentheses: boolean): string;
public abstract get(index: number): number;
public shift(shiftAmount: number): Pattern {
return new ShiftedPattern(this, shiftAmount);
}
}
/**
* Pattern factories are responsible for creating patterns according to query.
* The entire query process can take multiple stage to finish. Thus, the
* factories' query functions should be generators so the query process can be
* splitted.
* The iterator of the generator should be able to return one of true values.
* - A pattern, if that pattern matches the query.
* - Null, if this step did not yield any meaningful result.
*/
export abstract class PatternFactory {
public abstract identifier: string;
public abstract querySequence(
matcher: Matcher,
sequence: Array<number>,
): Iterator<undefined | Pattern>;
}
export class ShiftedPattern extends Pattern {
public constructor(
public originalPattern: Pattern,
public shiftAmount: number,
) {
super();
}
public toString(parentheses: boolean): string {
if (this.shiftAmount === 0) {
return this.originalPattern.toString(parentheses);
}
let result = this.originalPattern.toString(true) + '<<' + this.shiftAmount;
if (parentheses) {
result = '(' + result + ')';
}
return result;
}
public get(index: number): number {
return this.originalPattern.get(index + this.shiftAmount);
}
public shift(shiftAmount: number): Pattern {
return new ShiftedPattern(
this.originalPattern,
this.shiftAmount + shiftAmount,
);
}
}