diff --git a/rust_compiler/libs/compiler/src/v1.rs b/rust_compiler/libs/compiler/src/v1.rs index d137146..6d7f523 100644 --- a/rust_compiler/libs/compiler/src/v1.rs +++ b/rust_compiler/libs/compiler/src/v1.rs @@ -391,6 +391,26 @@ impl<'a> Compiler<'a> { } Expression::Ternary(tern) => Ok(Some(self.expression_ternary(tern.node, scope)?)), Expression::Invocation(expr_invoke) => { + // Special case: hash() with string literal can be evaluated at compile time + if expr_invoke.node.name.node == "hash" && expr_invoke.node.arguments.len() == 1 { + if let Expression::Literal(Spanned { + node: Literal::String(str_to_hash), + .. + }) = &expr_invoke.node.arguments[0].node + { + // Evaluate hash at compile time + let hash_value = crc_hash_signed(str_to_hash); + return Ok(Some(CompileLocation { + location: VariableLocation::Constant(Literal::Number(Number::Integer( + hash_value, + Unit::None, + ))), + temp_name: None, + })); + } + } + + // Non-constant hash calls or other function calls self.expression_function_invocation(expr_invoke, scope)?; // Invocation returns result in r15 (RETURN_REGISTER). // If used as an expression, we must move it to a temp to avoid overwrite. @@ -2359,7 +2379,19 @@ impl<'a> Compiler<'a> { // 4. Handle Binary Ops: Recurse BOTH sides, then combine Expression::Binary(bin) => fold_binary_expression(&bin.node), - // 5. Handle hash() macro - evaluates to a constant at compile time + // 5. Handle hash() syscall - evaluates to a constant at compile time + Expression::Syscall(Spanned { + node: + SysCall::System(System::Hash(Spanned { + node: Literal::String(str_to_hash), + .. + })), + .. + }) => { + return Some(Number::Integer(crc_hash_signed(str_to_hash), Unit::None)); + } + + // 6. Handle hash() macro as invocation - evaluates to a constant at compile time Expression::Invocation(inv) => { if inv.node.name.node == "hash" && inv.node.arguments.len() == 1 { if let Expression::Literal(Spanned { @@ -2374,7 +2406,7 @@ impl<'a> Compiler<'a> { None } - // 6. Anything else cannot be compile-time folded + // 7. Anything else cannot be compile-time folded _ => None, } } diff --git a/rust_compiler/libs/integration_tests/src/bitwise_tests.rs b/rust_compiler/libs/integration_tests/src/bitwise_tests.rs index be08802..eada160 100644 --- a/rust_compiler/libs/integration_tests/src/bitwise_tests.rs +++ b/rust_compiler/libs/integration_tests/src/bitwise_tests.rs @@ -74,4 +74,20 @@ mod bitwise_tests { let output = compile_with_and_without_optimization(source); insta::assert_snapshot!(output); } + + #[test] + fn test_sorter_bitwise_operations() { + let source = indoc! {r#" + device self = "db"; + device sorter = "d0"; + + loop { + yield(); + // allow Hay with an op_code of `1` + sorter[0] = (hash("ItemCropHay") << 8) | 1; + } + "#}; + let output = compile_with_and_without_optimization(source); + insta::assert_snapshot!(output); + } } diff --git a/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__bitwise_tests__bitwise_tests__sorter_bitwise_operations.snap b/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__bitwise_tests__bitwise_tests__sorter_bitwise_operations.snap new file mode 100644 index 0000000..0b3b60a --- /dev/null +++ b/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__bitwise_tests__bitwise_tests__sorter_bitwise_operations.snap @@ -0,0 +1,20 @@ +--- +source: libs/integration_tests/src/bitwise_tests.rs +assertion_line: 91 +expression: output +--- +## Unoptimized Output + +j main +main: +__internal_L1: +yield +put d0 0 55164456193 +j __internal_L1 +__internal_L2: + +## Optimized Output + +yield +put d0 0 55164456193 +j 0 diff --git a/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__device_indexing_tests__device_indexing_tests__device_indexing_optimization_folds_constants.snap b/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__device_indexing_tests__device_indexing_tests__device_indexing_optimization_folds_constants.snap index 59c0e72..fc8984f 100644 --- a/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__device_indexing_tests__device_indexing_tests__device_indexing_optimization_folds_constants.snap +++ b/rust_compiler/libs/integration_tests/src/snapshots/integration_tests__device_indexing_tests__device_indexing_tests__device_indexing_optimization_folds_constants.snap @@ -7,19 +7,13 @@ expression: output j main main: -sll r1 -952768015 16 -or r2 r1 2560 -or r3 r2 50 -move r8 r3 +move r8 -62440604628430 put d0 255 r8 -get r4 d0 255 -move r9 r4 +get r1 d0 255 +move r9 r1 ## Optimized Output -move r1 -62440604631040 -move r2 -62440604628480 -move r3 -62440604628430 move r8 -62440604628430 put d0 255 r8 get r9 d0 255