diff --git a/src/grammar.js b/src/grammar.js index 847d9155..1d4add86 100644 --- a/src/grammar.js +++ b/src/grammar.js @@ -63,6 +63,17 @@ class BinOP extends AST { } } +class TeneryOP extends AST { + constructor(exp, a, b) { + super(); + Object.defineProperty(this, 'value', { + get: () => { + return exp.value ? a.value : b.value; + } + }); + } +} + class FCall extends AST { constructor(f, context, args) { super(); @@ -170,6 +181,15 @@ export const grammar = create({ } }, infix: { + '?': { + precedence: 20, + led(grammar, left) { + const e1 = grammar.expression(0); + grammar.advance(':'); + const e2 = grammar.expression(0); + return new TeneryOP(left, e1, e2); + } + }, '.': { precedence: 1, combine: (left, right) => new ObjectAccess(left, right) @@ -178,6 +198,7 @@ export const grammar = create({ precedence: 1, combine: (left, right) => new ArrayAccess(left, right) }, + ':': {}, ']': {}, ',': {}, ')': {}, diff --git a/tests/simple_test.js b/tests/simple_test.js index 1f4b1389..4826c41e 100644 --- a/tests/simple_test.js +++ b/tests/simple_test.js @@ -95,6 +95,19 @@ describe('expander', () => { }); }); + describe('tenery expression', () => { + it('true 1st.', () => expand("${2 > 1 ? 22 : 11}").then(r => assert.equal(r, 22))); + it('false 2nd.', () => expand("${2 < 1 ? 22 : 11}").then(r => assert.equal(r, 11))); + + describe('combined', () => { + it('false 2nd.', () => expand("${2 < 1 ? 22+1 : 11+1}").then(r => assert.equal(r, 12))); + it('true 2nd.', () => expand("${2*0 < 1 ? 22+1 : 11+1}").then(r => assert.equal(r, 23))); + it('true 2nd. with function call', () => expand("${'a'=='b' ? 22+1 : substring('abc',1,2)}").then(r => + assert.equal(r, + 'b'))); + }); + }); + describe('functions', () => { it('unknown function', () => expand("${thisFunctionIsUnknown()}") .then(e => assert.equal(e, {}))