11//! Program compilation.
22
33use crate :: load:: { self , lex, parse} ;
4- use crate :: { ops, Bind , Filter } ;
4+ use crate :: { ops, Bind as Arg , Filter } ;
55use alloc:: collections:: { BTreeMap , BTreeSet } ;
66use alloc:: { boxed:: Box , string:: String , vec:: Vec } ;
77
88type NativeId = usize ;
99type ModId = usize ;
1010type VarId = usize ;
1111type VarSkip = usize ;
12- type LabelSkip = usize ;
1312type Arity = usize ;
1413
1514/// Index of a term in the look-up table.
@@ -81,15 +80,14 @@ pub(crate) enum Term<T = TermId> {
8180 /// Singleton object (`{f: g}`)
8281 ObjSingle ( T , T ) ,
8382
84- /// Bound variable (`$x`) or filter argument (`a`)
85- Var ( VarId , LabelSkip ) ,
83+ /// Bound variable (`$x`), label (`label $x`), or filter argument (`a`)
84+ Var ( VarId ) ,
8685 /// Call to a filter (`filter`, `filter(…)`)
87- CallDef ( TermId , Box < [ Bind < T > ] > , VarSkip , Option < Tailrec > ) ,
88- Native ( NativeId , Box < [ Bind < T > ] > ) ,
86+ CallDef ( TermId , Box < [ Arg < T > ] > , VarSkip , Option < Tailrec > ) ,
87+ Native ( NativeId , Box < [ Arg < T > ] > ) ,
8988
89+ /// Binding of a break label (`label $x | f`)
9090 Label ( T ) ,
91- Break ( usize ) ,
92-
9391 /// Negation operation (`-f`)
9492 Neg ( T ) ,
9593 /// Variable binding (`f as $x | g`) if identifier (`x`) is given, otherwise
@@ -233,22 +231,22 @@ impl<S: Default, F> Default for Compiler<S, F> {
233231}
234232
235233#[ derive( Clone , Debug ) ]
236- struct Sig < S , A = Bind > {
234+ struct Sig < S , A = Arg > {
237235 name : S ,
238236 // TODO: we could analyse for each argument whether it is TR, and
239237 // use this when converting args at callsite
240238 args : Box < [ A ] > ,
241239}
242240
243- fn bind_from < T > ( s : & str , x : T ) -> Bind < T > {
241+ fn bind_from < T > ( s : & str , x : T ) -> Arg < T > {
244242 if s. starts_with ( '$' ) {
245- Bind :: Var ( x)
243+ Arg :: Var ( x)
246244 } else {
247- Bind :: Fun ( x)
245+ Arg :: Fun ( x)
248246 }
249247}
250248
251- fn binds < T , U : Copy > ( binds : & [ Bind < T > ] , args : & [ U ] ) -> Box < [ Bind < U > ] > {
249+ fn binds < T , U : Copy > ( binds : & [ Arg < T > ] , args : & [ U ] ) -> Box < [ Arg < U > ] > {
252250 assert ! ( binds. len( ) == args. len( ) ) ;
253251 let args = binds. iter ( ) . zip ( args) ;
254252 args. map ( |( bind, id) | bind. as_ref ( ) . map ( |_| * id) ) . collect ( )
@@ -270,7 +268,7 @@ impl<S: Eq, A> Sig<S, A> {
270268}
271269
272270impl Def {
273- fn call ( & self , args : Box < [ Bind < TermId > ] > , vars : usize ) -> Term {
271+ fn call ( & self , args : Box < [ Arg < TermId > ] > , vars : usize ) -> Term {
274272 // we pretend that the function call is tail-recursive,
275273 // and at the very end of compilation, we will correct calls
276274 // to non-tail-recursive functions
@@ -279,12 +277,20 @@ impl Def {
279277}
280278
281279/// Store a map of vectors plus the sum of the lengths of all vectors.
282- #[ derive( Default ) ]
283280struct MapVecLen < S > {
284281 bound : MapVec < S , usize > ,
285282 total : usize ,
286283}
287284
285+ impl < S > Default for MapVecLen < S > {
286+ fn default ( ) -> Self {
287+ Self {
288+ bound : MapVec :: default ( ) ,
289+ total : 0 ,
290+ }
291+ }
292+ }
293+
288294impl < S : Ord > MapVecLen < S > {
289295 fn push ( & mut self , name : S ) {
290296 self . total += 1 ;
@@ -302,22 +308,40 @@ impl<S: Ord> MapVecLen<S> {
302308}
303309
304310enum Fun < S > {
305- // number of labels
306- Arg ( usize ) ,
307- Parent ( Box < [ Bind < S > ] > , Def ) ,
311+ Arg ,
312+ Parent ( Box < [ Arg < S > ] > , Def ) ,
308313 // Tr is for tail-rec allowed funs
309- Sibling ( Box < [ Bind < S > ] > , Def , Tr ) ,
314+ Sibling ( Box < [ Arg < S > ] > , Def , Tr ) ,
315+ }
316+
317+ /// Single binding.
318+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
319+ pub ( crate ) enum Bind < V , L = V , F = V > {
320+ /// binding to a variable
321+ Var ( V ) ,
322+ /// binding to a break label
323+ Label ( L ) ,
324+ /// binding to a filter
325+ Fun ( F ) ,
310326}
311327
312- #[ derive( Default ) ]
313328struct Locals < S > {
314329 // usize = number of vars
315330 funs : MapVec < ( S , Arity ) , ( Fun < S > , usize ) > ,
316- vars : MapVecLen < S > ,
317- labels : MapVecLen < S > ,
331+ vars : MapVecLen < Bind < S > > ,
318332 parents : Tr ,
319333}
320334
335+ impl < S > Default for Locals < S > {
336+ fn default ( ) -> Self {
337+ Self {
338+ funs : MapVec :: default ( ) ,
339+ vars : MapVecLen :: default ( ) ,
340+ parents : Tr :: default ( ) ,
341+ }
342+ }
343+ }
344+
321345struct MapVec < K , V > ( BTreeMap < K , Vec < V > > ) ;
322346
323347impl < K , V > Default for MapVec < K , V > {
@@ -354,15 +378,15 @@ impl<K: Ord, V> MapVec<K, V> {
354378}
355379
356380impl < S : Copy + Ord > Locals < S > {
357- fn push_sibling ( & mut self , name : S , args : Box < [ Bind < S > ] > , def : Def ) {
381+ fn push_sibling ( & mut self , name : S , args : Box < [ Arg < S > ] > , def : Def ) {
358382 let tr = self . parents . clone ( ) ;
359383 self . funs . push (
360384 ( name, args. len ( ) ) ,
361385 ( Fun :: Sibling ( args, def, tr) , self . vars . total ) ,
362386 ) ;
363387 }
364388
365- fn pop_sibling ( & mut self , name : S , arity : Arity ) -> ( Box < [ Bind < S > ] > , Def , Tr ) {
389+ fn pop_sibling ( & mut self , name : S , arity : Arity ) -> ( Box < [ Arg < S > ] > , Def , Tr ) {
366390 let ( y, vars) = match self . funs . pop ( & ( name, arity) ) {
367391 Some ( ( Fun :: Sibling ( args, def, tr) , vars) ) => ( ( args, def, tr) , vars) ,
368392 _ => panic ! ( ) ,
@@ -371,15 +395,15 @@ impl<S: Copy + Ord> Locals<S> {
371395 y
372396 }
373397
374- fn push_parent ( & mut self , name : S , args : Box < [ Bind < S > ] > , def : Def ) {
398+ fn push_parent ( & mut self , name : S , args : Box < [ Arg < S > ] > , def : Def ) {
375399 self . parents . insert ( def. id ) ;
376400
377401 let vars = self . vars . total ;
378402
379403 for arg in args. iter ( ) {
380404 match arg {
381- Bind :: Var ( v) => self . vars . push ( * v ) ,
382- Bind :: Fun ( f) => self . push_arg ( * f) ,
405+ Arg :: Var ( v) => self . vars . push ( Bind :: Var ( * v ) ) ,
406+ Arg :: Fun ( f) => self . push_arg ( * f) ,
383407 }
384408 }
385409
@@ -394,8 +418,8 @@ impl<S: Copy + Ord> Locals<S> {
394418 } ;
395419 for arg in args. iter ( ) . rev ( ) {
396420 match arg {
397- Bind :: Var ( v) => self . vars . pop ( v ) ,
398- Bind :: Fun ( f) => self . pop_arg ( * f) ,
421+ Arg :: Var ( v) => self . vars . pop ( & Bind :: Var ( * v ) ) ,
422+ Arg :: Fun ( f) => self . pop_arg ( * f) ,
399423 }
400424 }
401425 assert_eq ! ( self . vars. total, vars) ;
@@ -404,26 +428,22 @@ impl<S: Copy + Ord> Locals<S> {
404428 }
405429
406430 fn push_arg ( & mut self , name : S ) {
407- self . vars . total += 1 ;
408- self . funs
409- . push ( ( name, 0 ) , ( Fun :: Arg ( self . labels . total ) , self . vars . total ) ) ;
431+ self . vars . push ( Bind :: Fun ( name) ) ;
432+ self . funs . push ( ( name, 0 ) , ( Fun :: Arg , self . vars . total ) ) ;
410433 }
411434
412435 fn pop_arg ( & mut self , name : S ) {
413- let ( labels , vars) = match self . funs . pop ( & ( name, 0 ) ) {
414- Some ( ( Fun :: Arg ( labels ) , vars) ) => ( labels , vars) ,
436+ let vars = match self . funs . pop ( & ( name, 0 ) ) {
437+ Some ( ( Fun :: Arg , vars) ) => vars,
415438 _ => panic ! ( ) ,
416439 } ;
417- assert_eq ! ( self . labels. total, labels) ;
418440 assert_eq ! ( self . vars. total, vars) ;
419- self . vars . total -= 1 ;
441+ self . vars . pop ( & Bind :: Fun ( name ) ) ;
420442 }
421443
422444 fn call ( & mut self , name : S , args : & [ TermId ] , tr : & Tr ) -> Option < Term > {
423445 Some ( match self . funs . get_last_mut ( & ( name, args. len ( ) ) ) ? {
424- ( Fun :: Arg ( labels) , vars) => {
425- Term :: Var ( self . vars . total - * vars, self . labels . total - * labels)
426- }
446+ ( Fun :: Arg , vars) => Term :: Var ( self . vars . total - * vars) ,
427447 ( Fun :: Sibling ( args_, def, tr_) , vars) => {
428448 // we are at a position that may only call `tr` tail-recursively and
429449 // we call a sibling that may only call `tr_` tail-recursively,
@@ -447,10 +467,7 @@ impl<S: Copy + Ord> Locals<S> {
447467 }
448468
449469 fn is_empty ( & self ) -> bool {
450- self . funs . is_empty ( )
451- && self . vars . is_empty ( )
452- && self . labels . is_empty ( )
453- && self . parents . is_empty ( )
470+ self . funs . is_empty ( ) && self . vars . is_empty ( ) && self . parents . is_empty ( )
454471 }
455472}
456473
@@ -460,7 +477,7 @@ type Tr = BTreeSet<TermId>;
460477
461478impl < ' s , F > Compiler < & ' s str , F > {
462479 /// Supply functions with given signatures.
463- pub fn with_funs ( mut self , funs : impl IntoIterator < Item = ( & ' s str , Box < [ Bind ] > , F ) > ) -> Self {
480+ pub fn with_funs ( mut self , funs : impl IntoIterator < Item = ( & ' s str , Box < [ Arg ] > , F ) > ) -> Self {
464481 self . lut . funs = funs
465482 . into_iter ( )
466483 . map ( |( name, args, f) | ( Sig { name, args } , f) )
@@ -533,16 +550,19 @@ impl<'s, F> Compiler<&'s str, F> {
533550 }
534551
535552 fn with_label < T > ( & mut self , label : & ' s str , f : impl FnOnce ( & mut Self ) -> T ) -> T {
536- self . locals . labels . push ( label) ;
553+ self . locals . vars . push ( Bind :: Label ( label) ) ;
537554 let y = f ( self ) ;
538- self . locals . labels . pop ( & label) ;
555+ self . locals . vars . pop ( & Bind :: Label ( label) ) ;
539556 y
540557 }
541558
542559 fn with_vars < T > ( & mut self , vars : & [ & ' s str ] , f : impl FnOnce ( & mut Self ) -> T ) -> T {
543- vars. iter ( ) . for_each ( |v| self . locals . vars . push ( v) ) ;
560+ vars. iter ( )
561+ . for_each ( |v| self . locals . vars . push ( Bind :: Var ( v) ) ) ;
544562 let y = f ( self ) ;
545- vars. iter ( ) . rev ( ) . for_each ( |v| self . locals . vars . pop ( v) ) ;
563+ vars. iter ( )
564+ . rev ( )
565+ . for_each ( |v| self . locals . vars . pop ( & Bind :: Var ( v) ) ) ;
546566 y
547567 }
548568
@@ -583,7 +603,7 @@ impl<'s, F> Compiler<&'s str, F> {
583603 }
584604
585605 /// Compile a placeholder sibling with its corresponding definition.
586- fn def_post ( & mut self , d : parse:: Def < & ' s str > ) -> ( Sig < & ' s str , Bind > , Def ) {
606+ fn def_post ( & mut self , d : parse:: Def < & ' s str > ) -> ( Sig < & ' s str , Arg > , Def ) {
587607 let ( args, def, mut tr) = self . locals . pop_sibling ( d. name , d. args . len ( ) ) ;
588608 let tid = def. id ;
589609 self . locals . push_parent ( d. name , args, def) ;
@@ -808,19 +828,19 @@ impl<'s, F> Compiler<&'s str, F> {
808828 fn var ( & mut self , x : & ' s str ) -> Term {
809829 let mut i = self . locals . vars . total ;
810830
811- if let Some ( v) = self . locals . vars . bound . get_last ( & x ) {
812- return Term :: Var ( i - v, 0 ) ;
831+ if let Some ( v) = self . locals . vars . bound . get_last ( & Bind :: Var ( x ) ) {
832+ return Term :: Var ( i - v) ;
813833 }
814834 for ( x_, mid) in self . imported_vars . iter ( ) . rev ( ) {
815835 if x == * x_ && * mid == self . mod_map . len ( ) {
816- return Term :: Var ( i, 0 ) ;
836+ return Term :: Var ( i) ;
817837 } else {
818838 i += 1 ;
819839 }
820840 }
821841 for x_ in self . global_vars . iter ( ) . rev ( ) {
822842 if x == * x_ {
823- return Term :: Var ( i, 0 ) ;
843+ return Term :: Var ( i) ;
824844 } else {
825845 i += 1 ;
826846 }
@@ -829,8 +849,8 @@ impl<'s, F> Compiler<&'s str, F> {
829849 }
830850
831851 fn break_ ( & mut self , x : & ' s str ) -> Term {
832- if let Some ( l) = self . locals . labels . bound . get_last ( & x ) {
833- return Term :: Break ( self . locals . labels . total - l) ;
852+ if let Some ( l) = self . locals . vars . bound . get_last ( & Bind :: Label ( x ) ) {
853+ return Term :: Var ( self . locals . vars . total - l) ;
834854 }
835855 self . fail ( x, Undefined :: Label )
836856 }
0 commit comments