diff --git a/README.md b/README.md index 005bfbf..252246f 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/baselines/reference/emptyStatement.errors.baseline b/baselines/reference/emptyStatement.errors.baseline new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/baselines/reference/emptyStatement.errors.baseline @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/baselines/reference/emptyStatement.js.baseline b/baselines/reference/emptyStatement.js.baseline new file mode 100644 index 0000000..2e84a10 --- /dev/null +++ b/baselines/reference/emptyStatement.js.baseline @@ -0,0 +1 @@ +"var x = 1;\nvar y = 2" \ No newline at end of file diff --git a/baselines/reference/emptyStatement.tree.baseline b/baselines/reference/emptyStatement.tree.baseline new file mode 100644 index 0000000..8756c29 --- /dev/null +++ b/baselines/reference/emptyStatement.tree.baseline @@ -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" + } + ] +} \ No newline at end of file diff --git a/baselines/reference/redeclare.tree.baseline b/baselines/reference/redeclare.tree.baseline index 3db0ddc..ab40597 100644 --- a/baselines/reference/redeclare.tree.baseline +++ b/baselines/reference/redeclare.tree.baseline @@ -29,6 +29,9 @@ "kind": "Literal", "value": 2 } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/singleIdentifier.tree.baseline b/baselines/reference/singleIdentifier.tree.baseline index cf42d16..f1a7720 100644 --- a/baselines/reference/singleIdentifier.tree.baseline +++ b/baselines/reference/singleIdentifier.tree.baseline @@ -7,6 +7,9 @@ "kind": "Identifier", "text": "x" } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/singleTypedVar.tree.baseline b/baselines/reference/singleTypedVar.tree.baseline index 118b054..a4a6855 100644 --- a/baselines/reference/singleTypedVar.tree.baseline +++ b/baselines/reference/singleTypedVar.tree.baseline @@ -22,6 +22,9 @@ "kind": "Literal", "value": 1 } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/singleVar.tree.baseline b/baselines/reference/singleVar.tree.baseline index 1559bef..6b8a7ae 100644 --- a/baselines/reference/singleVar.tree.baseline +++ b/baselines/reference/singleVar.tree.baseline @@ -18,6 +18,9 @@ "kind": "Literal", "value": 1 } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/twoStatements.tree.baseline b/baselines/reference/twoStatements.tree.baseline index bb7a410..d0a79c9 100644 --- a/baselines/reference/twoStatements.tree.baseline +++ b/baselines/reference/twoStatements.tree.baseline @@ -32,6 +32,9 @@ "value": 2 } } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/twoTypedStatements.tree.baseline b/baselines/reference/twoTypedStatements.tree.baseline index 81397a4..dd3c638 100644 --- a/baselines/reference/twoTypedStatements.tree.baseline +++ b/baselines/reference/twoTypedStatements.tree.baseline @@ -36,6 +36,9 @@ "value": 2 } } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/baselines/reference/typeAlias.tree.baseline b/baselines/reference/typeAlias.tree.baseline index 7de7ce9..9c997c9 100644 --- a/baselines/reference/typeAlias.tree.baseline +++ b/baselines/reference/typeAlias.tree.baseline @@ -192,6 +192,9 @@ "kind": "Identifier", "text": "Net" } + }, + { + "kind": "EmptyStatement" } ] } \ No newline at end of file diff --git a/src/check.ts b/src/check.ts index 59fd0ac..e1d5744 100644 --- a/src/check.ts +++ b/src/check.ts @@ -13,6 +13,7 @@ import { resolve } from './bind'; const stringType: Type = { id: 'string' }; const numberType: Type = { id: 'number' }; const errorType: Type = { id: 'error' }; +const empty: Type = { id: 'empty' }; function typeToString(type: Type) { return type.id; @@ -41,6 +42,8 @@ export function check(module: Module) { return t; case Node.TypeAlias: return checkType(statement.typename); + case Node.EmptyStatement: + return empty; } } diff --git a/src/emit.ts b/src/emit.ts index c47aab7..90a5309 100644 --- a/src/emit.ts +++ b/src/emit.ts @@ -15,6 +15,8 @@ function emitStatement(statement: Statement): string { )}`; case Node.TypeAlias: return `type ${statement.name.text} = ${statement.typename.text}`; + case Node.EmptyStatement: + return ''; } } diff --git a/src/parse.ts b/src/parse.ts index af55465..45ab4d2 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -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(); @@ -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 }; } diff --git a/src/transform.ts b/src/transform.ts index fa1c396..2469267 100644 --- a/src/transform.ts +++ b/src/transform.ts @@ -16,6 +16,8 @@ function typescript(statements: Statement[]) { return [{ ...statement, typename: undefined }]; case Node.TypeAlias: return []; + case Node.EmptyStatement: + return []; } } } diff --git a/src/types.ts b/src/types.ts index 2918ecc..c318ebb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,6 +29,7 @@ export enum Node { ExpressionStatement, Var, TypeAlias, + EmptyStatement, } export type Error = { @@ -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; @@ -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 = { diff --git a/tests/emptyStatement.ts b/tests/emptyStatement.ts new file mode 100644 index 0000000..978c06e --- /dev/null +++ b/tests/emptyStatement.ts @@ -0,0 +1 @@ +var x: number = 1;;var y: number = 2;