@@ -13,40 +13,80 @@ use crate::parser::{repr_option, repr_vec};
1313#[ derive( Debug , PartialEq ) ]
1414pub enum ControlFlowNode {
1515 /// Keyword expects a node: `return 3+4`
16- Ast ( ControlFlowKeyword , Box < Ast > ) ,
16+ Ast ( ControlFlowKeyword , Box < Ast > , bool ) ,
1717 /// Keyword expects a colon and a node: `goto: label`
18- ColonAst ( ControlFlowKeyword , Option < Box < Ast > > ) ,
18+ ColonAst ( ControlFlowKeyword , Option < Box < Ast > > , bool ) ,
1919 /// Keyword expects another control flow: `typedef struct`
2020 ControlFlow ( ControlFlowKeyword , Option < Box < ControlFlowNode > > ) ,
2121 /// Keyword expects an identifier and a braced block: `struct Blob {}`
2222 IdentBlock ( ControlFlowKeyword , Option < String > , Option < BracedBlock > ) ,
2323 /// Keyword expects a parenthesised block and a braced block: `switch (cond)
2424 /// {};`
25- ParensBlock ( ControlFlowKeyword , Option < ParensBlock > , Option < BracedBlock > ) ,
25+ ParensBlock ( ControlFlowKeyword , Option < ParensBlock > , Box < Ast > , bool ) ,
2626 /// Keyword expects a semicolon: `break;`
2727 SemiColon ( ControlFlowKeyword ) ,
2828}
2929
3030impl ControlFlowNode {
31+ /// Sets the control flow to full
32+ pub fn fill ( & mut self ) {
33+ match self {
34+ Self :: Ast ( .., full) | Self :: ColonAst ( .., full) | Self :: ParensBlock ( .., full) => {
35+ * full = true ;
36+ }
37+ Self :: ControlFlow ( ..) | Self :: IdentBlock ( ..) | Self :: SemiColon ( ..) => ( ) ,
38+ }
39+ }
40+
41+ /// Function to return an [`Ast`], if exists
42+ pub const fn get_ast ( & mut self ) -> Option < & mut Box < Ast > > {
43+ match self {
44+ Self :: ColonAst ( _, Some ( ast) , false )
45+ | Self :: ParensBlock ( .., ast, false )
46+ | Self :: Ast ( _, ast, false ) => Some ( ast) ,
47+ Self :: ControlFlow ( ..)
48+ | Self :: IdentBlock ( ..)
49+ | Self :: SemiColon ( _)
50+ | Self :: ParensBlock ( .., true )
51+ | Self :: ColonAst ( .., true )
52+ | Self :: ColonAst ( _, None , false )
53+ | Self :: Ast ( .., true ) => None ,
54+ }
55+ }
56+
3157 /// Get keyword from node
3258 pub const fn get_keyword ( & self ) -> & ControlFlowKeyword {
3359 match self {
34- Self :: Ast ( keyword, _ )
35- | Self :: ColonAst ( keyword, _ )
60+ Self :: Ast ( keyword, .. )
61+ | Self :: ColonAst ( keyword, .. )
3662 | Self :: ControlFlow ( keyword, _)
37- | Self :: IdentBlock ( keyword, _ , _ )
38- | Self :: ParensBlock ( keyword, _ , _ )
63+ | Self :: IdentBlock ( keyword, .. )
64+ | Self :: ParensBlock ( keyword, .. )
3965 | Self :: SemiColon ( keyword) => keyword,
4066 }
4167 }
4268
69+ ///Checks if the control flow is empty
70+ pub fn is_empty ( & self ) -> bool {
71+ match self {
72+ Self :: Ast ( _, node, full) => * * node == Ast :: Empty && !* full,
73+ Self :: ColonAst ( _, node, full) => node. is_none ( ) && !* full,
74+ Self :: ControlFlow ( _, node) => node. is_none ( ) ,
75+ Self :: IdentBlock ( _, ident, node) => node. is_none ( ) && ident. is_none ( ) ,
76+ Self :: ParensBlock ( _, parens, braced, full) => {
77+ parens. is_none ( ) && * * braced != Ast :: Empty && !* full
78+ }
79+ Self :: SemiColon ( _) => true ,
80+ }
81+ }
82+
4383 /// Checks if the control flow is full
4484 pub const fn is_full ( & self ) -> bool {
4585 match self {
46- Self :: Ast ( ..) | Self :: ColonAst ( ..) => false ,
86+ Self :: Ast ( .., full ) | Self :: ColonAst ( .., full ) => * full ,
4787 Self :: ControlFlow ( _, node) => node. is_some ( ) ,
4888 Self :: IdentBlock ( _, ident, node) => node. is_some ( ) && ident. is_some ( ) ,
49- Self :: ParensBlock ( _, parens, braced ) => parens. is_some ( ) && braced . is_some ( ) ,
89+ Self :: ParensBlock ( _, parens, _ , full ) => parens. is_some ( ) && * full ,
5090 Self :: SemiColon ( _) => true ,
5191 }
5292 }
@@ -56,16 +96,20 @@ impl ControlFlowNode {
5696 /// See [`Ast::push_block_as_leaf`] for more information.
5797 pub fn push_block_as_leaf ( & mut self , node : Ast ) -> Result < ( ) , String > {
5898 match self {
59- Self :: Ast ( _, ast) | Self :: ColonAst ( _, Some ( ast) ) => ast. push_block_as_leaf ( node) ?,
60- Self :: ColonAst ( keyword, None ) => return Err ( format ! ( "Missing colon after {keyword}." ) ) ,
99+ Self :: Ast ( _, ast, false )
100+ | Self :: ColonAst ( _, Some ( ast) , false )
101+ | Self :: ParensBlock ( _, Some ( _) , ast, false ) => ast. push_block_as_leaf ( node) ?,
102+ Self :: ColonAst ( keyword, None , false ) => {
103+ return Err ( format ! ( "Missing colon after {keyword}." ) ) ;
104+ }
61105 Self :: ControlFlow ( keyword, old_ctrl @ None ) => {
62106 if let Ast :: ControlFlow ( node_ctrl) = node {
63107 * old_ctrl = Some ( Box :: from ( node_ctrl) ) ;
64108 } else {
65109 return Err ( format ! ( "{keyword} expected a keyword but found {node}" , ) ) ;
66110 }
67111 }
68- Self :: ParensBlock ( keyword, old_parens @ None , None ) => {
112+ Self :: ParensBlock ( keyword, old_parens @ None , _ , false ) => {
69113 if let Ast :: ParensBlock ( node_parens) = node {
70114 * old_parens = Some ( node_parens) ;
71115 } else {
@@ -74,8 +118,7 @@ impl ControlFlowNode {
74118 ) ) ;
75119 }
76120 }
77- Self :: ParensBlock ( _, Some ( _) , old_block @ None )
78- | Self :: IdentBlock ( _, Some ( _) , old_block @ None ) => {
121+ Self :: IdentBlock ( _, Some ( _) , old_block @ None ) => {
79122 if let Ast :: BracedBlock ( mut node_block) = node {
80123 node_block. full = true ;
81124 * old_block = Some ( node_block) ;
@@ -104,8 +147,10 @@ impl ControlFlowNode {
104147 }
105148 }
106149 }
107- Self :: ControlFlow ( _, Some ( _) )
108- | Self :: ParensBlock ( _, _, Some ( _) )
150+ Self :: Ast ( .., true )
151+ | Self :: ColonAst ( .., true )
152+ | Self :: ControlFlow ( _, Some ( _) )
153+ | Self :: ParensBlock ( ..)
109154 | Self :: IdentBlock ( _, _, Some ( _) )
110155 | Self :: SemiColon ( _) => {
111156 panic ! ( "Tried to push not on full block, but it is not pushable" )
@@ -116,7 +161,7 @@ impl ControlFlowNode {
116161
117162 /// Tries to push a colon inside the control flow node.
118163 pub fn push_colon ( & mut self ) -> Result < ( ) , String > {
119- if let Self :: ColonAst ( _, node @ None ) = self {
164+ if let Self :: ColonAst ( _, node @ None , false ) = self {
120165 * node = Some ( Box :: from ( Ast :: Empty ) ) ;
121166 Ok ( ( ) )
122167 } else {
@@ -129,8 +174,9 @@ impl ControlFlowNode {
129174 /// See [`Ast::push_op`] for more information.
130175 pub fn push_op < T : fmt:: Display + OperatorConversions > ( & mut self , op : T ) -> Result < ( ) , String > {
131176 match self {
132- Self :: Ast ( _, ast) | Self :: ColonAst ( _, Some ( ast) ) => ast. push_op ( op) ,
133- Self :: ColonAst ( ..)
177+ Self :: Ast ( _, ast, false ) | Self :: ColonAst ( _, Some ( ast) , false ) => ast. push_op ( op) ,
178+ Self :: Ast ( ..)
179+ | Self :: ColonAst ( ..)
134180 | Self :: ControlFlow ( ..)
135181 | Self :: IdentBlock ( ..)
136182 | Self :: ParensBlock ( ..)
@@ -146,9 +192,16 @@ impl ControlFlowNode {
146192impl fmt:: Display for ControlFlowNode {
147193 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
148194 match self {
149- Self :: Ast ( keyword, ast) => write ! ( f, "({keyword} {ast})" ) ,
150- Self :: ColonAst ( keyword, ast) => {
151- write ! ( f, "({keyword}: {})" , repr_option( ast) )
195+ Self :: Ast ( keyword, ast, full) => {
196+ write ! ( f, "({keyword} {ast}{})" , if * full { ".." } else { "" } )
197+ }
198+ Self :: ColonAst ( keyword, ast, full) => {
199+ write ! (
200+ f,
201+ "({keyword}: {}{})" ,
202+ repr_option( ast) ,
203+ if * full { ".." } else { "" }
204+ )
152205 }
153206 Self :: ControlFlow ( keyword, ctrl) => {
154207 write ! ( f, "({keyword} {})" , repr_option( ctrl) )
@@ -159,12 +212,12 @@ impl fmt::Display for ControlFlowNode {
159212 repr_option( ident) ,
160213 repr_option( block)
161214 ) ,
162- Self :: ParensBlock ( keyword, parens_block, block ) => {
215+ Self :: ParensBlock ( keyword, parens_block, ast , full ) => {
163216 write ! (
164217 f,
165- "({keyword} {} {})" ,
218+ "({keyword} {} {ast}{ })" ,
166219 repr_option( parens_block) ,
167- repr_option ( block )
220+ if * full { ".." } else { "" }
168221 )
169222 }
170223 Self :: SemiColon ( keyword) => write ! ( f, "({keyword})" ) ,
0 commit comments