diff --git a/src/index.ts b/src/index.ts index e975a07..ede6fec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,7 +45,7 @@ class ExpressionParser { } private tokenize(expression: string): string[] { - const regex = /([-+*/(),<>!=%^\[\]])|\b(?:\d+(\.\d+)?)|(?:"[^"]*")|(?:'[^']*')|(?:\w+)/g; + const regex = /([-+*/():,<>!=%^\[\]\{\}])|\b(?:\d+(\.\d+)?)|(?:"[^"]*")|(?:'[^']*')|(?:\w+)/g; return expression.match(regex) || []; } @@ -99,6 +99,43 @@ class ExpressionParser { return array; } + private parseObject(state: ParserState): object { + const obj: { [key: string]: any } = {}; + while (true) { + const key = state.currentToken; + if (typeof key !== 'string') { + throw new Error('Invalid object literal'); + } + state.nextToken(); + if (state.currentToken !== ':') { + throw new Error('Invalid object literal'); + } + + state.nextToken(); + + const value = this.parseExpression(state); + obj[key] = value; + + if (state.currentToken as any === '}') { + break; + } + + if (state.currentToken as any !== ',') { + throw new Error('Invalid object literal'); + } + + state.nextToken(); + } + + if (state.currentToken as any !== '}') { + throw new Error('Invalid object literal'); + } + + state.nextToken(); + + return obj; + } + private parseFunction(state: ParserState): any { const token = state.currentToken; const func = state.functions[token]; @@ -129,13 +166,13 @@ class ExpressionParser { } private parseFactor(state: ParserState): any { - let value: number | string | boolean | any[] = 0; + let value: number | string | boolean | any[] | object = 0; const token = state.currentToken; if (token === undefined) { throw new Error('Invalid expression'); } - + console.log(token) if (token === '(') { state.nextToken(); value = this.parseExpression(state); @@ -167,6 +204,9 @@ class ExpressionParser { const factor = this.parseFactor(state); value = operator(0, factor); + } else if (token === '{') { + state.nextToken() + value = this.parseObject(state); } else { throw new Error('Invalid expression'); } diff --git a/src/test/index.test.ts b/src/test/index.test.ts index 83008b0..88ec57a 100644 --- a/src/test/index.test.ts +++ b/src/test/index.test.ts @@ -39,15 +39,15 @@ describe('Example', () => { expect(parser.evaluate("[2 + 5, 5]")).toEqual([7, 5]) expect(parser.evaluate("[5, x]", { x: 2 })).toEqual([5, 2]) }) - // it('object', () => { - // const parser = new ExpressionParser(); - // expect(parser.evaluate("{ name: 'ADI', age: 20 }")).toEqual({ - // name: "ADI", - // age: 20 - // }) - // expect(parser.evaluate("{ name: 'ADI', age: 5 + 2 }")).toEqual({ - // name: "ADI", - // age: 7 - // }) - // }) + it('object', () => { + const parser = new ExpressionParser(); + expect(parser.evaluate("{ name: 'ADI', age: 20 }")).toEqual({ + name: "ADI", + age: 20 + }) + expect(parser.evaluate("{ name: 'ADI', age: 5 + 2 }")).toEqual({ + name: "ADI", + age: 7 + }) + }) }); \ No newline at end of file