Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
96 changes: 64 additions & 32 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ export class Parser extends DiagnosticEmitter {
let parameters: TypeNode[] | null = null;

// Name<T>
if (tn.skip(Token.LessThan)) {
if (!tn.peekOnNewLine() && tn.skip(Token.LessThan)) {
do {
let parameter = this.parseType(tn, true, suppressErrors);
if (!parameter) return null;
Expand Down Expand Up @@ -703,7 +703,7 @@ export class Parser extends DiagnosticEmitter {
}
}
// ... [][]
while (tn.skip(Token.OpenBracket)) {
while (!tn.peekOnNewLine() && tn.skip(Token.OpenBracket)) {
let bracketStart = tn.tokenPos;
if (!tn.skip(Token.CloseBracket)) {
if (!suppressErrors) {
Expand Down Expand Up @@ -991,7 +991,8 @@ export class Parser extends DiagnosticEmitter {
} while (tn.skip(Token.Comma));

let ret = Node.createVariableStatement(decorators, declarations, tn.range(startPos, tn.pos));
if (!tn.skip(Token.Semicolon) && !isFor) this.checkASI(tn);
if (isFor) tn.skip(Token.Semicolon);
else this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -1019,7 +1020,8 @@ export class Parser extends DiagnosticEmitter {
);
}
let flags = parentFlags;
if (tn.skip(Token.Exclamation)) {
if (tn.peek() == Token.Exclamation && !tn.peekOnNewLine()) {
tn.next();
flags |= CommonFlags.DefinitelyAssigned;
}

Expand Down Expand Up @@ -1175,7 +1177,7 @@ export class Parser extends DiagnosticEmitter {
}

let ret = Node.createReturnStatement(expr, tn.range(startPos, tn.pos));
if (!tn.skip(Token.Semicolon)) this.checkASI(tn);
this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -1601,7 +1603,8 @@ export class Parser extends DiagnosticEmitter {
tn.range(startPos, tn.pos)
);
ret.overriddenModuleName = this.currentModuleName;
tn.skip(Token.Semicolon);
if (body) tn.skip(Token.Semicolon);
else this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -1669,6 +1672,13 @@ export class Parser extends DiagnosticEmitter {
}

if (arrowKind) {
if (tn.peek() == Token.Equals_GreaterThan && tn.peekOnNewLine()) {
this.error(
DiagnosticCode.Unexpected_token,
tn.range(tn.nextTokenPos)
);
return null;
}
if (!tn.skip(Token.Equals_GreaterThan)) {
this.error(
DiagnosticCode._0_expected,
Expand Down Expand Up @@ -2203,7 +2213,7 @@ export class Parser extends DiagnosticEmitter {
}
return null;
}
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return retIndex;
}
if (!tn.skipIdentifier(IdentifierHandling.Always)) {
Expand Down Expand Up @@ -2367,8 +2377,10 @@ export class Parser extends DiagnosticEmitter {
body,
tn.range(startPos, tn.pos)
);
if (!(isInterface && tn.skip(Token.Comma))) {
tn.skip(Token.Semicolon);
let hasComma = isInterface && tn.skip(Token.Comma);
if (!hasComma) {
if (body) tn.skip(Token.Semicolon);
else this.parseSemicolon(tn);
}
return retMethod;

Expand Down Expand Up @@ -2421,7 +2433,8 @@ export class Parser extends DiagnosticEmitter {
tn.range(startPos, tn.pos)
);
}
if (tn.skip(Token.Exclamation)) {
if (tn.peek() == Token.Exclamation && !tn.peekOnNewLine()) {
tn.next();
flags |= CommonFlags.DefinitelyAssigned;
}
if (tn.skip(Token.Colon)) {
Expand Down Expand Up @@ -2465,9 +2478,7 @@ export class Parser extends DiagnosticEmitter {
initializer,
range
);
if (!(isInterface && tn.skip(Token.Comma))) {
tn.skip(Token.Semicolon);
}
if (!(isInterface && tn.skip(Token.Comma))) this.parseSemicolon(tn);
return retField;
}
return null;
Expand Down Expand Up @@ -2656,7 +2667,7 @@ export class Parser extends DiagnosticEmitter {
this.seenlog.add(internalPath);
}
}
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
} else if (tn.skip(Token.Asterisk)) {
if (tn.skip(Token.From)) {
Expand All @@ -2672,7 +2683,7 @@ export class Parser extends DiagnosticEmitter {
this.dependees.set(internalPath, new Dependee(currentSource, path));
this.backlog.push(internalPath);
}
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -2754,7 +2765,7 @@ export class Parser extends DiagnosticEmitter {
range
)
], null, false, tn.range(startPos, tn.pos));
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -2844,7 +2855,7 @@ export class Parser extends DiagnosticEmitter {
this.dependees.set(internalPath, new Dependee(assert(this.currentSource), path));
this.backlog.push(internalPath);
}
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -2915,7 +2926,7 @@ export class Parser extends DiagnosticEmitter {
if (tn.skipIdentifier()) {
let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
let ret = Node.createExportImportStatement(identifier, asIdentifier, tn.range(startPos, tn.pos));
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -3078,7 +3089,7 @@ export class Parser extends DiagnosticEmitter {
identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
}
let ret = Node.createBreakStatement(identifier, tn.range());
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
}

Expand All @@ -3094,7 +3105,7 @@ export class Parser extends DiagnosticEmitter {
identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
}
let ret = Node.createContinueStatement(identifier, tn.range());
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -3140,7 +3151,8 @@ export class Parser extends DiagnosticEmitter {
}

parseExpressionStatement(
tn: Tokenizer
tn: Tokenizer,
isFor: bool = false
): ExpressionStatement | null {

// at previous token
Expand All @@ -3149,7 +3161,8 @@ export class Parser extends DiagnosticEmitter {
if (!expr) return null;

let ret = Node.createExpressionStatement(expr);
tn.skip(Token.Semicolon);
if (isFor) tn.skip(Token.Semicolon);
else this.parseSemicolon(tn);
return ret;
}

Expand All @@ -3172,7 +3185,7 @@ export class Parser extends DiagnosticEmitter {
initializer = this.parseVariable(tn, CommonFlags.None, null, tn.tokenPos, true);

} else if (!tn.skip(Token.Semicolon)) {
initializer = this.parseExpressionStatement(tn);
initializer = this.parseExpressionStatement(tn, true);
if (!initializer) return null;
}

Expand Down Expand Up @@ -3234,7 +3247,7 @@ export class Parser extends DiagnosticEmitter {
if (tn.token == Token.Semicolon) {
let condition: ExpressionStatement | null = null;
if (!tn.skip(Token.Semicolon)) {
condition = this.parseExpressionStatement(tn);
condition = this.parseExpressionStatement(tn, true);
if (!condition) return null;
}

Expand Down Expand Up @@ -3375,7 +3388,6 @@ export class Parser extends DiagnosticEmitter {
switchCases.push(switchCase);
}
let ret = Node.createSwitchStatement(condition, switchCases, tn.range(startPos, tn.pos));
tn.skip(Token.Semicolon);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -3467,10 +3479,17 @@ export class Parser extends DiagnosticEmitter {
// at 'throw': Expression ';'?

let startPos = tn.tokenPos;
if (tn.peekOnNewLine()) {
this.error(
DiagnosticCode.Unexpected_token,
tn.range(tn.nextTokenPos)
);
return null;
}
let expression = this.parseExpression(tn);
if (!expression) return null;
let ret = Node.createThrowStatement(expression, tn.range(startPos, tn.pos));
if (!tn.skip(Token.Semicolon)) this.checkASI(tn);
this.parseSemicolon(tn);
return ret;
}

Expand Down Expand Up @@ -3561,7 +3580,6 @@ export class Parser extends DiagnosticEmitter {
finallyStatements,
tn.range(startPos, tn.pos)
);
tn.skip(Token.Semicolon);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -3608,7 +3626,7 @@ export class Parser extends DiagnosticEmitter {
type,
tn.range(startPos, tn.pos)
);
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
ret.overriddenModuleName = this.currentModuleName;
return ret;
} else {
Expand Down Expand Up @@ -3638,7 +3656,7 @@ export class Parser extends DiagnosticEmitter {
let moduleName = tn.readString();
let ret = Node.createModuleDeclaration(moduleName, flags, tn.range(startPos, tn.pos));
this.currentModuleName = moduleName;
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
}

Expand All @@ -3649,10 +3667,10 @@ export class Parser extends DiagnosticEmitter {
// at 'void': Expression ';'?

let startPos = tn.tokenPos;
let expression = this.parseExpression(tn, Precedence.Grouping);
let expression = this.parseExpression(tn, Precedence.UnaryPrefix);
if (!expression) return null;
let ret = Node.createVoidStatement(expression, tn.range(startPos, tn.pos));
tn.skip(Token.Semicolon);
this.parseSemicolon(tn);
return ret;
}

Expand All @@ -3670,7 +3688,6 @@ export class Parser extends DiagnosticEmitter {
let statement = this.parseStatement(tn);
if (!statement) return null;
let ret = Node.createWhileStatement(expression, statement, tn.range(startPos, tn.pos));
tn.skip(Token.Semicolon);
return ret;
} else {
this.error(
Expand Down Expand Up @@ -4131,6 +4148,15 @@ export class Parser extends DiagnosticEmitter {
while (
(nextPrecedence = determinePrecedence(tn.peek())) >= precedence
) {
let nextToken = tn.peek();
if (
(
nextToken == Token.Plus_Plus ||
nextToken == Token.Minus_Minus ||
nextToken == Token.As ||
nextToken == Token.Exclamation
) && tn.peekOnNewLine()
) break;
let token = tn.next();
switch (token) {

Expand Down Expand Up @@ -4430,6 +4456,12 @@ export class Parser extends DiagnosticEmitter {
);
}

private parseSemicolon(
tn: Tokenizer
): void {
if (!tn.skip(Token.Semicolon)) this.checkASI(tn);
}

/** Skips over a statement on errors in an attempt to reduce unnecessary diagnostic noise. */
skipStatement(tn: Tokenizer): void {
if (tn.peekOnNewLine()) tn.next(); // if reset() to the previous line
Expand Down
52 changes: 52 additions & 0 deletions tests/compiler/asi.debug.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(module
(type $0 (func))
(type $1 (func (param i32 i32 i32 i32)))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
(global $asi/i (mut i32) (i32.const 0))
(global $asi/j (mut i32) (i32.const 7))
(global $asi/k (mut i32) (i32.const 1))
(global $~lib/memory/__data_end i32 (i32.const 44))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 32812))
(global $~lib/memory/__heap_base i32 (i32.const 32812))
(memory $0 1)
(data $0 (i32.const 12) "\1c\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\0c\00\00\00a\00s\00i\00.\00t\00s\00")
(table $0 1 1 funcref)
(elem $0 (i32.const 1))
(export "memory" (memory $0))
(start $~start)
(func $start:asi
global.get $asi/j
global.set $asi/i
global.get $asi/k
i32.const 1
i32.add
global.set $asi/k
global.get $asi/i
i32.const 7
i32.eq
i32.eqz
if
i32.const 0
i32.const 32
i32.const 8
i32.const 1
call $~lib/builtins/abort
unreachable
end
global.get $asi/k
i32.const 2
i32.eq
i32.eqz
if
i32.const 0
i32.const 32
i32.const 9
i32.const 1
call $~lib/builtins/abort
unreachable
end
)
(func $~start
call $start:asi
)
)
28 changes: 28 additions & 0 deletions tests/compiler/asi.release.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(module
(type $0 (func))
(type $1 (func (param i32 i32 i32 i32)))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
(global $asi/k (mut i32) (i32.const 1))
(memory $0 1)
(data $0 (i32.const 1036) "\1c")
(data $0.1 (i32.const 1048) "\02\00\00\00\0c\00\00\00a\00s\00i\00.\00t\00s")
(export "memory" (memory $0))
(start $~start)
(func $~start
global.get $asi/k
i32.const 1
i32.add
global.set $asi/k
global.get $asi/k
i32.const 2
i32.ne
if
i32.const 0
i32.const 1056
i32.const 9
i32.const 1
call $~lib/builtins/abort
unreachable
end
)
)
Loading
Loading