diff --git a/silverscript-lang/src/compiler.rs b/silverscript-lang/src/compiler.rs index 9428d87..a5cdf79 100644 --- a/silverscript-lang/src/compiler.rs +++ b/silverscript-lang/src/compiler.rs @@ -2769,15 +2769,7 @@ fn compile_expr<'i>( compile_expr(source, env, params, types, builder, options, visiting, stack_depth, script_size, contract_constants)?; compile_expr(start, env, params, types, builder, options, visiting, stack_depth, script_size, contract_constants)?; compile_expr(end, env, params, types, builder, options, visiting, stack_depth, script_size, contract_constants)?; - - builder.add_op(Op2Dup)?; - *stack_depth += 2; - builder.add_op(OpSwap)?; - builder.add_op(OpSub)?; - *stack_depth -= 1; - builder.add_op(OpSwap)?; - builder.add_op(OpDrop)?; - *stack_depth -= 1; + // OpSubstr expects bounds as (start, end). builder.add_op(OpSubstr)?; *stack_depth -= 2; Ok(()) diff --git a/silverscript-lang/tests/cashc_valid_examples_tests.rs b/silverscript-lang/tests/cashc_valid_examples_tests.rs index 60e2b8b..e5de852 100644 --- a/silverscript-lang/tests/cashc_valid_examples_tests.rs +++ b/silverscript-lang/tests/cashc_valid_examples_tests.rs @@ -865,7 +865,7 @@ fn runs_cashc_valid_examples() { assert!(result.is_ok(), "{example} failed: {}", result.unwrap_err()); } "slice.sil" | "slice_variable_parameter.sil" => { - // Unsatisfiable in this runtime: it expects a P2PKH locking bytecode in the active input. + // Valid in this runtime with current slice lowering. let constructor_args = vec![vec![0u8; 20].into()]; let compiled = compile_contract(&source, &constructor_args, CompileOptions::default()).expect("compile succeeds"); let selector = selector_for_compiled(&compiled, "spend"); @@ -879,7 +879,7 @@ fn runs_cashc_valid_examples() { ); tx.tx.inputs[0].signature_script = sigscript; let result = execute_tx(tx, utxo, reused); - assert!(result.is_err(), "{example} should fail"); + assert!(result.is_ok(), "{example} failed: {}", result.unwrap_err()); } "slice_optimised.sil" => { // Unsatisfiable in this runtime: NUM2BIN rejects target sizes > 8 (slice needs 20). @@ -899,7 +899,7 @@ fn runs_cashc_valid_examples() { assert!(result.is_err(), "{example} should fail"); } "split_or_slice_signature.sil" => { - // Unsatisfiable in this runtime: signature slicing triggers invalid range errors. + // Valid in this runtime with current slice lowering. let mut signature = vec![0u8; 64]; signature.push(0x01); let constructor_args = vec![signature.into()]; @@ -915,7 +915,7 @@ fn runs_cashc_valid_examples() { ); tx.tx.inputs[0].signature_script = sigscript; let result = execute_tx(tx, utxo, reused); - assert!(result.is_err(), "{example} should fail"); + assert!(result.is_ok(), "{example} failed: {}", result.unwrap_err()); } "split_size.sil" => { // Unsatisfiable in this runtime: `b.length / 2` leaves `b` on the stack, causing invalid substring ranges. diff --git a/silverscript-lang/tests/compiler_tests.rs b/silverscript-lang/tests/compiler_tests.rs index d031607..d53f9ed 100644 --- a/silverscript-lang/tests/compiler_tests.rs +++ b/silverscript-lang/tests/compiler_tests.rs @@ -976,6 +976,48 @@ fn runs_array_runtime_examples() { assert!(result.is_ok(), "array runtime example failed: {}", result.unwrap_err()); } +#[test] +fn runs_slice_with_explicit_end_bounds() { + let source = r#" + contract SliceLowering() { + entrypoint function main() { + byte[] data = 0x0102030405060708090a; + byte[] segment = data.slice(3, 8); + require(segment.length == 5); + require(segment == 0x0405060708); + } + } + "#; + let compiled = compile_contract(source, &[], CompileOptions::default()).expect("compile succeeds"); + let sigscript = ScriptBuilder::new().drain(); + let result = run_script_with_sigscript(compiled.script, sigscript); + assert!(result.is_ok(), "slice runtime should succeed: {}", result.unwrap_err()); +} + +#[test] +fn runs_slice_reconstruction_and_compare_runtime_example() { + let source = r#" + contract SliceReconstruct() { + entrypoint function main() { + byte[] data = 0x0102030405060708090a; + byte[] left = data.slice(0, 4); + byte[] right = data.slice(4, 10); + byte[] rebuilt = left + right; + + require(left == 0x01020304); + require(right == 0x05060708090a); + require(rebuilt.length == data.length); + require(rebuilt == data); + } + } + "#; + + let compiled = compile_contract(source, &[], CompileOptions::default()).expect("compile succeeds"); + let sigscript = ScriptBuilder::new().drain(); + let result = run_script_with_sigscript(compiled.script, sigscript); + assert!(result.is_ok(), "slice reconstruction runtime should succeed: {}", result.unwrap_err()); +} + #[test] fn allows_concat_of_int_arrays_with_plus() { let source = r#"