Skip to content

Commit 19422b2

Browse files
Merge pull request #28 from RoboPhred/short-circuit-evaluation
Short circuit evaluation
2 parents 995a736 + 7c6c029 commit 19422b2

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

index.js

+19-3
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,30 @@ module.exports = function (ast, vars) {
4040
}
4141
else if (node.type === 'BinaryExpression' ||
4242
node.type === 'LogicalExpression') {
43+
var op = node.operator;
44+
45+
if (op === '&&') {
46+
var l = walk(node.left);
47+
if (l === FAIL) return FAIL;
48+
if (!l) return l;
49+
var r = walk(node.right);
50+
if (r === FAIL) return FAIL;
51+
return r;
52+
}
53+
else if (op === '||') {
54+
var l = walk(node.left);
55+
if (l === FAIL) return FAIL;
56+
if (l) return l;
57+
var r = walk(node.right);
58+
if (r === FAIL) return FAIL;
59+
return r;
60+
}
61+
4362
var l = walk(node.left);
4463
if (l === FAIL) return FAIL;
4564
var r = walk(node.right);
4665
if (r === FAIL) return FAIL;
4766

48-
var op = node.operator;
4967
if (op === '==') return l == r;
5068
if (op === '===') return l === r;
5169
if (op === '!=') return l != r;
@@ -62,8 +80,6 @@ module.exports = function (ast, vars) {
6280
if (op === '|') return l | r;
6381
if (op === '&') return l & r;
6482
if (op === '^') return l ^ r;
65-
if (op === '&&') return l && r;
66-
if (op === '||') return l || r;
6783

6884
return FAIL;
6985
}

test/eval.js

+26
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,29 @@ test('constructor at runtime only', function(t) {
121121
var res = evaluate(ast);
122122
t.equal(res, undefined);
123123
});
124+
125+
test('short circuit evaluation AND', function(t) {
126+
t.plan(1);
127+
128+
var variables = {
129+
value: null
130+
};
131+
var src = 'value && value.func()';
132+
var ast = parse(src).body[0].expression;
133+
var res = evaluate(ast, variables);
134+
t.equals(res, null);
135+
})
136+
137+
test('short circuit evaluation OR', function(t) {
138+
t.plan(1);
139+
140+
var fnInvoked = false;
141+
var variables = {
142+
value: true,
143+
fn: function() { fnInvoked = true}
144+
};
145+
var src = 'value || fn()';
146+
var ast = parse(src).body[0].expression;
147+
evaluate(ast, variables);
148+
t.equals(fnInvoked, false);
149+
})

0 commit comments

Comments
 (0)