22//!
33//! Pass 1: assign variable IDs/type checking
44//! Pass 3: solving
5- use std:: collections:: { HashMap , HashSet , VecDeque } ;
5+ use std:: collections:: VecDeque ;
66use std:: io:: BufReader ;
77use std:: path:: Path ;
88
@@ -62,8 +62,8 @@ fn check_layers(output: &CompileOutput) {
6262
6363#[ derive( Default ) ]
6464pub ( crate ) struct VarIdTyFrame < ' a > {
65- var_bindings : HashMap < & ' a str , ( VarId , Ty ) > ,
66- scope_bindings : HashSet < & ' a str > ,
65+ var_bindings : IndexMap < & ' a str , ( VarId , Ty ) > ,
66+ scope_bindings : IndexSet < & ' a str > ,
6767}
6868
6969pub ( crate ) struct VarIdTyPass < ' a > {
@@ -113,12 +113,12 @@ pub struct FnTy {
113113#[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
114114pub struct CellFnTy {
115115 args : Vec < Ty > ,
116- data : HashMap < String , Ty > ,
116+ data : IndexMap < String , Ty > ,
117117}
118118
119119#[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
120120pub struct CellTy {
121- data : HashMap < String , Ty > ,
121+ data : IndexMap < String , Ty > ,
122122}
123123
124124impl AstMetadata for VarIdTyMetadata {
@@ -769,7 +769,7 @@ pub(crate) struct DynLoc {
769769
770770#[ derive( Clone ) ]
771771struct Frame {
772- bindings : HashMap < VarId , ValueId > ,
772+ bindings : IndexMap < VarId , ValueId > ,
773773 parent : Option < FrameId > ,
774774}
775775
@@ -805,9 +805,9 @@ struct CellState {
805805
806806struct ExecPass < ' a > {
807807 ast : & ' a Ast < & ' a str , VarIdTyMetadata > ,
808- cell_states : HashMap < CellId , CellState > ,
809- values : HashMap < ValueId , DeferValue < ' a , VarIdTyMetadata > > ,
810- frames : HashMap < FrameId , Frame > ,
808+ cell_states : IndexMap < CellId , CellState > ,
809+ values : IndexMap < ValueId , DeferValue < ' a , VarIdTyMetadata > > ,
810+ frames : IndexMap < FrameId , Frame > ,
811811 nil_value : ValueId ,
812812 global_frame : FrameId ,
813813 next_id : u64 ,
@@ -816,7 +816,7 @@ struct ExecPass<'a> {
816816 // The first element of this stack is the root cell.
817817 // the last element of this stack is the current cell.
818818 partial_cells : VecDeque < CellId > ,
819- compiled_cells : HashMap < CellId , CompiledCell > ,
819+ compiled_cells : IndexMap < CellId , CompiledCell > ,
820820}
821821
822822enum ExecScopeName {
@@ -830,9 +830,9 @@ impl<'a> ExecPass<'a> {
830830 pub ( crate ) fn new ( ast : & ' a Ast < & ' a str , VarIdTyMetadata > ) -> Self {
831831 Self {
832832 ast,
833- cell_states : HashMap :: new ( ) ,
834- values : HashMap :: from_iter ( [ ( 1 , DeferValue :: Ready ( Value :: None ) ) ] ) ,
835- frames : HashMap :: from_iter ( [ (
833+ cell_states : IndexMap :: new ( ) ,
834+ values : IndexMap :: from_iter ( [ ( 1 , DeferValue :: Ready ( Value :: None ) ) ] ) ,
835+ frames : IndexMap :: from_iter ( [ (
836836 0 ,
837837 Frame {
838838 bindings : Default :: default ( ) ,
@@ -843,7 +843,7 @@ impl<'a> ExecPass<'a> {
843843 global_frame : 0 ,
844844 next_id : 2 ,
845845 partial_cells : VecDeque :: new ( ) ,
846- compiled_cells : HashMap :: new ( ) ,
846+ compiled_cells : IndexMap :: new ( ) ,
847847 }
848848 }
849849
@@ -981,10 +981,20 @@ impl<'a> ExecPass<'a> {
981981 if state. nullspace_vecs . is_none ( ) {
982982 state. nullspace_vecs = Some ( state. solver . nullspace_vecs ( ) ) ;
983983 }
984- if let Some ( expr) = state. fallback_constraints . pop ( ) {
985- state. fallback_constraints_used . push ( expr. clone ( ) ) ;
986- state. solver . constrain_eq0 ( expr) ;
987- } else {
984+ let mut constraint_added = false ;
985+ while let Some ( expr) = state. fallback_constraints . pop ( ) {
986+ if expr
987+ . coeffs
988+ . iter ( )
989+ . any ( |( c, v) | c. abs ( ) > 1e-6 && !state. solver . is_solved ( * v) )
990+ {
991+ state. fallback_constraints_used . push ( expr. clone ( ) ) ;
992+ state. solver . constrain_eq0 ( expr) ;
993+ constraint_added = true ;
994+ break ;
995+ }
996+ }
997+ if !constraint_added {
988998 panic ! ( "no progress" ) ;
989999 }
9901000 }
@@ -1050,11 +1060,11 @@ impl<'a> ExecPass<'a> {
10501060 } ;
10511061
10521062 let mut ccell = CompiledCell {
1053- scopes : HashMap :: new ( ) ,
1063+ scopes : IndexMap :: new ( ) ,
10541064 root : state. root_scope ,
10551065 fallback_constraints_used : state. fallback_constraints_used . clone ( ) ,
10561066 nullspace_vecs : state. nullspace_vecs . clone ( ) . unwrap_or_default ( ) ,
1057- objects : HashMap :: new ( ) ,
1067+ objects : IndexMap :: new ( ) ,
10581068 } ;
10591069 fn add_scope ( cell : & mut CompiledCell , state : & CellState , id : ScopeId , scope : & ExecScope ) {
10601070 if cell. scopes . contains_key ( & id) {
@@ -1472,7 +1482,7 @@ impl<'a> ExecPass<'a> {
14721482 }
14731483
14741484 fn eval_partial ( & mut self , vid : ValueId ) -> bool {
1475- let v = self . values . remove ( & vid) ;
1485+ let v = self . values . swap_remove ( & vid) ;
14761486 if v. is_none ( ) {
14771487 return false ;
14781488 }
@@ -2213,9 +2223,9 @@ pub struct CompiledScope {
22132223
22142224#[ derive( Debug , Clone , Serialize , Deserialize ) ]
22152225pub struct CompiledCell {
2216- pub scopes : HashMap < ScopeId , CompiledScope > ,
2226+ pub scopes : IndexMap < ScopeId , CompiledScope > ,
22172227 pub root : ScopeId ,
2218- pub objects : HashMap < ObjectId , SolvedValue > ,
2228+ pub objects : IndexMap < ObjectId , SolvedValue > ,
22192229 pub fallback_constraints_used : Vec < LinearExpr > ,
22202230 pub nullspace_vecs : Vec < Vec < f64 > > ,
22212231}
@@ -2277,7 +2287,7 @@ pub struct StaticErrorCompileOutput {
22772287
22782288#[ derive( Debug , Clone , Serialize , Deserialize ) ]
22792289pub struct ValidCompileOutput {
2280- pub cells : HashMap < CellId , CompiledCell > ,
2290+ pub cells : IndexMap < CellId , CompiledCell > ,
22812291 pub top : CellId ,
22822292 pub layers : LayerProperties ,
22832293}
0 commit comments