2
2
//SPDX-License-Identifier: BSD-3-Clause
3
3
4
4
use crate :: elements:: subword:: Subword ;
5
- use crate :: elements :: word :: Word ;
5
+ use super :: Word ;
6
6
7
7
fn after_dollar ( s : & str ) -> bool {
8
8
s == "$" || s == "$$"
@@ -14,21 +14,19 @@ pub fn eval(word: &mut Word) -> Vec<Word> {
14
14
let mut skip_until = 0 ;
15
15
for i in open_brace_pos ( word) {
16
16
if i < skip_until { //ブレース展開の終わりまで処理をスキップ
17
- continue ;
17
+ continue ;
18
18
}
19
19
20
- if let Some ( d) = parse ( & word. subwords [ i..] ) {
21
- let shift_d: Vec < usize > = d. iter ( ) . map ( |e| e+i) . collect ( ) ;
22
-
23
- if i > 0 && after_dollar ( word. subwords [ i-1 ] . get_text ( ) ) {
24
- skip_until = * shift_d. last ( ) . unwrap ( ) ;
25
- continue ;
26
- }
20
+ let d = parse ( & word. subwords [ i..] , i) ;
21
+ if d. len ( ) <= 2 {
22
+ continue ;
23
+ }
27
24
28
- return expand ( & word. subwords , & shift_d) ;
25
+ match i > 0 && after_dollar ( word. subwords [ i-1 ] . get_text ( ) ) {
26
+ true => skip_until = * d. last ( ) . unwrap ( ) ,
27
+ false => return expand ( & word. subwords , & d) ,
29
28
}
30
29
}
31
-
32
30
vec ! [ word. clone( ) ]
33
31
}
34
32
@@ -52,56 +50,43 @@ fn open_brace_pos(w: &Word) -> Vec<usize> {
52
50
. collect ( )
53
51
}
54
52
55
- pub fn parse ( subwords : & [ Box < dyn Subword > ] ) -> Option < Vec < usize > > {
53
+ fn parse ( subwords : & [ Box < dyn Subword > ] , start : usize ) -> Vec < usize > {
56
54
let mut stack = vec ! [ ] ;
57
55
for sw in subwords {
58
- stack. push ( Some ( sw. get_text ( ) ) ) ;
56
+ stack. push ( sw. get_text ( ) ) ;
59
57
if sw. get_text ( ) == "}" {
60
- match get_delimiters ( & mut stack) {
61
- Some ( ds ) => return Some ( ds ) ,
62
- _ => { } ,
58
+ let ds = get_delimiters ( & mut stack, start ) ;
59
+ if ds . len ( ) > 2 {
60
+ return ds ;
63
61
}
64
62
}
65
63
}
66
- None
64
+ vec ! [ ]
67
65
}
68
66
69
- fn get_delimiters ( stack : & mut Vec < Option < & str > > ) -> Option < Vec < usize > > {
70
- let mut comma_pos = vec ! [ ] ;
67
+ fn get_delimiters ( stack : & mut Vec < & str > , start : usize ) -> Vec < usize > {
68
+ let mut delimiter_pos = vec ! [ start , stack . len ( ) - 1 +start ] ;
71
69
for i in ( 1 ..stack. len ( ) -1 ) . rev ( ) {
72
- if stack[ i] == Some ( "," ) {
73
- comma_pos . push ( i) ;
74
- } else if stack[ i] == Some ( "{" ) { // find an inner brace expcomma_posion
75
- stack[ i..] . iter_mut ( ) . for_each ( |e| * e = None ) ;
76
- return None ;
70
+ if stack[ i] == "," {
71
+ delimiter_pos . insert ( 1 , start+ i) ;
72
+ } else if stack[ i] == "{" { // find an inner brace expcomma_posion
73
+ stack[ i..] . iter_mut ( ) . for_each ( |e| * e = "" ) ;
74
+ return vec ! [ ] ;
77
75
}
78
76
}
79
-
80
- if comma_pos. len ( ) > 0 {
81
- comma_pos. reverse ( ) ;
82
- comma_pos. insert ( 0 , 0 ) ; // add "{" pos
83
- comma_pos. push ( stack. len ( ) -1 ) ; // add "}" pos
84
- Some ( comma_pos)
85
- } else {
86
- None
87
- }
77
+ delimiter_pos
88
78
}
89
79
90
- pub fn expand ( subwords : & Vec < Box < dyn Subword > > , delimiters : & Vec < usize > ) -> Vec < Word > {
80
+ fn expand ( subwords : & Vec < Box < dyn Subword > > , delimiters : & Vec < usize > ) -> Vec < Word > {
91
81
let left = & subwords[ ..delimiters[ 0 ] ] ;
92
82
let mut right = subwords[ ( delimiters. last ( ) . unwrap ( ) +1 ) ..] . to_vec ( ) ;
93
83
invalidate_brace ( & mut right) ;
94
84
95
85
let mut ans = vec ! [ ] ;
96
- let mut from = delimiters[ 0 ] + 1 ;
97
- for to in & delimiters[ 1 ..] {
98
- let mut w = Word :: new ( ) ;
99
- w. subwords . extend ( left. to_vec ( ) ) ;
100
- w. subwords . extend ( subwords[ from..* to] . to_vec ( ) ) ;
101
- w. subwords . extend ( right. to_vec ( ) ) ;
102
- w. text = w. subwords . iter ( ) . map ( |s| s. get_text ( ) ) . collect ( ) ;
86
+ for i in 0 ..( delimiters. len ( ) -1 ) {
87
+ let center = & subwords[ ( delimiters[ i] +1 ) ..delimiters[ i+1 ] ] ;
88
+ let mut w = Word :: new ( [ left, & center, & right ] . concat ( ) ) ;
103
89
ans. append ( & mut eval ( & mut w) ) ;
104
- from = * to + 1 ;
105
90
}
106
91
ans
107
92
}
0 commit comments