Skip to content

Commit 40402fe

Browse files
Merge pull request #2504 from sensei-hacker/fix-decompiler-whenchanged-naming
Fix decompiler to output whenChanged() instead of delta()
2 parents d0ded94 + 83dd3f4 commit 40402fe

3 files changed

Lines changed: 105 additions & 5 deletions

File tree

js/transpiler/transpiler/condition_decompiler.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import {
1313
OPERATION,
14+
OPERAND_TYPE,
1415
getOperationName
1516
} from './inav_constants.js';
1617

@@ -57,9 +58,6 @@ class ConditionDecompiler {
5758
constructor(context) {
5859
this.decompileOperand = context.decompileOperand;
5960
this.addWarning = context.addWarning;
60-
61-
// Operation constants for structural pattern matching
62-
this.OPERAND_TYPE_LC = 4; // OPERAND_TYPE.LC
6361
}
6462

6563
/**
@@ -150,7 +148,7 @@ class ConditionDecompiler {
150148
*/
151149
handleNot(lc, allConditions, visited) {
152150
// If operandA is an LC reference, we can inspect the referenced LC directly
153-
if (lc.operandAType === this.OPERAND_TYPE_LC && allConditions) {
151+
if (lc.operandAType === OPERAND_TYPE.LC && allConditions) {
154152
const innerLcIndex = lc.operandAValue;
155153
const innerLC = allConditions.find(c => c.index === innerLcIndex);
156154

js/transpiler/transpiler/decompiler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ class Decompiler {
854854
lines.push(indentStr + '});');
855855
},
856856
'whenChanged': () => {
857-
lines.push(indentStr + `delta(${pattern.value}, ${pattern.threshold}, () => {`);
857+
lines.push(indentStr + `whenChanged(${pattern.value}, ${pattern.threshold}, () => {`);
858858
if (body) lines.push(body);
859859
lines.push(indentStr + '});');
860860
}

js/transpiler/transpiler/tests/decompiler.test.cjs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,5 +705,107 @@ if (inav.flight.gpsValid === 1) {
705705
});
706706
});
707707

708+
describe('OPERAND_TYPE.LC in handleNot', () => {
709+
let decompiler;
710+
711+
beforeEach(() => {
712+
decompiler = new Decompiler();
713+
});
714+
715+
test('should decompile NOT(EQUAL) as !== using LC reference', () => {
716+
// This tests that OPERAND_TYPE.LC (value 4) is correctly used in handleNot
717+
// to recognize when operandA references another Logic Condition
718+
const conditions = [
719+
// LC 0: flight.vbat === 100
720+
{
721+
index: 0,
722+
enabled: 1,
723+
activatorId: -1,
724+
operation: 1, // EQUAL
725+
operandAType: 2, // FLIGHT
726+
operandAValue: 4, // VBAT
727+
operandBType: 0, // VALUE
728+
operandBValue: 100
729+
},
730+
// LC 1: NOT(LC 0) - should become flight.vbat !== 100
731+
{
732+
index: 1,
733+
enabled: 1,
734+
activatorId: -1,
735+
operation: 12, // NOT
736+
operandAType: 4, // OPERAND_TYPE.LC - this is what we're testing
737+
operandAValue: 0, // Reference to LC 0
738+
operandBType: 0,
739+
operandBValue: 0
740+
},
741+
// LC 2: Action activated by the NOT condition
742+
{
743+
index: 2,
744+
enabled: 1,
745+
activatorId: 1,
746+
operation: 18, // GVAR_SET
747+
operandAType: 0,
748+
operandAValue: 0,
749+
operandBType: 0,
750+
operandBValue: 1
751+
}
752+
];
753+
754+
const result = decompiler.decompile(conditions);
755+
756+
expect(result.success).toBe(true);
757+
// handleNot should recognize LC reference and optimize NOT(EQUAL) to !==
758+
expect(result.code).toContain('!==');
759+
expect(result.code).toContain('flight.vbat');
760+
expect(result.code).toContain('100');
761+
});
762+
});
763+
764+
describe('whenChanged (DELTA operation)', () => {
765+
let decompiler;
766+
767+
beforeEach(() => {
768+
decompiler = new Decompiler();
769+
});
770+
771+
test('should decompile DELTA operation as whenChanged()', () => {
772+
// DELTA operation monitors a value and triggers when it changes by threshold
773+
// whenChanged(flight.vbat, 100, () => { gvar[0] = 1; })
774+
const conditions = [
775+
// LC 0: DELTA operation - monitors vbat changes > 100
776+
{
777+
index: 0,
778+
enabled: 1,
779+
activatorId: -1,
780+
operation: 50, // DELTA
781+
operandAType: 2, // FLIGHT
782+
operandAValue: 4, // FLIGHT_PARAM.VBAT
783+
operandBType: 0, // VALUE
784+
operandBValue: 100 // threshold
785+
},
786+
// LC 1: Action - set gvar[0] = 1 when delta triggers
787+
{
788+
index: 1,
789+
enabled: 1,
790+
activatorId: 0,
791+
operation: 18, // GVAR_SET
792+
operandAType: 0, // VALUE
793+
operandAValue: 0, // gvar index
794+
operandBType: 0, // VALUE
795+
operandBValue: 1
796+
}
797+
];
798+
799+
const result = decompiler.decompile(conditions);
800+
801+
expect(result.success).toBe(true);
802+
// Should output whenChanged(), not delta()
803+
expect(result.code).toContain('whenChanged(');
804+
expect(result.code).not.toContain('delta(');
805+
expect(result.code).toContain('flight.vbat');
806+
expect(result.code).toContain('100');
807+
});
808+
});
809+
708810
// Export the load function for the runner
709811
module.exports = { loadDecompiler };

0 commit comments

Comments
 (0)