@@ -469,8 +469,36 @@ class QAST::MASTRegexCompiler {
469
469
}
470
470
471
471
method charrange ($ node ) {
472
- # TODO: implement charrange for moarvm.
473
- self . enumcharlist($ node );
472
+ my @ ins ;
473
+ my $ i0 := fresh_i();
474
+ my $ i1 := fresh_i();
475
+ my $ lower := fresh_i();
476
+ my $ upper := fresh_i();
477
+ nqp :: push (@ ins , op(' ge_i' , $ i0 , % * REG <pos >, % * REG <eos >));
478
+ nqp :: push (@ ins , op(' if_i' , $ i0 , % * REG <fail >));
479
+ nqp :: push (@ ins , op(' const_i64' , $ lower , ival($ node [1 ]. value )));
480
+ nqp :: push (@ ins , op(' const_i64' , $ upper , ival($ node [2 ]. value )));
481
+ nqp :: push (@ ins , op(' ordat' , $ i0 , % * REG <tgt >, % * REG <pos >));
482
+ if $ node . negate {
483
+ my $ succeed := label($ * QASTCOMPILER . unique ($ * RXPREFIX ~ ' _charrange' ));
484
+ nqp :: push (@ ins , op(' gt_i' , $ i1 , $ i0 , $ upper ));
485
+ nqp :: push (@ ins , op(' if_i' , $ i1 , $ succeed ));
486
+ nqp :: push (@ ins , op(' lt_i' , $ i1 , $ i0 , $ lower ));
487
+ nqp :: push (@ ins , op(' if_i' , $ i1 , $ succeed ));
488
+ nqp :: push (@ ins , op(' goto' , % * REG <fail >));
489
+ nqp :: push (@ ins , $ succeed );
490
+ } else {
491
+ nqp :: push (@ ins , op(' lt_i' , $ i1 , $ i0 , $ lower ));
492
+ nqp :: push (@ ins , op(' if_i' , $ i1 , % * REG <fail >));
493
+ nqp :: push (@ ins , op(' gt_i' , $ i1 , $ i0 , $ upper ));
494
+ nqp :: push (@ ins , op(' if_i' , $ i1 , % * REG <fail >));
495
+ }
496
+ nqp :: push (@ ins , op(' inc_i' , % * REG <pos >)) unless $ node . subtype eq ' zerowidth' ;
497
+ release($ i0 , $ MVM_reg_int64 );
498
+ release($ i1 , $ MVM_reg_int64 );
499
+ release($ lower , $ MVM_reg_int64 );
500
+ release($ upper , $ MVM_reg_int64 );
501
+ @ ins
474
502
}
475
503
476
504
method literal ($ node ) {
0 commit comments