Skip to content

Commit

Permalink
Use semicolon as terminator and peek to add empty statement
Browse files Browse the repository at this point in the history
  • Loading branch information
imteekay committed May 16, 2023
1 parent 3c75ed2 commit b74b6fc
Show file tree
Hide file tree
Showing 16 changed files with 20 additions and 61 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ npm run mtsc ./tests/singleVar.ts
- [x] Add EmptyStatement (https://github.com/imteekay/mini-typescript/pull/2).
- [x] Make semicolon a statement ender, not statement separator.
- Hint: You'll need a predicate to peek at the next token and decide if it's the start of an element.
- Bonus: Switch from semicolon to newline as statement ender.
- [ ] Bonus: Switch from semicolon to newline as statement ender.
- [x] Add string literals (https://github.com/imteekay/mini-typescript/pull/4).
- [x] Refactor: rename `Literal` to `NumericLiteral` (https://github.com/imteekay/mini-typescript/pull/6).
- [ ] Add let.
Expand Down
3 changes: 0 additions & 3 deletions baselines/reference/emptyStatement.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@
"kind": "NumericLiteral",
"value": 2
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/redeclare.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
"kind": "NumericLiteral",
"value": 2
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/singleIdentifier.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
"kind": "Identifier",
"text": "x"
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/singleTypedVar.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@
"value": "test",
"isSingleQuote": true
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/singleVar.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
"kind": "NumericLiteral",
"value": 1
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/stringLiteral.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@
"value": "escaped\nR",
"isSingleQuote": true
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/terminator.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@
"kind": "Identifier",
"text": "z"
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/twoStatements.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
"value": 2
}
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/twoTypedStatements.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@
"value": 2
}
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions baselines/reference/typeAlias.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,6 @@
"kind": "Identifier",
"text": "Net"
}
},
{
"kind": "EndOfFile"
}
]
}
3 changes: 0 additions & 3 deletions src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const stringType: Type = { id: 'string' };
const numberType: Type = { id: 'number' };
const errorType: Type = { id: 'error' };
const empty: Type = { id: 'empty' };
const eof: Type = { id: 'eof' };

function typeToString(type: Type) {
return type.id;
Expand Down Expand Up @@ -45,8 +44,6 @@ export function check(module: Module) {
return checkType(statement.typename);
case Node.EmptyStatement:
return empty;
case Node.EndOfFile:
return eof;
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/emit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ function emitStatement(statement: Statement): string {
return `type ${statement.name.text} = ${statement.typename.text}`;
case Node.EmptyStatement:
return '';
case Node.EndOfFile:
return '';
}
}

Expand Down
31 changes: 18 additions & 13 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export function parse(lexer: Lexer): Module {

function parseModule(): Module {
return {
statements: parseStatements(parseStatement),
statements: parseStatements(
parseStatement,
() => tryParseToken(Token.Semicolon),
() => lexer.token() === Token.Semicolon,
),
locals: new Map(),
};
}
Expand Down Expand Up @@ -63,9 +67,7 @@ export function parse(lexer: Lexer): Module {
function parseStatement(): Statement {
const pos = lexer.pos();

if (tryParseToken(Token.EOF)) {
return { kind: Node.EndOfFile };
} else if (tryParseToken(Token.Var)) {
if (tryParseToken(Token.Var)) {
const name = parseIdentifier();
const typename = tryParseToken(Token.Colon)
? parseIdentifier()
Expand All @@ -78,13 +80,8 @@ export function parse(lexer: Lexer): Module {
parseExpected(Token.Equals);
const typename = parseIdentifier();
return { kind: Node.TypeAlias, name, typename, pos };
} else if (tryParseToken(Token.Semicolon)) {
// if a semicolon is followed by another semicolon,
// it should return an empty statement
if (lexer.token() === Token.Semicolon) {
return { kind: Node.EmptyStatement };
}
return parseStatement();
} else if (lexer.token() === Token.Semicolon) {
return { kind: Node.EmptyStatement };
}
return { kind: Node.ExpressionStatement, expr: parseExpression(), pos };
}
Expand All @@ -108,10 +105,18 @@ export function parse(lexer: Lexer): Module {
}
}

function parseStatements<T>(element: () => T) {
function parseStatements<T>(
element: () => T,
terminator: () => boolean,
peek: () => boolean,
) {
const list = [element()];
while (lexer.token() !== Token.EOF) {
list.push(element());
if (terminator()) {
if (peek()) list.push(element());
} else {
list.push(element());
}
}
return list;
}
Expand Down
2 changes: 0 additions & 2 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ function typescript(statements: Statement[]) {
return [];
case Node.EmptyStatement:
return [];
case Node.EndOfFile:
return [];
}
}
}
11 changes: 1 addition & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,7 @@ export type Assignment = Location & {
value: Expression;
};

export type Statement =
| ExpressionStatement
| Var
| TypeAlias
| EmptyStatement
| EndOfFile;
export type Statement = ExpressionStatement | Var | TypeAlias | EmptyStatement;

export type ExpressionStatement = Location & {
kind: Node.ExpressionStatement;
Expand All @@ -102,10 +97,6 @@ export type EmptyStatement = {
kind: Node.EmptyStatement;
};

export type EndOfFile = {
kind: Node.EndOfFile;
};

export type Declaration = Var | TypeAlias; // plus others, like function

export type Symbol = {
Expand Down

0 comments on commit b74b6fc

Please sign in to comment.