@@ -48,16 +48,17 @@ def build(clause: list[Directive | str], current: Node, condition: Condition):
4848 raise InvalidNode (directive )
4949
5050 case Special .Hash :
51- for index , clause in enumerate (
52- directive .clauses [:- 1 ] if directive .default_token else directive .clauses ):
53- build (clause , current , Equal (Special .Hash , index ))
54-
55- default = Less (index + 1 , index + 1 , Special .Hash )
5651 if directive .default_token :
57- build (directive .clauses [- 1 ], current , default )
52+ for index , clause in enumerate (directive .clauses [:- 1 ]):
53+ build (clause , current , Equal (Special .Hash , index ))
54+
55+ build (directive .clauses [- 1 ], current , Less (index + 1 , index + 1 , Special .Hash ))
5856
5957 else :
60- self .add_edge (current , current .closing , condition = default )
58+ for index , clause in enumerate (directive .clauses ):
59+ build (clause , current , Equal (Special .Hash , index ))
60+
61+ self .add_edge (current , current .closing , condition = Less (index + 1 , index + 1 , Special .Hash ))
6162
6263 case n if 0 <= n < len (directive .clauses ):
6364 build (directive .clauses [n ], current , Condition ())
@@ -93,7 +94,7 @@ def build(clause: list[Directive | str], current: Node, condition: Condition):
9394 buffer .extend (clauses .pop () + [directive .default_token ])
9495
9596 for section in clauses [:- 1 ]:
96- buffer .extend (section + [Directive ("~ ;" , [])])
97+ buffer .extend (section + [Directive (";" , [])])
9798
9899 # TODO: Actually handle justification
99100 build (buffer + clauses [- 1 ], current , Condition ())
@@ -124,8 +125,8 @@ def build(clause: list[Directive | str], current: Node, condition: Condition):
124125 self .add_edge (current , CFG .CRASH )
125126 return
126127
127- case '*' if directive . get_param ( 0 , 0 ) == Special .V :
128- self .add_edge (current , CFG . CRASH )
128+ case '%' | '&' | '|' | '~' | '*' if Special .V in directive . params :
129+ self .crash_on (current )
129130 return
130131
131132 case _:
@@ -185,7 +186,7 @@ def __str__(self) -> str:
185186 case nil , non_nil :
186187 return program + f"~#[{ nil } ~:;{ non_nil } "
187188
188- case "[" :
189+ case "[" if current . directive . get_param ( 0 ) == Special . Hash :
189190 cases = {}
190191 for child in self [current ]:
191192 # Terrible no good very bad
@@ -215,13 +216,14 @@ def __str__(self) -> str:
215216
216217 return program
217218
218- def add_crash (self , u : Node ):
219- self .add_edge (u , v := Node (Directive ("?" , [])))
220- self .add_edge (v , CFG .CRASH )
221-
222219 def add_edge (self , u : Node , v : Node , ** attrs ):
223220 super ().add_edge (u , v , condition = attrs .get ("condition" , Condition ()), back = attrs .get ("back" , False ))
224221
222+ def crash_on (self , node : Node ):
223+ self .remove_edges_from ([* self .edges (node )])
224+ self .add_edge (node , crash := Node (Directive ("?" , [])))
225+ self .add_edge (crash , CFG .CRASH )
226+
225227 def descendants (self , node : Node ) -> set [Node ]:
226228 return nx .descendants (self , node ) | {node }
227229
@@ -282,6 +284,9 @@ def subgraph(self, nodes) -> 'CFG':
282284 subgraph .__class__ = CFG
283285 return subgraph
284286
287+ def terminates_from (self , node : Node ) -> bool :
288+ return bool ({CFG .CRASH , CFG .END } & self .descendants (node ))
289+
285290 def update_pointers (self ):
286291 # TODO: Use the logger
287292 for node in self :
0 commit comments