@@ -7,23 +7,25 @@ use crate::transpiler::re;
77
88#[ derive( Debug ) ]
99pub struct Parser {
10- pub stack : Vec < lexer :: Token > ,
10+ pub records : Vec < usize > ,
1111 pub results : Vec < Contents > ,
12- pub previous : Previous ,
12+ pub previous : Record ,
1313 pub contains_code_block : bool ,
1414}
1515
16- #[ derive( Debug ) ]
16+ #[ derive( Debug , Clone ) ]
1717pub struct Contents {
1818 pub line : Option < String > ,
1919 pub kind : lexer:: Token ,
20+ pub indent_level : usize ,
2021 pub chron : Chronology ,
2122}
2223
2324#[ derive( Debug ) ]
24- pub struct Previous {
25+ pub struct Record {
2526 pub kind : lexer:: Token ,
2627 pub chron : Chronology ,
28+ pub indent_level : usize ,
2729}
2830
2931#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
@@ -34,73 +36,103 @@ pub enum Chronology {
3436 None ,
3537}
3638
37- impl From < & Contents > for Previous {
39+ impl From < & Contents > for Record {
3840 fn from ( contents : & Contents ) -> Self {
39- Previous {
41+ Record {
4042 kind : contents. kind ,
4143 chron : contents. chron ,
44+ indent_level : contents. indent_level ,
4245 }
4346 }
4447}
4548
4649impl Contents {
47- fn new ( line : Option < String > , kind : lexer:: Token , chron : Chronology ) -> Self {
48- Contents { line, kind, chron }
50+ fn new ( info : lexer:: Info , chron : Chronology ) -> Self {
51+ Contents {
52+ line : info. line ,
53+ kind : info. token ,
54+ indent_level : info. indent_level ,
55+ chron,
56+ }
57+ }
58+
59+ fn new_with_line ( line : Option < String > , info : lexer:: Info , chron : Chronology ) -> Self {
60+ Contents {
61+ line,
62+ kind : info. token ,
63+ indent_level : info. indent_level ,
64+ chron,
65+ }
4966 }
5067}
5168
5269impl Parser {
5370 pub fn new ( ) -> Parser {
54- let stack : Vec < lexer :: Token > = Vec :: new ( ) ;
55- let previous = Previous {
71+ let records : Vec < usize > = Vec :: new ( ) ;
72+ let previous = Record {
5673 kind : Token :: FileStart ,
5774 chron : Chronology :: None ,
75+ indent_level : 0 ,
5876 } ;
5977 let results: Vec < Contents > = Vec :: new ( ) ;
6078 let contains_code_block = false ;
6179 Parser {
62- stack ,
80+ records ,
6381 results,
6482 previous,
6583 contains_code_block,
6684 }
6785 }
6886
6987 pub fn run ( & mut self , lexer : lexer:: Lexer ) {
70- if lexer. results . iter ( ) . any ( |item| item. token == Token :: CodeBlock ) {
88+ if lexer
89+ . results
90+ . iter ( )
91+ . any ( |item| item. token == Token :: CodeBlock )
92+ {
7193 self . contains_code_block = true ;
7294 }
7395
74- let mut iter = lexer. results . into_iter ( ) . peekable ( ) ;
96+ let mut iter = lexer. results . into_iter ( ) . enumerate ( ) . peekable ( ) ;
7597 while let Some ( item) = iter. next ( ) {
76- let current = item;
77- if current. token == Token :: Blank {
78- continue
79- }
80- else if let Some ( next) = iter. peek ( ) {
98+ let ( number, current) = item;
99+ if let Some ( ( _, next) ) = iter. peek ( ) {
81100 if lexer:: Lexer :: is_group ( & current. token ) {
82101 if let Some ( contents) = self . group_to_contents ( current, next) {
83- self . previous = Previous :: from ( & contents) ;
102+ // Keep track of the indices of the open groups in results
103+ if contents. chron == Chronology :: Start {
104+ self . records . push ( number) ;
105+ } else if contents. chron == Chronology :: End {
106+ self . records . pop ( ) ;
107+ }
108+
109+ self . previous = Record :: from ( & contents) ;
84110 self . results . push ( contents) ;
85111 }
86112 } else {
87- let contents = Contents :: new (
88- current. line ,
89- current. token ,
90- Chronology :: None ,
91- ) ;
92- self . previous = Previous :: from ( & contents) ;
113+ // Close open blocks up to that point since interrupted
114+ for record in self . records . iter ( ) {
115+ let contents = self . results . get ( * record) . unwrap ( ) ;
116+ self . results . push ( Contents {
117+ line : None ,
118+ kind : contents. kind ,
119+ chron : Chronology :: End ,
120+ indent_level : contents. indent_level ,
121+ } ) ;
122+ }
123+ self . records . clear ( ) ;
124+ let contents = Contents :: new ( current, Chronology :: None ) ;
125+ self . previous = Record :: from ( & contents) ;
93126 self . results . push ( contents) ;
94127 }
95- } else {
96- self . results . push ( Contents :: new (
97- None ,
98- current. token ,
99- Chronology :: None ,
100- ) ) ;
101128 }
102- println ! ( "{:?}" , self . previous) ;
103129 }
130+ self . results . push ( Contents {
131+ line : None ,
132+ kind : Token :: FileEnd ,
133+ indent_level : 0 ,
134+ chron : Chronology :: None ,
135+ } ) ;
104136 }
105137
106138 fn group_to_contents ( & self , current : lexer:: Info , next : & lexer:: Info ) -> Option < Contents > {
@@ -111,28 +143,39 @@ impl Parser {
111143 if let Token :: CodeBlock = current. token {
112144 if let Some ( language) = re:: replace_code_block ( current. line . as_ref ( ) . map ( |x| & * * x) ) {
113145 let mut language = language;
114- if code_blocks:: is_invalid_language ( & language)
115- {
146+ if code_blocks:: is_invalid_language ( & language) {
116147 eprintln ! (
117148 "Language \" {}\" not found. Using default of \" python\" ." ,
118149 language
119150 ) ;
120151 language = "python" . to_string ( ) ;
121152 } ;
122- return Some ( Contents :: new ( Some ( language) , current. token , Chronology :: Start ) )
153+ return Some ( Contents :: new_with_line (
154+ Some ( language) ,
155+ current,
156+ Chronology :: Start ,
157+ ) ) ;
123158 } else {
124- return Some ( Contents :: new ( current. line , current . token , Chronology :: End ) )
159+ return Some ( Contents :: new ( current, Chronology :: End ) ) ;
125160 }
161+ } else if current. indent_level > self . previous . indent_level
162+ && current. indent_level > next. indent_level
163+ {
164+ return Some ( Contents :: new ( current, Chronology :: None ) ) ;
165+ } else if current. indent_level > self . previous . indent_level {
166+ return Some ( Contents :: new ( current, Chronology :: Start ) ) ;
167+ } else if current. indent_level > next. indent_level {
168+ return Some ( Contents :: new ( current, Chronology :: End ) ) ;
126169 } else if token_discrim != prev_discrim && token_discrim != next_discrim {
127- return Some ( Contents :: new ( current. line , current . token , Chronology :: None ) ) ;
170+ return Some ( Contents :: new ( current, Chronology :: None ) ) ;
128171 } else if token_discrim != next_discrim {
129- return Some ( Contents :: new ( current. line , current . token , Chronology :: End ) ) ;
172+ return Some ( Contents :: new ( current, Chronology :: End ) ) ;
130173 } else if token_discrim != prev_discrim
131- || ( token_discrim == prev_discrim && self . previous . chron == Chronology :: End )
174+ // || (token_discrim == prev_discrim && self.previous.chron == Chronology::End)
132175 {
133- return Some ( Contents :: new ( current. line , current . token , Chronology :: Start ) ) ;
176+ return Some ( Contents :: new ( current, Chronology :: Start ) ) ;
134177 } else if token_discrim == prev_discrim && token_discrim == next_discrim {
135- return Some ( Contents :: new ( current. line , current . token , Chronology :: Middle ) ) ;
178+ return Some ( Contents :: new ( current, Chronology :: Middle ) ) ;
136179 }
137180 None
138181 }
0 commit comments