@@ -11,7 +11,7 @@ use ecow::{eco_vec, EcoString, EcoVec};
1111use regex:: Regex ;
1212
1313use crate :: {
14- check:: { instrs_signature, instrs_signature_no_temp} ,
14+ check:: { instrs_clean_signature , instrs_signature, instrs_signature_no_temp} ,
1515 primitive:: { ImplPrimitive , Primitive } ,
1616 Assembly , BindingKind , Compiler , FmtInstrs , Function , FunctionId , Instr , Signature , Span ,
1717 SysOp , TempStack , Uiua , UiuaResult , Value ,
@@ -1349,7 +1349,41 @@ fn invert_temp_pattern<'a>(
13491349 comp : & mut Compiler ,
13501350) -> Option < ( & ' a [ Instr ] , EcoVec < Instr > ) > {
13511351 // Push temp
1352- if let Some ( ( input, instr, inner, end_instr, _) ) = try_push_temp_wrap ( input) {
1352+ if let Some ( ( input, instr, inner, end_instr, depth) ) = try_push_temp_wrap ( input) {
1353+ // By-inverse
1354+ if let [ Instr :: Prim ( Primitive :: Dup , dup_span) ] = inner {
1355+ for len in 1 ..=input. len ( ) {
1356+ for mid in 0 ..len {
1357+ let before = & input[ ..mid] ;
1358+ if instrs_clean_signature ( before) . map_or ( true , |sig| sig != ( 0 , 0 ) ) {
1359+ continue ;
1360+ } ;
1361+ let instrs = & input[ mid..len] ;
1362+ let Some ( sig) = instrs_clean_signature ( instrs) else {
1363+ continue ;
1364+ } ;
1365+ if sig. args != depth + 1 {
1366+ continue ;
1367+ }
1368+ for pat in ON_INVERT_PATTERNS {
1369+ if let Some ( ( after, on_inv) ) = pat. invert_extract ( instrs, comp) {
1370+ if after. is_empty ( ) {
1371+ let mut instrs = eco_vec ! [
1372+ instr. clone( ) ,
1373+ Instr :: Prim ( Primitive :: Dup , * dup_span) ,
1374+ end_instr. clone( ) ,
1375+ Instr :: Prim ( Primitive :: Flip , * dup_span) ,
1376+ ] ;
1377+ instrs. extend ( on_inv) ;
1378+ instrs. extend_from_slice ( before) ;
1379+ return Some ( ( & input[ len..] , instrs) ) ;
1380+ }
1381+ }
1382+ }
1383+ }
1384+ }
1385+ }
1386+ // Normal inverse
13531387 let mut instrs = invert_instrs ( inner, comp) ?;
13541388 instrs. insert ( 0 , instr. clone ( ) ) ;
13551389 instrs. push ( end_instr. clone ( ) ) ;
@@ -1369,7 +1403,7 @@ fn invert_temp_pattern<'a>(
13691403 continue ;
13701404 }
13711405 for pat in ON_INVERT_PATTERNS {
1372- if let Some ( ( after, pseudo_inv ) ) = pat. invert_extract ( after, comp) {
1406+ if let Some ( ( after, on_inv ) ) = pat. invert_extract ( after, comp) {
13731407 if let Some ( after_inv) = invert_instrs ( after, comp) {
13741408 let mut instrs = eco_vec ! [ start_instr. clone( ) ] ;
13751409
@@ -1385,7 +1419,7 @@ fn invert_temp_pattern<'a>(
13851419
13861420 instrs. extend_from_slice ( before) ;
13871421
1388- instrs. extend ( pseudo_inv ) ;
1422+ instrs. extend ( on_inv ) ;
13891423
13901424 instrs. push ( end_instr. clone ( ) ) ;
13911425 return Some ( ( input, instrs) ) ;
0 commit comments