11use crate :: { F , a_simplify_lang:: * , ir:: * , lang:: * , precompiles:: * } ;
22use lean_vm:: * ;
3- use p3_field:: Field ;
3+ use p3_field:: { Field , PrimeCharacteristicRing } ;
44use std:: {
55 borrow:: Borrow ,
66 collections:: { BTreeMap , BTreeSet } ,
@@ -395,6 +395,7 @@ fn compile_lines(
395395 shift_0,
396396 shift_1 : shift. clone ( ) ,
397397 res : res. to_mem_after_fp_or_constant ( compiler) ,
398+ for_range_check : false ,
398399 } ) ;
399400 }
400401
@@ -432,6 +433,7 @@ fn compile_lines(
432433 res : IntermediaryMemOrFpOrConstant :: MemoryAfterFp {
433434 offset : compiler. get_offset ( & ret_var. clone ( ) . into ( ) ) ,
434435 } ,
436+ for_range_check : false ,
435437 } ) ;
436438 }
437439
@@ -612,6 +614,65 @@ fn compile_lines(
612614 location : * location,
613615 } ) ;
614616 }
617+ SimpleLine :: RangeCheck { value, max } => {
618+ let x = match IntermediateValue :: from_simple_expr ( value, compiler) {
619+ IntermediateValue :: MemoryAfterFp { offset } => offset. naive_eval ( ) . unwrap ( ) ,
620+ value:: IntermediateValue :: Fp => F :: ZERO ,
621+ value:: IntermediateValue :: Constant ( _) => unimplemented ! ( ) ,
622+ } ;
623+
624+ let t = max. naive_eval ( ) . unwrap ( ) ;
625+ let aux_i: usize = compiler. stack_size + 0 ;
626+ let aux_j: usize = compiler. stack_size + 1 ;
627+ let aux_k: usize = compiler. stack_size + 2 ;
628+
629+ // Step 1: DEREF: m[fp + i] == m[m[fp + x]]
630+ // DEREF: m[fp + i] == m[value]
631+
632+ let step_1 = IntermediateInstruction :: Deref {
633+ shift_0 : ConstExpression :: scalar ( x. to_usize ( ) ) ,
634+ shift_1 : ConstExpression :: from ( 0 ) ,
635+ res : IntermediaryMemOrFpOrConstant :: MemoryAfterFp { offset : aux_i. into ( ) } ,
636+ for_range_check : true ,
637+ } ;
638+
639+
640+ // Step 2: ADD: m[m[fp + x]] + m[fp + j] == (t-1)
641+ // m[fp + j] == t - 1 - value
642+ //
643+ // m[fp + j] == t - 1 - m[fp + x]
644+ let q = t - F :: ONE ;
645+ let step_2 = IntermediateInstruction :: Computation {
646+ operation : Operation :: Add ,
647+ arg_a : IntermediateValue :: MemoryAfterFp { offset : x. to_usize ( ) . into ( ) } ,
648+ arg_c : IntermediateValue :: MemoryAfterFp { offset : aux_j. into ( ) } , // solve
649+ res : IntermediateValue :: Constant ( q. to_usize ( ) . into ( ) ) , // t - 1
650+ } ;
651+
652+ // Step 3: DEREF: m[fp + k] == m[m[fp + j]]
653+ let step_3 = IntermediateInstruction :: Deref {
654+ shift_0 : ConstExpression :: scalar ( aux_j) ,
655+ shift_1 : ConstExpression :: from ( 0 ) ,
656+ res : IntermediaryMemOrFpOrConstant :: MemoryAfterFp { offset : aux_k. into ( ) } ,
657+ for_range_check : true ,
658+ } ;
659+
660+
661+ // TODO: handle undefined memory access error
662+
663+ //println!("aux_i: {}; {:?}", aux_i, step_1);
664+ //println!("aux_j: {}; {:?}", aux_j, step_2);
665+ //println!("aux_k: {}; {:?}", aux_k, step_3);
666+
667+ instructions. push ( IntermediateInstruction :: RangeCheck {
668+ value : IntermediateValue :: from_simple_expr ( value, compiler) ,
669+ max : max. clone ( ) ,
670+ } ) ;
671+ instructions. push ( step_1) ;
672+ instructions. push ( step_2) ;
673+ instructions. push ( step_3) ;
674+ compiler. stack_size += 3 ;
675+ }
615676 }
616677 }
617678
@@ -689,11 +750,13 @@ fn setup_function_call(
689750 res: IntermediaryMemOrFpOrConstant :: Constant ( ConstExpression :: label(
690751 return_label. clone( ) ,
691752 ) ) ,
753+ for_range_check: false ,
692754 } ,
693755 IntermediateInstruction :: Deref {
694756 shift_0: new_fp_pos. into( ) ,
695757 shift_1: ConstExpression :: one( ) ,
696758 res: IntermediaryMemOrFpOrConstant :: Fp ,
759+ for_range_check: false ,
697760 } ,
698761 ] ;
699762
@@ -703,6 +766,7 @@ fn setup_function_call(
703766 shift_0 : new_fp_pos. into ( ) ,
704767 shift_1 : ( 2 + i) . into ( ) ,
705768 res : arg. to_mem_after_fp_or_constant ( compiler) ,
769+ for_range_check : false ,
706770 } ) ;
707771 }
708772
@@ -811,7 +875,8 @@ fn find_internal_vars(lines: &[SimpleLine]) -> BTreeSet<Var> {
811875 | SimpleLine :: Print { .. }
812876 | SimpleLine :: FunctionRet { .. }
813877 | SimpleLine :: Precompile { .. }
814- | SimpleLine :: LocationReport { .. } => { }
878+ | SimpleLine :: LocationReport { .. }
879+ | SimpleLine :: RangeCheck { .. } => { }
815880 }
816881 }
817882 internal_vars
0 commit comments