Skip to content

Commit 34618c6

Browse files
committed
#787: improved code generation strategy
1 parent 4071edb commit 34618c6

4 files changed

Lines changed: 27 additions & 41 deletions

File tree

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

22
import Token from './models/Token';
33
import { TokenType } from './definitions/TokenType';
4-
import { Keyword } from './definitions/Keyword';
4+
5+
const NO_TOKEN = new Token(TokenType.NONE, '', -1, 0);
56

67
export default class Coder
78
{
@@ -27,62 +28,46 @@ export default class Coder
2728
generate(): string
2829
{
2930
let code = '';
30-
let previous: Token = new Token(TokenType.NOTHING, '', 0, 0);
31-
32-
for (const current of this.#tokens)
31+
32+
for (let index = 0; index < this.#tokens.length; index++)
3333
{
34-
const prefix = this.#needsSpacingBefore(current, previous) ? ' ' : '';
35-
const postfix = this.#needsSpacingAfter(current) ? ' ' : '';
34+
const previous = this.#tokens[index - 1] ?? NO_TOKEN;
35+
const current = this.#tokens[index];
36+
const next = this.#tokens[index + 1] ?? NO_TOKEN;
37+
38+
const prefix = this.#needsSpacingBefore(previous, current) ? ' ' : '';
39+
const postfix = this.#needsSpacingAfter(current, next) ? ' ' : '';
3640

3741
code += `${prefix}${current.value}${postfix}`;
38-
39-
previous = current;
4042
}
4143

4244
return code;
4345
}
4446

45-
#needsSpacingBefore(current: Token, previous: Token): boolean
47+
#needsSpacingBefore(previous: Token, current: Token): boolean
4648
{
47-
if (current.isType(TokenType.KEYWORD) && this.#isInfixKeyword(current))
49+
if (current.isType(TokenType.KEYWORD) && this.#isTextType(previous))
4850
{
4951
return true;
5052
}
51-
else if (previous.isType(TokenType.OPERATOR) && current.isType(TokenType.OPERATOR))
53+
else if (current.isType(TokenType.OPERATOR) && previous.isType(TokenType.OPERATOR))
5254
{
5355
return true;
5456
}
5557

5658
return false;
5759
}
5860

59-
#needsSpacingAfter(current: Token): boolean
60-
{
61-
return current.isType(TokenType.KEYWORD) && this.#isPrefixKeyword(current);
62-
}
63-
64-
#isPrefixKeyword(token: Token): boolean
61+
#needsSpacingAfter(current: Token, next: Token): boolean
6562
{
66-
return this.#isInfixKeyword(token)
67-
|| token.hasValue(Keyword.VAR)
68-
|| token.hasValue(Keyword.LET)
69-
|| token.hasValue(Keyword.CONST)
70-
|| token.hasValue(Keyword.FUNCTION)
71-
|| token.hasValue(Keyword.CLASS)
72-
|| token.hasValue(Keyword.USING)
73-
|| token.hasValue(Keyword.RETURN)
74-
|| token.hasValue(Keyword.ASYNC)
75-
|| token.hasValue(Keyword.AWAIT)
76-
|| token.hasValue(Keyword.YIELD)
77-
|| token.hasValue(Keyword.NEW)
78-
|| token.hasValue(Keyword.THROW);
63+
return current.isType(TokenType.KEYWORD) && (next.isType(TokenType.KEYWORD) || this.#isTextType(next));
7964
}
8065

81-
#isInfixKeyword(token: Token): boolean
66+
#isTextType(token: Token)
8267
{
83-
return token.hasValue(Keyword.OF)
84-
|| token.hasValue(Keyword.IN)
85-
|| token.hasValue(Keyword.AS)
86-
|| token.hasValue(Keyword.FROM);
68+
return token.isType(TokenType.IDENTIFIER)
69+
|| token.isType(TokenType.BOOLEAN)
70+
|| token.isType(TokenType.NOTHING)
71+
|| token.isType(TokenType.NUMBER);
8772
}
8873
}

packages/analysis/src/static/definitions/TokenType.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const TokenType =
1515
INDICATOR: 'indicator',
1616
REGEX: 'regex',
1717
SCOPE: 'scope',
18-
WHITESPACE: 'whitespace'
18+
WHITESPACE: 'whitespace',
19+
NONE: 'none'
1920
};
2021

2122
export { TokenType };

packages/analysis/test/static/Parser.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('Parser', () =>
5252
{
5353
const expression = parser.parseStatement(VALUES.IF_ELSE);
5454
expect(expression).toBeInstanceOf(ESExpression);
55-
expect(expression.toString(false)).toEqual('if(true){return "value1";}else{return "value2";}');
55+
expect(expression.toString(false)).toEqual('if(true){return"value1";}else{return"value2";}');
5656
});
5757

5858
it('should parse an try...catch...finally expression', () =>
@@ -557,7 +557,7 @@ describe('Parser', () =>
557557
expect(variable.binding).toBeInstanceOf(ESIdentifierBinding);
558558
expect(variable.type).toEqual('const');
559559
expect(variable.initializer).toBeInstanceOf(ESExpression);
560-
expect(variable.initializer?.toString(false)).toEqual(' as ');
560+
expect(variable.initializer?.toString(false)).toEqual('as');
561561
});
562562
});
563563

@@ -928,7 +928,7 @@ describe('Parser', () =>
928928

929929
expect(funktion.identifier).toEqual('name');
930930
expect(funktion.isAsync).toBeFalsy();
931-
expect(funktion.body.toString()).toEqual("{return 'value';}");
931+
expect(funktion.body.toString()).toEqual("{return'value';}");
932932

933933
const parameters = funktion.parameters;
934934
expect(parameters).toHaveLength(0);
@@ -940,7 +940,7 @@ describe('Parser', () =>
940940

941941
expect(funktion.identifier).toEqual('name');
942942
expect(funktion.isAsync).toBeFalsy();
943-
expect(funktion.body.toString()).toEqual("{if(true){return 'value';}}");
943+
expect(funktion.body.toString()).toEqual("{if(true){return'value';}}");
944944

945945
const parameters = funktion.parameters;
946946
expect(parameters).toHaveLength(0);

packages/analysis/test/static/fixtures/modules.fixture.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export {Person};
8282
class Person{#name;#age;constructor(name,age) {this.#name=name;this.#age=age;}}
8383
const peter=new Person(name,42);
8484
async function async(){}
85-
const a=async ;
85+
const a=async;
8686
const b=async ()=>{};
8787
const as=12;
8888
export {as as hi};

0 commit comments

Comments
 (0)