From d38ab8871902217e18a4dd7dcfa509e28bf31065 Mon Sep 17 00:00:00 2001 From: h-vien Date: Wed, 22 May 2024 15:04:23 +0700 Subject: [PATCH 1/2] :sparkles: feat(binary-expression): implement builder binary --- package/src/__test__/test.test.ts | 2 +- package/src/nodes/expressions/assignment.ts | 2 +- .../src/nodes/expressions/binary/builder.ts | 38 +++++++++++++++++++ .../{binary.ts => binary/index.ts} | 11 ++++-- package/src/nodes/expressions/index.ts | 4 +- package/src/nodes/statements/item.ts | 1 + package/src/tokenizer.ts | 7 ---- 7 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 package/src/nodes/expressions/binary/builder.ts rename package/src/nodes/expressions/{binary.ts => binary/index.ts} (64%) diff --git a/package/src/__test__/test.test.ts b/package/src/__test__/test.test.ts index 54a5b69..51ef2c1 100644 --- a/package/src/__test__/test.test.ts +++ b/package/src/__test__/test.test.ts @@ -37,7 +37,7 @@ describe('Test every thing', () => { in ra (a) a++ }` - const test = ` test = 2 % i ` + const test = ` test = 2 + i -1` const result = parserNode.parse(test, Program) console.log(JSON.stringify(result, null, 2)) }) diff --git a/package/src/nodes/expressions/assignment.ts b/package/src/nodes/expressions/assignment.ts index 5139f86..2912d74 100644 --- a/package/src/nodes/expressions/assignment.ts +++ b/package/src/nodes/expressions/assignment.ts @@ -2,7 +2,7 @@ import { Parser } from '@parser/parser' import { Keyword } from '@parser/constants/keyword' import { Identifier } from '../identifier/index' import { Expression } from './index' -import { BinaryExpression } from './binary' +import { BinaryExpression } from './binary/index' export class AssignmentExpression { type = 'AssignmentExpression' diff --git a/package/src/nodes/expressions/binary/builder.ts b/package/src/nodes/expressions/binary/builder.ts new file mode 100644 index 0000000..f6ba75c --- /dev/null +++ b/package/src/nodes/expressions/binary/builder.ts @@ -0,0 +1,38 @@ +import { Identifier } from '@parser/nodes/identifier/index' +import { Expression } from '../index' +import { Parser } from '@parser/parser' +import { Token } from '@parser/types/token' +import { Operator } from '@parser/types/operator' + +export class BinaryExpressionBuilder { + parser: Parser + constructor(_parser: Parser) { + this.parser = _parser + } + BuilderExpression(builderName: string, operatorToken: Operator) { + let left = this[builderName]?.() + + while (this.parser.nextToken?.type === operatorToken) { + const operator = this.parser.validate(operatorToken).value + const right = this[builderName]() + left = { + type: 'BinaryExpression', + operator, + left, + right + } + } + + return left + } + + AdditiveExpression() { + console.log('vao dau') + return { + type: 'BinaryExpression', + operator: '+', + left: new Identifier(this.parser), + right: new Expression(this.parser) + } + } +} diff --git a/package/src/nodes/expressions/binary.ts b/package/src/nodes/expressions/binary/index.ts similarity index 64% rename from package/src/nodes/expressions/binary.ts rename to package/src/nodes/expressions/binary/index.ts index bfee247..95d4aac 100644 --- a/package/src/nodes/expressions/binary.ts +++ b/package/src/nodes/expressions/binary/index.ts @@ -1,7 +1,10 @@ import { Keyword } from '@parser/constants/keyword' +import { Identifier } from '@parser/nodes/identifier/index' import { Parser } from '@parser/parser' -import { Identifier } from '../identifier/index' -import { Expression } from './index' +import { Expression } from '../index' +import { BinaryExpressionBuilder } from './builder' +import { Operator } from '@parser/types/operator' +import { CLIENT_RENEG_LIMIT } from 'tls' export class BinaryExpression { type = 'BinaryExpression' @@ -13,8 +16,10 @@ export class BinaryExpression { right: Identifier | Expression constructor(parser: Parser, identifier?: Identifier) { + const binaryBuilder = new BinaryExpressionBuilder(parser) this.left = - identifier ?? (parser.nextToken?.type === Keyword.IDENTIFIER ? new Identifier(parser) : new Expression(parser)) + identifier ?? + (parser.nextToken?.type === Keyword.IDENTIFIER ? new Identifier(parser) : binaryBuilder.AdditiveExpression()) switch (parser.nextToken?.type) { case '+': case '-': diff --git a/package/src/nodes/expressions/index.ts b/package/src/nodes/expressions/index.ts index eeea3ee..38935e5 100644 --- a/package/src/nodes/expressions/index.ts +++ b/package/src/nodes/expressions/index.ts @@ -1,7 +1,6 @@ import { Keyword } from '@parser/constants/keyword' import { Parser } from '@parser/parser' import { AssignmentExpression } from './assignment' -import { BinaryExpression } from './binary' import { CallExpression } from './call' import { MemberExpression } from './member' import { UnaryExpression } from './unary' @@ -12,6 +11,7 @@ import { LabelledStatement } from '../statements/label' import { ObjectExpression } from './object' import { Literal } from '../literal/index' import { Identifier } from '../identifier/index' +import { BinaryExpression } from './binary/index' export class Expression { [key: string]: any @@ -90,7 +90,7 @@ export class Expression { switch (parser.nextToken?.type) { case '=': { - Object.assign(this, AssignmentExpression(parser, memberExpression)) + Object.assign(this, new AssignmentExpression(parser, memberExpression)) break } case '(': { diff --git a/package/src/nodes/statements/item.ts b/package/src/nodes/statements/item.ts index cf129c8..ead4b9e 100644 --- a/package/src/nodes/statements/item.ts +++ b/package/src/nodes/statements/item.ts @@ -5,6 +5,7 @@ import { Statement } from './index' export class StatementItem { constructor(parser: Parser) { + console.log(parser.nextToken?.type) switch (parser.nextToken?.type) { case Keyword.LET: case Keyword.CONST: diff --git a/package/src/tokenizer.ts b/package/src/tokenizer.ts index 8377f16..1897520 100644 --- a/package/src/tokenizer.ts +++ b/package/src/tokenizer.ts @@ -68,11 +68,4 @@ export class Tokenizer { throw new SyntaxError(`Unexpected token: "${string[0]}"`) } - - public hasMoreOperator() { - // const operators = ["<", ">", "=", "!=", "===", "!=="]; - // const parts = expression.split(new RegExp(`([${operators.join("")}])`, "g")); - const parts = this.parser.syntax.split('{')[0] - return /[+\-*/%<>=!&|^]+/.test(parts) - } } From 1f348896ef92f4b9403e36ebdc0ab1446de168a5 Mon Sep 17 00:00:00 2001 From: Vien Huynh Date: Thu, 23 May 2024 20:13:47 +0700 Subject: [PATCH 2/2] :sparkles: feat(binary-expresison): implement parse complex binary logic --- package/src/__test__/test.test.ts | 9 +- package/src/constants/keyword.ts | 5 +- package/src/constants/specs.ts | 9 +- .../expressions/__test__/assignment.test.ts | 26 ++--- .../nodes/expressions/__test__/binary.test.ts | 73 ++++++++++-- .../nodes/expressions/__test__/unary.test.ts | 24 ---- package/src/nodes/expressions/assignment.ts | 8 +- .../src/nodes/expressions/binary/builder.ts | 48 +++++--- package/src/nodes/expressions/binary/index.ts | 43 +++---- package/src/nodes/expressions/index.ts | 5 +- .../src/nodes/expressions/parenthesized.ts | 14 +++ package/src/nodes/identifier/index.ts | 5 +- .../statements/breakable/__test__/for.test.ts | 106 ++++++++++-------- .../statements/breakable/iteration/for.ts | 1 - .../statements/breakable/iteration/while.ts | 2 +- package/src/nodes/statements/item.ts | 1 - 16 files changed, 224 insertions(+), 155 deletions(-) delete mode 100644 package/src/nodes/expressions/__test__/unary.test.ts create mode 100644 package/src/nodes/expressions/parenthesized.ts diff --git a/package/src/__test__/test.test.ts b/package/src/__test__/test.test.ts index 51ef2c1..e48fa14 100644 --- a/package/src/__test__/test.test.ts +++ b/package/src/__test__/test.test.ts @@ -1,3 +1,5 @@ +import { transpiler } from '@parser' +import { Expression } from '@parser/nodes/expressions/index' import { Program } from '@parser/program' import { parserNode } from '@parser/test' @@ -37,8 +39,11 @@ describe('Test every thing', () => { in ra (a) a++ }` - const test = ` test = 2 + i -1` + const test = `khai báo a = { + a: 1 + } + in ra(a.a) + ` const result = parserNode.parse(test, Program) - console.log(JSON.stringify(result, null, 2)) }) }) diff --git a/package/src/constants/keyword.ts b/package/src/constants/keyword.ts index de331dd..a1f75e9 100644 --- a/package/src/constants/keyword.ts +++ b/package/src/constants/keyword.ts @@ -63,5 +63,8 @@ export enum Keyword { INSTANCEOF = 'Instanceof', WITH = 'With', DEBUGGER = 'Debugger', - IDENTIFIER = 'Identifier' + IDENTIFIER = 'Identifier', + RELATIONAL_OPERATOR = 'RelationalOperator', + ADDITIVE_OPERATOR = 'AdditiveOperator', + MULTIPLICATIVE_OPERATOR = 'MultiplicativeOperator' } diff --git a/package/src/constants/specs.ts b/package/src/constants/specs.ts index c83d67f..e251fb0 100644 --- a/package/src/constants/specs.ts +++ b/package/src/constants/specs.ts @@ -16,6 +16,14 @@ export const Specs: Array = [ // Skip multi-line comments: [/^\/\*[\S\s]*?\*\//, null], + [/^\+\+/, '++'], // PlusPlus + + // -------------------------------------- + // Math operators: +, -, *, / + [/^[+\-]/, Keyword.ADDITIVE_OPERATOR], + [/^[*\/\%]/, Keyword.MULTIPLICATIVE_OPERATOR], + // Relational operators: >, >=, <, <= + [/^(<=|>=|<|>|==)/, Keyword.RELATIONAL_OPERATOR], // -------------------------------------- // Symbols and delimiters: [/^\[/, '['], // OpenBracket @@ -36,7 +44,6 @@ export const Specs: Array = [ [/^:/, ':'], // Colon [/^\.{3}/, '...'], // Ellipsis [/^\./, '.'], // Dot - [/^\+\+/, '++'], // PlusPlus [/^\+/, '+'], // Plus [/^--/, '--'], // MinusMinus [/^-/, '-'], // Minus diff --git a/package/src/nodes/expressions/__test__/assignment.test.ts b/package/src/nodes/expressions/__test__/assignment.test.ts index ad54c89..2872857 100644 --- a/package/src/nodes/expressions/__test__/assignment.test.ts +++ b/package/src/nodes/expressions/__test__/assignment.test.ts @@ -5,7 +5,7 @@ import { AssignmentExpression } from '../assignment' describe('expression-assignment.test', () => { it('should parse the syntax normally', () => { const result = parserNode.parse('a = 12;', AssignmentExpression) - expect(toPlainObject(result)).toStrictEqual({ + expect(toPlainObject(result)).toEqual({ type: 'AssignmentExpression', left: { type: 'Identifier', @@ -13,24 +13,20 @@ describe('expression-assignment.test', () => { }, operator: '=', right: { - type: 'BinaryExpression', - left: { - type: 'NumericLiteral', - start: 4, - end: 6, - value: 12, - extra: { - rawValue: 12, - raw: '12' - } - }, - right: {} + type: 'NumericLiteral', + start: 4, + end: 6, + value: 12, + extra: { + rawValue: 12, + raw: '12' + } } }) }) it('Should parse the syntax with a complex expression', () => { const result = parserNode.parse('a = 12 + 2;', AssignmentExpression) - expect(toPlainObject(result)).toStrictEqual({ + expect(toPlainObject(result)).toEqual({ type: 'AssignmentExpression', left: { type: 'Identifier', @@ -39,6 +35,7 @@ describe('expression-assignment.test', () => { operator: '=', right: { type: 'BinaryExpression', + operator: '+', left: { type: 'NumericLiteral', start: 4, @@ -49,7 +46,6 @@ describe('expression-assignment.test', () => { raw: '12' } }, - operator: '+', right: { type: 'NumericLiteral', start: 9, diff --git a/package/src/nodes/expressions/__test__/binary.test.ts b/package/src/nodes/expressions/__test__/binary.test.ts index 99297bd..e7c5e97 100644 --- a/package/src/nodes/expressions/__test__/binary.test.ts +++ b/package/src/nodes/expressions/__test__/binary.test.ts @@ -1,26 +1,77 @@ import { parserNode } from '@parser/test' import toPlainObject from '@parser/utils/toPlainObject' -import { BinaryExpression } from '../binary' import { Expression } from '../index' +import { BinaryExpression } from '../binary/index' describe('expression-binary.test', () => { it('should parse the syntax normally', () => { - const result = parserNode.parse('xin chào === hello', Expression) - - expect(toPlainObject(result)).toStrictEqual({ - type: 'BinaryExpression', - operator: '===', + const res = parserNode.parse('a = 1 + 2 ', Expression) + expect(toPlainObject(res)).toEqual({ + type: 'AssignmentExpression', left: { type: 'Identifier', - name: 'xin_ch_224o' + name: 'a' }, + operator: '=', right: { - type: 'Identifier', - name: 'hello' + type: 'BinaryExpression', + operator: '+', + left: { + type: 'NumericLiteral', + start: 4, + end: 5, + value: 1, + extra: { + rawValue: 1, + raw: '1' + } + }, + right: { + type: 'NumericLiteral', + start: 8, + end: 9, + value: 2, + extra: { + rawValue: 2, + raw: '2' + } + } } - } as BinaryExpression) + }) }) it('should parse the syntax normally', () => { - const res = parserNode.parse('a = 1 + 2 ', Expression) + const res = parserNode.parse('a - 1 * 2 ', BinaryExpression) + expect(toPlainObject(res)).toEqual({ + type: 'BinaryExpression', + left: { + type: 'Identifier', + name: 'a' + }, + operator: '-', + right: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'NumericLiteral', + start: 4, + end: 5, + value: 1, + extra: { + rawValue: 1, + raw: '1' + } + }, + right: { + type: 'NumericLiteral', + start: 8, + end: 9, + value: 2, + extra: { + rawValue: 2, + raw: '2' + } + } + } + }) }) }) diff --git a/package/src/nodes/expressions/__test__/unary.test.ts b/package/src/nodes/expressions/__test__/unary.test.ts deleted file mode 100644 index 9a6c21b..0000000 --- a/package/src/nodes/expressions/__test__/unary.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { parserNode } from '@parser/test' -import { UnaryExpression } from '../unary' -import toPlainObject from '@parser/utils/toPlainObject' - -describe('expression-unary.test', () => { - it('should parse the syntax normally', () => { - const result = parserNode.parse('+"12"', UnaryExpression) - expect(toPlainObject(result)).toStrictEqual({ - type: 'UnaryExpression', - operator: '+', - prefix: true, - argument: { - type: 'StringLiteral', - value: '12', - extra: { - rawValue: '12', - raw: '"12"' - }, - start: 1, - end: 5 - } - }) - }) -}) diff --git a/package/src/nodes/expressions/assignment.ts b/package/src/nodes/expressions/assignment.ts index 2912d74..2e6ab66 100644 --- a/package/src/nodes/expressions/assignment.ts +++ b/package/src/nodes/expressions/assignment.ts @@ -3,6 +3,7 @@ import { Keyword } from '@parser/constants/keyword' import { Identifier } from '../identifier/index' import { Expression } from './index' import { BinaryExpression } from './binary/index' +import { BinaryExpressionBuilder } from './binary/builder' export class AssignmentExpression { type = 'AssignmentExpression' @@ -16,11 +17,10 @@ export class AssignmentExpression { constructor(parser: Parser, identifier?: Identifier | Expression) { this.left = identifier ?? (parser.nextToken?.type === Keyword.IDENTIFIER ? new Identifier(parser) : new Expression(parser)) - while (parser.nextToken?.type === '=') { - this.operator = String(parser.validate('=').value) - this.right = new BinaryExpression(parser) - return + this.operator = String(parser.validate(parser.nextToken?.type as any).value) + const binaryBuilder = new BinaryExpressionBuilder(parser, identifier as Identifier) + this.right = binaryBuilder.RelationalExpression() } } } diff --git a/package/src/nodes/expressions/binary/builder.ts b/package/src/nodes/expressions/binary/builder.ts index f6ba75c..02dd9a4 100644 --- a/package/src/nodes/expressions/binary/builder.ts +++ b/package/src/nodes/expressions/binary/builder.ts @@ -1,17 +1,20 @@ -import { Identifier } from '@parser/nodes/identifier/index' -import { Expression } from '../index' +import { Keyword } from '@parser/constants/keyword' import { Parser } from '@parser/parser' import { Token } from '@parser/types/token' -import { Operator } from '@parser/types/operator' +import { UnaryExpression } from '../unary' +import { Literal } from '@parser/nodes/literal/index' +import { Expression } from '../index' +import { Identifier } from '@parser/nodes/identifier/index' export class BinaryExpressionBuilder { parser: Parser - constructor(_parser: Parser) { + identifier?: Identifier + constructor(_parser: Parser, _identifier?: Identifier) { this.parser = _parser + this.identifier = _identifier } - BuilderExpression(builderName: string, operatorToken: Operator) { + BuilderExpression(builderName: string, operatorToken: Token['type']) { let left = this[builderName]?.() - while (this.parser.nextToken?.type === operatorToken) { const operator = this.parser.validate(operatorToken).value const right = this[builderName]() @@ -22,17 +25,36 @@ export class BinaryExpressionBuilder { right } } - return left } AdditiveExpression() { - console.log('vao dau') - return { - type: 'BinaryExpression', - operator: '+', - left: new Identifier(this.parser), - right: new Expression(this.parser) + const res = this.BuilderExpression('MultiplicativeExpression', Keyword.ADDITIVE_OPERATOR) + return res + } + MultiplicativeExpression() { + const res = this.BuilderExpression('PrimaryExpression', Keyword.MULTIPLICATIVE_OPERATOR) + return res + } + RelationalExpression() { + const res = this.BuilderExpression('AdditiveExpression', Keyword.RELATIONAL_OPERATOR) + return res + } + PrimaryExpression() { + switch (this.parser.nextToken?.type) { + case '(': + return this.ParenthesizedExpression() + case Keyword.IDENTIFIER: + return new Identifier(this.parser) + default: + return new Literal(this.parser) } } + + ParenthesizedExpression() { + this.parser.validate('(') + const expression = new Expression(this.parser) + this.parser.validate(')') + return expression + } } diff --git a/package/src/nodes/expressions/binary/index.ts b/package/src/nodes/expressions/binary/index.ts index 95d4aac..553aefc 100644 --- a/package/src/nodes/expressions/binary/index.ts +++ b/package/src/nodes/expressions/binary/index.ts @@ -3,46 +3,29 @@ import { Identifier } from '@parser/nodes/identifier/index' import { Parser } from '@parser/parser' import { Expression } from '../index' import { BinaryExpressionBuilder } from './builder' -import { Operator } from '@parser/types/operator' -import { CLIENT_RENEG_LIMIT } from 'tls' export class BinaryExpression { type = 'BinaryExpression' left: Identifier | Expression - operator: string | undefined + operator?: string - right: Identifier | Expression + right?: Identifier | Expression constructor(parser: Parser, identifier?: Identifier) { - const binaryBuilder = new BinaryExpressionBuilder(parser) this.left = - identifier ?? - (parser.nextToken?.type === Keyword.IDENTIFIER ? new Identifier(parser) : binaryBuilder.AdditiveExpression()) - switch (parser.nextToken?.type) { - case '+': - case '-': - case '*': - case '/': - case '%': - case '**': - case '^': - case '>': - case '>>': - case '>>>': - case '<': - case '<<': - case '<<<': - case '>=': - case '<=': - case '==': - case '===': { - this.operator = String(parser.validate(parser.nextToken?.type).value) - break - } - } + identifier ?? (parser.nextToken?.type === Keyword.IDENTIFIER ? new Identifier(parser) : new Expression(parser)) + + while ( + [Keyword.RELATIONAL_OPERATOR, Keyword.ADDITIVE_OPERATOR, Keyword.MULTIPLICATIVE_OPERATOR].includes( + parser.nextToken?.type as Keyword + ) + ) { + this.operator = String(parser.validate(parser.nextToken?.type as any).value) + const binaryBuilder = new BinaryExpressionBuilder(parser, identifier) - this.right = new Expression(parser) + this.right = binaryBuilder.RelationalExpression() + } } } diff --git a/package/src/nodes/expressions/index.ts b/package/src/nodes/expressions/index.ts index 38935e5..dd1b627 100644 --- a/package/src/nodes/expressions/index.ts +++ b/package/src/nodes/expressions/index.ts @@ -67,7 +67,10 @@ export class Expression { case '>=': case '<=': case '==': - case '===': { + case '===': + case Keyword.ADDITIVE_OPERATOR: + case Keyword.MULTIPLICATIVE_OPERATOR: + case Keyword.RELATIONAL_OPERATOR: { Object.assign(this, new BinaryExpression(parser, identifier)) break } diff --git a/package/src/nodes/expressions/parenthesized.ts b/package/src/nodes/expressions/parenthesized.ts new file mode 100644 index 0000000..a26cb6d --- /dev/null +++ b/package/src/nodes/expressions/parenthesized.ts @@ -0,0 +1,14 @@ +import { Parser } from '@parser/parser' +import { ObjectLiteral } from '../literal/object' +import { Expression } from './index' + +export class ParenthesizedExpression { + type = 'ParenthesizedExpression' + expression: Expression + + constructor(parser: Parser) { + parser.validate('(') + this.expression = new Expression(parser) + parser.validate(')') + } +} diff --git a/package/src/nodes/identifier/index.ts b/package/src/nodes/identifier/index.ts index fa4a10e..6c5f19a 100644 --- a/package/src/nodes/identifier/index.ts +++ b/package/src/nodes/identifier/index.ts @@ -7,10 +7,11 @@ export class Identifier { name: string constructor(parser: Parser) { - this.name = String(parser.validate(Keyword.IDENTIFIER)?.value) + const res = parser.validate(Keyword.IDENTIFIER)?.value + this.name = String(res) .replace(/[^\sA-Za-z]/g, (match) => { // Find vietnamese character and replace - return `_${match.codePointAt(0)}` + return `_${match?.codePointAt(0)}` }) .replace(/\s/g, '_') } diff --git a/package/src/nodes/statements/breakable/__test__/for.test.ts b/package/src/nodes/statements/breakable/__test__/for.test.ts index d671b6b..9212fa2 100644 --- a/package/src/nodes/statements/breakable/__test__/for.test.ts +++ b/package/src/nodes/statements/breakable/__test__/for.test.ts @@ -4,8 +4,7 @@ import { ForStatement } from '../iteration/for' describe('For statement test', () => { it('Should parse for statement correctly', () => { - const result = parserNode.parse('for(let a = 0; a < 10; a = a + 1){return 1;}', ForStatement) - + const result = parserNode.parse('for(let a = 0; a < 10; a++){return 1;}', ForStatement) expect(toPlainObject(result)).toStrictEqual({ type: 'ForStatement', init: { @@ -15,13 +14,13 @@ describe('For statement test', () => { type: 'VariableDeclarator', init: { type: 'NumericLiteral', + start: 12, + end: 13, value: 0, extra: { rawValue: 0, raw: '0' - }, - start: 12, - end: 13 + } }, id: { type: 'Identifier', @@ -40,40 +39,23 @@ describe('For statement test', () => { operator: '<', right: { type: 'NumericLiteral', + start: 19, + end: 21, value: 10, extra: { rawValue: 10, raw: '10' - }, - start: 19, - end: 21 + } } }, update: { - type: 'AssignmentExpression', - left: { + type: 'UpdateExpression', + argument: { type: 'Identifier', name: 'a' }, - operator: '=', - right: { - type: 'BinaryExpression', - left: { - type: 'Identifier', - name: 'a' - }, - operator: '+', - right: { - type: 'NumericLiteral', - value: 1, - extra: { - rawValue: 1, - raw: '1' - }, - start: 31, - end: 32 - } - } + prefix: false, + operator: '++' }, body: { type: 'BlockStatement', @@ -82,13 +64,13 @@ describe('For statement test', () => { type: 'ReturnStatement', argument: { type: 'NumericLiteral', + start: 35, + end: 36, value: 1, extra: { rawValue: 1, raw: '1' - }, - start: 41, - end: 42 + } } } ] @@ -97,7 +79,7 @@ describe('For statement test', () => { }) it('Should parse for statement correctly', () => { - const result = parserNode.parse('lặp(khai báo a = 0; a < 10; a++){return 1;}', ForStatement) + const result = parserNode.parse('lặp(khai báo a = 0; a < 10 - 2 * 2; a++){return 1;}', ForStatement) expect(toPlainObject(result)).toStrictEqual({ type: 'ForStatement', init: { @@ -107,13 +89,13 @@ describe('For statement test', () => { type: 'VariableDeclarator', init: { type: 'NumericLiteral', + start: 17, + end: 18, value: 0, extra: { rawValue: 0, raw: '0' - }, - start: 17, - end: 18 + } }, id: { type: 'Identifier', @@ -131,24 +113,52 @@ describe('For statement test', () => { }, operator: '<', right: { - type: 'NumericLiteral', - value: 10, - extra: { - rawValue: 10, - raw: '10' + type: 'BinaryExpression', + operator: '-', + left: { + type: 'NumericLiteral', + start: 24, + end: 26, + value: 10, + extra: { + rawValue: 10, + raw: '10' + } }, - start: 24, - end: 26 + right: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'NumericLiteral', + start: 29, + end: 30, + value: 2, + extra: { + rawValue: 2, + raw: '2' + } + }, + right: { + type: 'NumericLiteral', + start: 33, + end: 34, + value: 2, + extra: { + rawValue: 2, + raw: '2' + } + } + } } }, update: { type: 'UpdateExpression', - operator: '++', argument: { type: 'Identifier', name: 'a' }, - prefix: false + prefix: false, + operator: '++' }, body: { type: 'BlockStatement', @@ -157,13 +167,13 @@ describe('For statement test', () => { type: 'ReturnStatement', argument: { type: 'NumericLiteral', + start: 48, + end: 49, value: 1, extra: { rawValue: 1, raw: '1' - }, - start: 40, - end: 41 + } } } ] diff --git a/package/src/nodes/statements/breakable/iteration/for.ts b/package/src/nodes/statements/breakable/iteration/for.ts index a07cb6f..09cccd9 100644 --- a/package/src/nodes/statements/breakable/iteration/for.ts +++ b/package/src/nodes/statements/breakable/iteration/for.ts @@ -49,7 +49,6 @@ export class ForStatement { } parser.validate(';') - this.test = new Expression(parser) if (parser.nextToken?.type === ';') { parser.validate(';') diff --git a/package/src/nodes/statements/breakable/iteration/while.ts b/package/src/nodes/statements/breakable/iteration/while.ts index ae5171b..4397f50 100644 --- a/package/src/nodes/statements/breakable/iteration/while.ts +++ b/package/src/nodes/statements/breakable/iteration/while.ts @@ -1,7 +1,7 @@ import { Parser } from '@parser/parser' import { BlockStatement } from '../../block' -import { Expression } from '@parser/nodes/expressions' import { Keyword } from '@parser/constants/keyword' +import { Expression } from '@parser/nodes/expressions/index' export class WhileStatement { type = 'WhileStatement' diff --git a/package/src/nodes/statements/item.ts b/package/src/nodes/statements/item.ts index ead4b9e..cf129c8 100644 --- a/package/src/nodes/statements/item.ts +++ b/package/src/nodes/statements/item.ts @@ -5,7 +5,6 @@ import { Statement } from './index' export class StatementItem { constructor(parser: Parser) { - console.log(parser.nextToken?.type) switch (parser.nextToken?.type) { case Keyword.LET: case Keyword.CONST: