@@ -316,20 +316,28 @@ impl AstToEgglog {
316316 {
317317 // Evaluate start index (must be a constant for now)
318318 if let edge_ast:: Expr :: Literal ( lit) = index. as_ref ( ) {
319- if let edge_ast:: Lit :: Int ( start, _, _) = lit. as_ref ( ) {
319+ if let edge_ast:: Lit :: Int ( start_bytes, _, _) = lit. as_ref ( ) {
320+ let start =
321+ u64:: from_be_bytes ( start_bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) )
322+ as usize ;
320323 let new_base = ast_helpers:: add (
321324 base_expr,
322325 ast_helpers:: const_int (
323- ( * start as usize * 32 ) as i64 ,
326+ ( start * 32 ) as i64 ,
324327 self . current_ctx . clone ( ) ,
325328 ) ,
326329 ) ;
327330 // Compute slice length from end index
328331 let slice_len = end_index. as_ref ( ) . map_or ( 0 , |end_idx| {
329332 if let edge_ast:: Expr :: Literal ( end_lit) = end_idx. as_ref ( ) {
330- if let edge_ast:: Lit :: Int ( end, _, _) = end_lit. as_ref ( )
333+ if let edge_ast:: Lit :: Int ( end_bytes, _, _) =
334+ end_lit. as_ref ( )
331335 {
332- ( * end as usize ) - ( * start as usize )
336+ let end = u64:: from_be_bytes (
337+ end_bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) ,
338+ )
339+ as usize ;
340+ end - start
333341 } else {
334342 0
335343 }
@@ -464,16 +472,40 @@ impl AstToEgglog {
464472 /// Lower a literal value.
465473 pub ( crate ) fn lower_literal ( & self , lit : & edge_ast:: Lit ) -> Result < RcExpr , IrError > {
466474 match lit {
467- edge_ast:: Lit :: Int ( val , maybe_ty, _span) => {
475+ edge_ast:: Lit :: Int ( bytes , maybe_ty, _span) => {
468476 let ty = maybe_ty
469477 . as_ref ( )
470478 . map ( |pt| self . lower_primitive_type ( pt) )
471479 . unwrap_or ( EvmType :: Base ( EvmBaseType :: UIntT ( 256 ) ) ) ;
472- Ok ( Rc :: new ( EvmExpr :: Const (
473- EvmConstant :: SmallInt ( * val as i64 ) ,
474- ty,
475- self . current_ctx . clone ( ) ,
476- ) ) )
480+ // Check if value fits in SmallInt (first 24 bytes are zero and high bit of remaining 8 is not set)
481+ let is_small = bytes[ ..24 ] . iter ( ) . all ( |& b| b == 0 ) && ( bytes[ 24 ] & 0x80 ) == 0 ;
482+ if is_small {
483+ let mut val: u64 = 0 ;
484+ for & b in & bytes[ 24 ..] {
485+ val = ( val << 8 ) | ( b as u64 ) ;
486+ }
487+ Ok ( Rc :: new ( EvmExpr :: Const (
488+ EvmConstant :: SmallInt ( val as i64 ) ,
489+ ty,
490+ self . current_ctx . clone ( ) ,
491+ ) ) )
492+ } else {
493+ let hex_str: String = bytes
494+ . iter ( )
495+ . skip_while ( |& & b| b == 0 )
496+ . map ( |b| format ! ( "{b:02x}" ) )
497+ . collect ( ) ;
498+ let hex_str = if hex_str. is_empty ( ) {
499+ "00" . to_string ( )
500+ } else {
501+ hex_str
502+ } ;
503+ Ok ( Rc :: new ( EvmExpr :: Const (
504+ EvmConstant :: LargeInt ( hex_str) ,
505+ ty,
506+ self . current_ctx . clone ( ) ,
507+ ) ) )
508+ }
477509 }
478510 edge_ast:: Lit :: Bool ( val, _span) => {
479511 Ok ( ast_helpers:: const_bool ( * val, self . current_ctx . clone ( ) ) )
0 commit comments