Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EmptyStatement #2

Merged
merged 10 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ npm run mtsc ./tests/singleVar.ts

## Exercises

- [ ] Add EmptyStatement.
- [x] Add EmptyStatement.
- [ ] 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.
Expand Down
1 change: 1 addition & 0 deletions baselines/reference/emptyStatement.errors.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions baselines/reference/emptyStatement.js.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"var x = 1;\nvar y = 2"
54 changes: 54 additions & 0 deletions baselines/reference/emptyStatement.tree.baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"locals": {
"x": [
{
"kind": "Var",
"pos": 3
}
],
"y": [
{
"kind": "Var",
"pos": 22
}
]
},
"statements": [
{
"kind": "Var",
"name": {
"kind": "Identifier",
"text": "x"
},
"typename": {
"kind": "Identifier",
"text": "number"
},
"init": {
"kind": "Literal",
"value": 1
}
},
{
"kind": "EmptyStatement"
},
{
"kind": "Var",
"name": {
"kind": "Identifier",
"text": "y"
},
"typename": {
"kind": "Identifier",
"text": "number"
},
"init": {
"kind": "Literal",
"value": 2
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/redeclare.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"kind": "Literal",
"value": 2
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/singleIdentifier.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"kind": "Identifier",
"text": "x"
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/singleTypedVar.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
"kind": "Literal",
"value": 1
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/singleVar.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
"kind": "Literal",
"value": 1
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/twoStatements.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
"value": 2
}
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/twoTypedStatements.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
"value": 2
}
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions baselines/reference/typeAlias.tree.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@
"kind": "Identifier",
"text": "Net"
}
},
{
"kind": "EmptyStatement"
}
]
}
3 changes: 3 additions & 0 deletions src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { resolve } from './bind';
const stringType: Type = { id: 'string' };
const numberType: Type = { id: 'number' };
const errorType: Type = { id: 'error' };
const emptyType: Type = { id: 'empty' };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For bonus points, see what the spec says an empty statement returns and name the type after that.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the spec, it says it returns empty. Just renamed from emptyType to empty imteekay/mini-typescript@6da8ef0 Lmk if this is what you meant for the refactoring.


function typeToString(type: Type) {
return type.id;
Expand Down Expand Up @@ -41,6 +42,8 @@ export function check(module: Module) {
return t;
case Node.TypeAlias:
return checkType(statement.typename);
case Node.EmptyStatement:
return emptyType;
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/emit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Statement, Node, Expression } from './types';

export function emit(statements: Statement[]) {
return statements.map(emitStatement).join(';\n');
return statements.filter(Boolean).map(emitStatement).join(';\n');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would personally leave the empty statements in the output, since the output should be as close as possible to the input, but with types removed.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, just removed the filter imteekay/mini-typescript@6182029

}

function emitStatement(statement: Statement): string {
Expand All @@ -15,6 +15,8 @@ function emitStatement(statement: Statement): string {
)}`;
case Node.TypeAlias:
return `type ${statement.name.text} = ${statement.typename.text}`;
case Node.EmptyStatement:
return '';
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
} from './types';
import { error } from './error';

const emptyTokens = [Token.EOF, Token.Semicolon];

export function parse(lexer: Lexer): Module {
lexer.scan();
return parseModule();
Expand Down Expand Up @@ -69,6 +71,8 @@ export function parse(lexer: Lexer): Module {
parseExpected(Token.Equals);
const typename = parseIdentifier();
return { kind: Node.TypeAlias, name, typename, pos };
} else if (emptyTokens.includes(lexer.token())) {
return { kind: Node.EmptyStatement };
}
return { kind: Node.ExpressionStatement, expr: parseExpression(), pos };
}
Expand Down
2 changes: 2 additions & 0 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ function typescript(statements: Statement[]) {
return [{ ...statement, typename: undefined }];
case Node.TypeAlias:
return [];
case Node.EmptyStatement:
return [];
}
}
}
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export enum Node {
ExpressionStatement,
Var,
TypeAlias,
EmptyStatement,
}

export type Error = {
Expand Down Expand Up @@ -58,7 +59,7 @@ export type Assignment = Location & {
value: Expression;
};

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

export type ExpressionStatement = Location & {
kind: Node.ExpressionStatement;
Expand All @@ -78,6 +79,10 @@ export type TypeAlias = Location & {
typename: Identifier;
};

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

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

export type Symbol = {
Expand Down
1 change: 1 addition & 0 deletions tests/emptyStatement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var x: number = 1;;var y: number = 2;