@@ -242,6 +242,7 @@ public Idx LinkList(Idx[] indices)
242242 return indices [ 0 ] ;
243243 }
244244
245+ // Allocates an enumerator — suitable for tests and diagnostics; avoid in hot paths.
245246 public IEnumerable < Idx > Siblings ( Idx head )
246247 {
247248 var cur = head ;
@@ -253,9 +254,13 @@ public IEnumerable<Idx> Siblings(Idx head)
253254 }
254255
255256 // Builds body after registering params so they are found in paramMap when encountered in the body.
256- public SysExpr ToSystemExpression ( ) => ToSystemExpression ( RootIdx , new Dictionary < int , SysParam > ( ) ) ;
257+ public SysExpr ToSystemExpression ( )
258+ {
259+ var paramMap = default ( SmallMap16 < int , SysParam , IntEq > ) ;
260+ return ToSystemExpression ( RootIdx , ref paramMap ) ;
261+ }
257262
258- private SysExpr ToSystemExpression ( Idx nodeIdx , Dictionary < int , SysParam > paramMap )
263+ private SysExpr ToSystemExpression ( Idx nodeIdx , ref SmallMap16 < int , SysParam , IntEq > paramMap )
259264 {
260265 if ( nodeIdx . IsNil )
261266 throw new InvalidOperationException ( "Cannot convert nil Idx to System.Linq.Expressions" ) ;
@@ -274,11 +279,9 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
274279
275280 case ExpressionType . Parameter :
276281 {
277- if ( ! paramMap . TryGetValue ( nodeIdx . It , out var p ) )
278- {
282+ ref var p = ref paramMap . Map . AddOrGetValueRef ( nodeIdx . It , out var found ) ;
283+ if ( ! found )
279284 p = SysExpr . Parameter ( node . Type , node . Info as string ) ;
280- paramMap [ nodeIdx . It ] = p ;
281- }
282285 return p ;
283286 }
284287
@@ -291,20 +294,20 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
291294 var paramExprs = new List < SysParam > ( ) ;
292295 if ( paramIdxs != null )
293296 foreach ( var pIdx in paramIdxs )
294- paramExprs . Add ( ( SysParam ) ToSystemExpression ( pIdx , paramMap ) ) ;
295- var body = ToSystemExpression ( node . ChildIdx , paramMap ) ;
297+ paramExprs . Add ( ( SysParam ) ToSystemExpression ( pIdx , ref paramMap ) ) ;
298+ var body = ToSystemExpression ( node . ChildIdx , ref paramMap ) ;
296299 return SysExpr . Lambda ( node . Type , body , paramExprs ) ;
297300 }
298301
299302 case ExpressionType . New :
300- return SysExpr . New ( ( ConstructorInfo ) node . Info , SiblingList ( node . ChildIdx , paramMap ) ) ;
303+ return SysExpr . New ( ( ConstructorInfo ) node . Info , SiblingList ( node . ChildIdx , ref paramMap ) ) ;
301304
302305 case ExpressionType . Call :
303306 {
304307 var method = ( MethodInfo ) node . Info ;
305308 return method . IsStatic
306- ? SysExpr . Call ( method , SiblingList ( node . ChildIdx , paramMap ) )
307- : SysExpr . Call ( ToSystemExpression ( node . ChildIdx , paramMap ) , method , SiblingList ( node . ExtraIdx , paramMap ) ) ;
309+ ? SysExpr . Call ( method , SiblingList ( node . ChildIdx , ref paramMap ) )
310+ : SysExpr . Call ( ToSystemExpression ( node . ChildIdx , ref paramMap ) , method , SiblingList ( node . ExtraIdx , ref paramMap ) ) ;
308311 }
309312
310313 case ExpressionType . Add :
@@ -332,8 +335,8 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
332335 case ExpressionType . Power :
333336 case ExpressionType . Coalesce :
334337 return SysExpr . MakeBinary ( node . NodeType ,
335- ToSystemExpression ( node . ChildIdx , paramMap ) ,
336- ToSystemExpression ( node . ExtraIdx , paramMap ) ,
338+ ToSystemExpression ( node . ChildIdx , ref paramMap ) ,
339+ ToSystemExpression ( node . ExtraIdx , ref paramMap ) ,
337340 false , node . Info as MethodInfo ) ;
338341
339342 case ExpressionType . Negate :
@@ -353,24 +356,28 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
353356 case ExpressionType . PreDecrementAssign :
354357 case ExpressionType . PostDecrementAssign :
355358 return SysExpr . MakeUnary ( node . NodeType ,
356- ToSystemExpression ( node . ChildIdx , paramMap ) ,
359+ ToSystemExpression ( node . ChildIdx , ref paramMap ) ,
357360 node . Type , node . Info as MethodInfo ) ;
358361
359362 case ExpressionType . Conditional :
360363 return SysExpr . Condition (
361- ToSystemExpression ( node . ChildIdx , paramMap ) ,
362- ToSystemExpression ( node . ExtraIdx , paramMap ) ,
363- ToSystemExpression ( NodeAt ( node . ExtraIdx ) . NextIdx , paramMap ) ,
364+ ToSystemExpression ( node . ChildIdx , ref paramMap ) ,
365+ ToSystemExpression ( node . ExtraIdx , ref paramMap ) ,
366+ ToSystemExpression ( NodeAt ( node . ExtraIdx ) . NextIdx , ref paramMap ) ,
364367 node . Type ) ;
365368
366369 case ExpressionType . Block :
367370 {
368- var exprs = SiblingList ( node . ChildIdx , paramMap ) ;
371+ var exprs = SiblingList ( node . ChildIdx , ref paramMap ) ;
369372 if ( node . ExtraIdx . IsNil )
370373 return SysExpr . Block ( node . Type , exprs ) ;
371374 var vars = new List < SysParam > ( ) ;
372- foreach ( var vIdx in Siblings ( node . ExtraIdx ) )
373- vars . Add ( ( SysParam ) ToSystemExpression ( vIdx , paramMap ) ) ;
375+ var vCur = node . ExtraIdx ;
376+ while ( ! vCur . IsNil )
377+ {
378+ vars . Add ( ( SysParam ) ToSystemExpression ( vCur , ref paramMap ) ) ;
379+ vCur = NodeAt ( vCur ) . NextIdx ;
380+ }
374381 return SysExpr . Block ( node . Type , vars , exprs ) ;
375382 }
376383
@@ -380,11 +387,15 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
380387 }
381388 }
382389
383- private List < SysExpr > SiblingList ( Idx head , Dictionary < int , SysParam > paramMap )
390+ private List < SysExpr > SiblingList ( Idx head , ref SmallMap16 < int , SysParam , IntEq > paramMap )
384391 {
385392 var list = new List < SysExpr > ( ) ;
386- foreach ( var idx in Siblings ( head ) )
387- list . Add ( ToSystemExpression ( idx , paramMap ) ) ;
393+ var cur = head ;
394+ while ( ! cur . IsNil )
395+ {
396+ list . Add ( ToSystemExpression ( cur , ref paramMap ) ) ;
397+ cur = NodeAt ( cur ) . NextIdx ;
398+ }
388399 return list ;
389400 }
390401
0 commit comments