11use std:: iter;
22
33use indexing:: { ExprItem , ExprItemId , IndexingResult , ValueGroupId } ;
4- use rowan:: ast:: AstNode ;
4+ use rowan:: ast:: { AstNode , AstPtr } ;
5+ use rustc_hash:: FxHashMap ;
56use smol_str:: SmolStr ;
67use syntax:: cst;
78
89use crate :: {
9- BinderId , BinderKind , ExpressionArgument , ExpressionId , ExpressionKind , LoweredEquation ,
10- LoweredExprItem , LoweringMap , LoweringResult , OperatorPair , SourceMap , TickPair , TypeId ,
11- TypeKind ,
10+ BinderId , BinderKind , ExpressionArgument , ExpressionId , ExpressionKind , LetBindingId ,
11+ LetBindingKind , LetBindingKindId , LoweredEquation , LoweredExprItem , LoweringMap ,
12+ LoweringResult , OperatorPair , SourceMap , TickPair , TypeId , TypeKind ,
1213} ;
1314
1415#[ derive( Default ) ]
@@ -90,17 +91,7 @@ fn lower_value_group(
9091 let Some ( ptr) = index. source_map . declaration_ptr ( id) else { continue } ;
9192 let Some ( node) = ptr. try_to_node ( root) else { continue } ;
9293 let cst:: Declaration :: ValueEquation ( e) = node else { continue } ;
93-
94- if let Some ( f) = e. function_binders ( ) {
95- for b in f. children ( ) {
96- equation. binders . push ( lower_binder ( state, & b) ) ;
97- }
98- }
99-
100- let Some ( g) = e. guarded_expression ( ) else { continue } ;
101- let Some ( w) = g. where_expression ( ) else { continue } ;
102- let Some ( e) = w. expression ( ) else { continue } ;
103- equation. expression = Some ( lower_expression ( state, & e) ) ;
94+ lower_equation_like ( state, equation, e. function_binders ( ) , e. guarded_expression ( ) ) ;
10495 }
10596
10697 LoweredExprItem :: Value { signature, equations }
@@ -229,7 +220,11 @@ fn lower_expression(state: &mut State, cst: &cst::Expression) -> ExpressionId {
229220 } ) ;
230221 ExpressionKind :: IfThenElse { r#if, then, r#else }
231222 }
232- cst:: Expression :: ExpressionLetIn ( _l) => ExpressionKind :: LetIn ,
223+ cst:: Expression :: ExpressionLetIn ( l) => {
224+ let bindings = l. bindings ( ) . map_or ( vec ! [ ] , |b| lower_let_binding_statements ( state, & b) ) ;
225+ let expression = l. expression ( ) . map ( |e| lower_expression ( state, & e) ) ;
226+ ExpressionKind :: LetIn { bindings, expression }
227+ }
233228 cst:: Expression :: ExpressionLambda ( _l) => ExpressionKind :: Lambda ,
234229 cst:: Expression :: ExpressionCaseOf ( _c) => ExpressionKind :: CaseOf ,
235230 cst:: Expression :: ExpressionDo ( _d) => ExpressionKind :: Do ,
@@ -253,3 +248,166 @@ fn lower_expression(state: &mut State, cst: &cst::Expression) -> ExpressionId {
253248 } ;
254249 state. source_map . insert_expression ( cst, kind)
255250}
251+
252+ fn lower_let_binding_statements (
253+ state : & mut State ,
254+ cst : & cst:: LetBindingStatements ,
255+ ) -> Vec < LetBindingId > {
256+ let mut nominal = FxHashMap :: default ( ) ;
257+ cst. children ( ) . map ( |b| lower_let_binding ( state, & mut nominal, & b) ) . collect ( )
258+ }
259+
260+ fn lower_let_binding (
261+ state : & mut State ,
262+ nominal : & mut FxHashMap < SmolStr , LetBindingKindId > ,
263+ cst : & cst:: LetBinding ,
264+ ) -> LetBindingId {
265+ fn insert_kind_id (
266+ state : & mut State ,
267+ ptr : & cst:: LetBinding ,
268+ kind_id : LetBindingKindId ,
269+ ) -> LetBindingId {
270+ let ptr = AstPtr :: new ( ptr) ;
271+ let ( index, _) = state. source_map . let_bindings . insert_full ( ptr, kind_id) ;
272+ LetBindingId :: from_raw ( index)
273+ }
274+
275+ fn insert_kind (
276+ state : & mut State ,
277+ ptr : & cst:: LetBinding ,
278+ kind : LetBindingKind ,
279+ ) -> ( LetBindingKindId , LetBindingId ) {
280+ let index = state. source_map . let_bindings_grouped . len ( ) ;
281+ let kind_id = LetBindingKindId :: from_raw ( index) ;
282+ state. source_map . let_bindings_grouped . push ( kind) ;
283+ let ptr_id = insert_kind_id ( state, ptr, kind_id) ;
284+ ( kind_id, ptr_id)
285+ }
286+
287+ match cst {
288+ cst:: LetBinding :: LetBindingPattern ( p) => {
289+ let kind = lower_let_binding_pattern ( state, p) ;
290+ let ( _, ptr_id) = insert_kind ( state, cst, kind) ;
291+ ptr_id
292+ }
293+ cst:: LetBinding :: LetBindingSignature ( s) => {
294+ let token = s. name_token ( ) ;
295+ let name = token. as_ref ( ) . map ( |t| t. text ( ) ) ;
296+ let signature = s. signature ( ) . map ( |s| lower_type ( state, & s) ) ;
297+
298+ if let Some ( name) = name {
299+ if let Some ( & kind_id) = nominal. get ( name) {
300+ let index: usize = kind_id. into ( ) ;
301+ let group = & mut state. source_map . let_bindings_grouped [ index] ;
302+ if let LetBindingKind :: Value { signature : s, .. } = group {
303+ if let Some ( existing) = s {
304+ unimplemented ! (
305+ "{:?} <-> {:?} : duplicate let bindings" ,
306+ existing,
307+ signature
308+ ) ;
309+ } else {
310+ * s = signature;
311+ }
312+ }
313+ return insert_kind_id ( state, cst, kind_id) ;
314+ }
315+ }
316+
317+ let name = name. map ( SmolStr :: from) ;
318+ let for_nominal = name. clone ( ) ;
319+
320+ let equations = vec ! [ ] ;
321+ let kind = LetBindingKind :: Value { name, signature, equations } ;
322+
323+ let ( kind_id, ptr_id) = insert_kind ( state, cst, kind) ;
324+
325+ if let Some ( name) = for_nominal {
326+ nominal. insert ( name, kind_id) ;
327+ }
328+
329+ ptr_id
330+ }
331+ cst:: LetBinding :: LetBindingEquation ( e) => {
332+ let token = e. name_token ( ) ;
333+ let name = token. as_ref ( ) . map ( |t| t. text ( ) ) ;
334+
335+ let mut equation = LoweredEquation :: default ( ) ;
336+ lower_equation_like ( state, & mut equation, e. function_binders ( ) , e. guarded_expression ( ) ) ;
337+
338+ if let Some ( name) = name {
339+ if let Some ( & kind_id) = nominal. get ( name) {
340+ let index: usize = kind_id. into ( ) ;
341+ let group = & mut state. source_map . let_bindings_grouped [ index] ;
342+ if let LetBindingKind :: Value { equations, .. } = group {
343+ equations. push ( equation) ;
344+ }
345+ return insert_kind_id ( state, cst, kind_id) ;
346+ }
347+ }
348+
349+ let name = name. map ( SmolStr :: from) ;
350+ let for_nominal = name. clone ( ) ;
351+
352+ let signature = None ;
353+ let equations = vec ! [ equation] ;
354+ let kind = LetBindingKind :: Value { name, signature, equations } ;
355+
356+ let ( kind_id, ptr_id) = insert_kind ( state, cst, kind) ;
357+
358+ if let Some ( name) = for_nominal {
359+ nominal. insert ( name, kind_id) ;
360+ }
361+
362+ ptr_id
363+ }
364+ }
365+ }
366+
367+ fn lower_let_binding_pattern ( state : & mut State , cst : & cst:: LetBindingPattern ) -> LetBindingKind {
368+ let pattern = cst. binder ( ) . map ( |b| lower_binder ( state, & b) ) ;
369+
370+ let where_expression = cst. where_expression ( ) ;
371+
372+ let expression = where_expression. as_ref ( ) . and_then ( |w| {
373+ let e = w. expression ( ) ?;
374+ Some ( lower_expression ( state, & e) )
375+ } ) ;
376+
377+ let bindings = where_expression
378+ . as_ref ( )
379+ . and_then ( |w| {
380+ let b = w. bindings ( ) ?;
381+ Some ( lower_let_binding_statements ( state, & b) )
382+ } )
383+ . unwrap_or_default ( ) ;
384+
385+ LetBindingKind :: Pattern { pattern, expression, bindings }
386+ }
387+
388+ fn lower_equation_like (
389+ state : & mut State ,
390+ equation : & mut LoweredEquation ,
391+ function_binders : Option < cst:: FunctionBinders > ,
392+ guarded_expression : Option < cst:: GuardedExpression > ,
393+ ) {
394+ let where_expression = guarded_expression. and_then ( |g| g. where_expression ( ) ) ;
395+
396+ let binders = function_binders. map_or ( vec ! [ ] , |b| {
397+ let children = b. children ( ) ;
398+ children. map ( |b| lower_binder ( state, & b) ) . collect ( )
399+ } ) ;
400+
401+ let expression = where_expression. as_ref ( ) . and_then ( |w| {
402+ let e = w. expression ( ) ?;
403+ Some ( lower_expression ( state, & e) )
404+ } ) ;
405+
406+ let bindings = where_expression
407+ . and_then ( |w| w. bindings ( ) )
408+ . map_or ( vec ! [ ] , |b| lower_let_binding_statements ( state, & b) ) ;
409+
410+ equation. binders = binders;
411+ equation. expression = expression;
412+ equation. bindings = bindings;
413+ }
0 commit comments