Skip to content

Commit

Permalink
optimized case expression
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Deubler <[email protected]>
  • Loading branch information
TerminalTim committed Jul 22, 2024
1 parent e7b614f commit 012a268
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
23 changes: 13 additions & 10 deletions packages/common/src/Expressions/ConditionalExpressions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CaseExpressionError extends Error {

export class CaseExpression extends Expression {
static operator = 'case';
private conditionIndex: number;
private start: number;

constructor(json, env) {
if (json.length < 4) {
Expand All @@ -45,7 +45,7 @@ export class CaseExpression extends Expression {
const operands: JSONExpression = [this.json[0]];
let partial = false;
let dynamic: false | Expression = false;
this.conditionIndex = 1;
this.start = 1;
for (let i = 1, branch = 2, {json} = this, len = json.length, fbIndex = len - 1; i < len; i++) {
let exp = this.compileOperand(i);
const isCondition = Boolean(i % 2);
Expand All @@ -63,28 +63,31 @@ export class CaseExpression extends Expression {
}
dynamic = <Expression> this;
}
} else if (isCondition) {
// make sure it's not fallback
if (!isFallback) {
} else if (isCondition && !isFallback) {
if (exp) {
this.start = i;
// following condition are unreachable, we stop next iteration (result)
len = i + 2;
} else {
// unreachable -> we can skip statement;
i++;
this.conditionIndex = i + 1;
continue;
this.start = i + 1;
}
continue;
}

operands[i] = exp;
}
if (partial) {
return this.clone(operands);
// return this.clone(operands).eval(context);
}
return dynamic;
}

eval(context) {
const {json} = this;
let len = json.length - 1;
for (let i = this.conditionIndex || 1; i < len; i += 2) {
for (let i = this.start || 1; i < len; i += 2) {
let condition = this.operand(i, context);
if (condition) {
return this.operand(i + 1, context);
Expand Down Expand Up @@ -121,7 +124,7 @@ export class StepExpression extends Expression {
export class MatchExpression extends Expression {
static operator = 'match';

dynamic(context: Context): false|Expression {
dynamic(context: Context): false | Expression {
for (let i = 1, len = this.json.length - 2; i < len; i += 2) {
if (Expression.isDynamicExpression(this.compileOperand(i), context)) {
return this;
Expand Down
29 changes: 29 additions & 0 deletions packages/tests/specs/common/expressions/expressions_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,33 @@ describe('Expressions', function() {
const result = evalExpression(exp, ExpressionMode.dynamic);
expectExpression('match', result);
});

it('(dynamic) case expression dynamic nested value expression', async () => {
const exp=['case',
true,
['==', ['zoom'], 555],
null
];
const result = evalExpression(exp, ExpressionMode.dynamic);
expectExpression('==', result);
});

it('(dynamic) case expression simple operands only, positive condition boolean', async () => {
const exp=['case',
true,
555,
null
];
const result = evalExpression(exp, ExpressionMode.dynamic);
expect(result).to.equal(555);
});
it('(dynamic) case expression simple operands only, positive condition number', async () => {
const exp=['case',
1,
555,
null
];
const result = evalExpression(exp, ExpressionMode.dynamic);
expect(result).to.equal(555);
});
});

0 comments on commit 012a268

Please sign in to comment.