diff --git a/src/parser.ts b/src/parser.ts index 273caca..bb3ee1a 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -189,10 +189,18 @@ function parseExpression(body: Token[]): AST | null { return new CallExpression(callee, args) } else if (second.value === '.' || second.value === '[') { - // TODO: CallExpression from accessor (e.g. array.length()) const object = new Identifier(first.value) const property = parseExpression([body[2]])! - return new MemberExpression(object, property) + const left = new MemberExpression(object, property) + + // e.g. array.length() + if (body[3]?.value === '(' && last.value === ')') { + const right = parseExpression(body.slice(2))! as CallExpression + right.callee = left + return right + } + + return left } } @@ -452,6 +460,8 @@ const glsl = /* glsl */ `#version 300 es } method(true); + + foo.bar(); ` console.log(glsl) diff --git a/tests/parser.test.ts b/tests/parser.test.ts index fb5a8f5..bdd6437 100644 --- a/tests/parser.test.ts +++ b/tests/parser.test.ts @@ -86,12 +86,25 @@ describe('parser', () => { }) it('parses member expressions', () => { - const expression = parse('foo.bar')[0] as MemberExpression - expect(expression).toBeInstanceOf(MemberExpression) - expect(expression.object).toBeInstanceOf(Identifier) - expect((expression.object as Identifier).value).toBe('foo') - expect(expression.property).toBeInstanceOf(Identifier) - expect((expression.property as Identifier).value).toBe('bar') + { + const expression = parse('foo.bar')[0] as MemberExpression + expect(expression).toBeInstanceOf(MemberExpression) + expect(expression.object).toBeInstanceOf(Identifier) + expect((expression.object as Identifier).value).toBe('foo') + expect(expression.property).toBeInstanceOf(Identifier) + expect((expression.property as Identifier).value).toBe('bar') + } + + { + const expression = parse('array.length()')[0] as CallExpression + expect(expression).toBeInstanceOf(CallExpression) + expect(expression.callee).toBeInstanceOf(MemberExpression) + expect((expression.callee as MemberExpression).object).toBeInstanceOf(Identifier) + expect(((expression.callee as MemberExpression).object as Identifier).value).toBe('array') + expect((expression.callee as MemberExpression).property).toBeInstanceOf(Identifier) + expect(((expression.callee as MemberExpression).property as Identifier).value).toBe('length') + expect(expression.args.length).toBe(0) + } }) }) })