Implementation
@override
ASTNode? parseStmt({required ParseStyle style}) {
handlePrecedings();
// if (_handlePrecedingCommentsOrEmptyLines()) {
// return null;
// }
// handle emtpy statement is a must because automatic semicolon insertion.
if (curTok.type == lexicon.endOfStatementMark) {
advance();
return null;
}
if (curTok.type == Semantic.endOfFile) {
return null;
}
// save preceding comments because those might change during expression parsing.
final savedPrecedings = savePrecedings();
// if (curTok is TokenEmptyLine) {
// final empty = advance();
// final emptyStmt = ASTEmptyLine(
// line: empty.line, column: empty.column, offset: empty.offset);
// emptyStmt.precedingComments = precedingComments;
// return emptyStmt;
// }
ASTNode stmt;
switch (style) {
case ParseStyle.script:
if (curTok.lexeme == lexicon.kImport) {
stmt = _parseImportDecl();
} else if (curTok.lexeme == lexicon.kExport) {
stmt = _parseExportStmt();
} else if (curTok.lexeme == lexicon.kType) {
stmt = _parseTypeAliasDecl(isTopLevel: true);
} else if (curTok.lexeme == lexicon.kNamespace) {
stmt = _parseNamespaceDecl(isTopLevel: true);
} else if (curTok.type == lexicon.kExternal) {
advance();
if (curTok.type == lexicon.kAbstract) {
advance();
stmt = _parseClassDecl(
isAbstract: true, isExternal: true, isTopLevel: true);
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(isExternal: true, isTopLevel: true);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl(isExternal: true, isTopLevel: true);
} else if (lexicon.variableDeclarationKeywords
.contains(curTok.type)) {
final err = HTError.externalVar(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(isExternal: true, isTopLevel: true);
} else {
final err = HTError.unexpected(
lexicon.kExternal, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
} else if (curTok.type == lexicon.kAbstract) {
advance();
stmt = _parseClassDecl(
isAbstract: true, isTopLevel: true, lateResolve: false);
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(isTopLevel: true, lateResolve: false);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl(isTopLevel: true);
} else if (curTok.type == lexicon.kVar) {
if (lexicon.destructuringDeclarationMark.contains(peek(1).type)) {
stmt = _parseDestructuringDecl(isTopLevel: true, isMutable: true);
} else {
stmt = _parseVarDecl(isMutable: true, isTopLevel: true);
}
} else if (curTok.type == lexicon.kFinal) {
if (lexicon.destructuringDeclarationMark.contains(peek(1).type)) {
stmt = _parseDestructuringDecl(isTopLevel: true);
} else {
stmt = _parseVarDecl(isTopLevel: true);
}
} else if (curTok.type == lexicon.kLate) {
stmt = _parseVarDecl(lateFinalize: true, isTopLevel: true);
} else if (curTok.type == lexicon.kConst) {
stmt = _parseVarDecl(isConst: true, isTopLevel: true);
} else if (curTok.type == lexicon.kFun) {
if (expect([lexicon.kFun, Semantic.identifier]) ||
expect([
lexicon.kFun,
lexicon.externalFunctionTypeDefStart,
Semantic.identifier,
lexicon.externalFunctionTypeDefEnd,
Semantic.identifier
])) {
stmt = _parseFunction(isTopLevel: true);
} else {
stmt = _parseFunction(
category: FunctionCategory.literal, isTopLevel: true);
}
}
// else if (curTok.type == lexicon.kAsync) {
// if (expect([lexicon.kAsync, Semantic.identifier]) ||
// expect([
// lexicon.kFun,
// lexicon.externalFunctionTypeDefStart,
// Semantic.identifier,
// lexicon.externalFunctionTypeDefEnd,
// Semantic.identifier
// ])) {
// stmt = _parseFunction(isAsync: true, isTopLevel: true);
// } else {
// stmt = _parseFunction(
// category: FunctionCategory.literal,
// isAsync: true,
// isTopLevel: true);
// }
// }
else if (curTok.type == lexicon.kStruct) {
stmt =
_parseStructDecl(isTopLevel: true); // , lateInitialize: false);
} else if (curTok.type == lexicon.kDelete) {
stmt = _parseDeleteStmt();
} else if (curTok.type == lexicon.kIf) {
stmt = _parseIf();
} else if (curTok.type == lexicon.kWhile) {
stmt = _parseWhileStmt();
} else if (curTok.type == lexicon.kDo) {
stmt = _parseDoStmt();
} else if (curTok.type == lexicon.kFor) {
stmt = _parseForStmt();
} else if (curTok.type == lexicon.kWhen) {
stmt = _parseWhen();
} else if (curTok.type == lexicon.kAssert) {
stmt = _parseAssertStmt();
} else if (curTok.type == lexicon.kThrow) {
stmt = _parseThrowStmt();
} else {
stmt = _parseExprStmt();
}
break;
case ParseStyle.module:
if (curTok.lexeme == lexicon.kImport) {
stmt = _parseImportDecl();
} else if (curTok.lexeme == lexicon.kExport) {
stmt = _parseExportStmt();
} else if (curTok.lexeme == lexicon.kType) {
stmt = _parseTypeAliasDecl(isTopLevel: true);
} else if (curTok.lexeme == lexicon.kNamespace) {
stmt = _parseNamespaceDecl(isTopLevel: true);
} else if (curTok.type == lexicon.kExternal) {
advance();
if (curTok.type == lexicon.kAbstract) {
advance();
if (curTok.type != lexicon.kClass) {
final err = HTError.unexpected(
lexicon.kAbstract, Semantic.classDeclaration, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseClassDecl(
isAbstract: true, isExternal: true, isTopLevel: true);
}
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(isExternal: true, isTopLevel: true);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl(isExternal: true, isTopLevel: true);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(isExternal: true, isTopLevel: true);
} else if (lexicon.variableDeclarationKeywords
.contains(curTok.type)) {
final err = HTError.externalVar(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
final err = HTError.unexpected(
lexicon.kExternal, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
} else if (curTok.type == lexicon.kAbstract) {
advance();
stmt = _parseClassDecl(isAbstract: true, isTopLevel: true);
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(isTopLevel: true);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl(isTopLevel: true);
} else if (curTok.type == lexicon.kVar) {
stmt = _parseVarDecl(
isMutable: true, isTopLevel: true, lateInitialize: true);
} else if (curTok.type == lexicon.kFinal) {
stmt = _parseVarDecl(lateInitialize: true, isTopLevel: true);
} else if (curTok.type == lexicon.kLate) {
stmt = _parseVarDecl(lateFinalize: true, isTopLevel: true);
} else if (curTok.type == lexicon.kConst) {
stmt = _parseVarDecl(isConst: true, isTopLevel: true);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(isTopLevel: true);
} else if (curTok.type == lexicon.kStruct) {
stmt = _parseStructDecl(isTopLevel: true);
} else {
final err = HTError.unexpected(
Semantic.declStmt, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
break;
case ParseStyle.namespace:
if (curTok.lexeme == lexicon.kType) {
stmt = _parseTypeAliasDecl();
} else if (curTok.lexeme == lexicon.kNamespace) {
stmt = _parseNamespaceDecl();
} else if (curTok.type == lexicon.kExternal) {
advance();
if (curTok.type == lexicon.kAbstract) {
advance();
if (curTok.type != lexicon.kClass) {
final err = HTError.unexpected(
lexicon.kAbstract, Semantic.classDeclaration, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseClassDecl(isAbstract: true, isExternal: true);
}
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(isExternal: true);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl(isExternal: true);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(isExternal: true);
} else if (lexicon.variableDeclarationKeywords
.contains(curTok.type)) {
final err = HTError.externalVar(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
final err = HTError.unexpected(
lexicon.kExternal, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
} else if (curTok.type == lexicon.kAbstract) {
advance();
stmt = _parseClassDecl(
isAbstract: true, lateResolve: _isWithinModuleNamespace);
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(lateResolve: _isWithinModuleNamespace);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl();
} else if (curTok.type == lexicon.kVar) {
stmt = _parseVarDecl(
isMutable: true, lateInitialize: _isWithinModuleNamespace);
} else if (curTok.type == lexicon.kFinal) {
stmt = _parseVarDecl(lateInitialize: _isWithinModuleNamespace);
} else if (curTok.type == lexicon.kConst) {
stmt = _parseVarDecl(isConst: true);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction();
} else if (curTok.type == lexicon.kStruct) {
stmt = _parseStructDecl();
} else {
final err = HTError.unexpected(
Semantic.declStmt, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
break;
case ParseStyle.classDefinition:
final isOverrided = expect([lexicon.kOverride], consume: true);
final isExternal = expect([lexicon.kExternal], consume: true) ||
(_currentClassDeclaration?.isExternal ?? false);
final isStatic = expect([lexicon.kStatic], consume: true);
if (curTok.lexeme == lexicon.kType) {
if (isExternal) {
final err = HTError.external(Semantic.typeAliasDeclaration,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseTypeAliasDecl();
}
} else {
if (curTok.type == lexicon.kVar) {
stmt = _parseVarDecl(
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isMutable: true,
isStatic: isStatic,
lateInitialize: true);
} else if (curTok.type == lexicon.kFinal) {
stmt = _parseVarDecl(
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isStatic: isStatic,
lateInitialize: true);
} else if (curTok.type == lexicon.kLate) {
stmt = _parseVarDecl(
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isStatic: isStatic,
lateFinalize: true);
} else if (curTok.type == lexicon.kConst) {
if (isStatic) {
stmt = _parseVarDecl(
isConst: true, classId: _currentClassDeclaration?.id);
} else {
final err = HTError.external(Semantic.typeAliasDeclaration,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(
category: FunctionCategory.method,
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isStatic: isStatic);
}
// else if (curTok.type == lexicon.kAsync) {
// if (isExternal) {
// final err = HTError.external(Semantic.asyncFunction,
// filename: currrentFileName,
// line: curTok.line,
// column: curTok.column,
// offset: curTok.offset,
// length: curTok.length);
// errors.add(err);
// final errToken = advance();
// stmt = ASTEmptyLine(
// source: currentSource,
// line: errToken.line,
// column: errToken.column,
// offset: errToken.offset);
// } else {
// stmt = _parseFunction(
// category: FunctionCategory.method,
// classId: _currentClassDeclaration?.id,
// isAsync: true,
// isOverrided: isOverrided,
// isExternal: isExternal,
// isStatic: isStatic);
// }
// }
else if (curTok.type == lexicon.kGet) {
stmt = _parseFunction(
category: FunctionCategory.getter,
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isStatic: isStatic);
} else if (curTok.type == lexicon.kSet) {
stmt = _parseFunction(
category: FunctionCategory.setter,
classId: _currentClassDeclaration?.id,
isOverrided: isOverrided,
isExternal: isExternal,
isStatic: isStatic);
} else if (curTok.type == lexicon.kConstruct) {
if (isStatic) {
final err = HTError.unexpected(
lexicon.kStatic, Semantic.declStmt, lexicon.kConstruct,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else if (isExternal && !_currentClassDeclaration!.isExternal) {
final err = HTError.external(Semantic.ctorFunction,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseFunction(
category: FunctionCategory.constructor,
classId: _currentClassDeclaration?.id,
isExternal: isExternal,
);
}
} else if (curTok.type == lexicon.kFactory) {
if (isStatic) {
final err = HTError.unexpected(
lexicon.kStatic, Semantic.declStmt, lexicon.kConstruct,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else if (isExternal && !_currentClassDeclaration!.isExternal) {
final err = HTError.external(Semantic.factory,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseFunction(
category: FunctionCategory.factoryConstructor,
classId: _currentClassDeclaration?.id,
isExternal: isExternal,
isStatic: true,
);
}
} else {
final err = HTError.unexpected(
Semantic.classDefinition, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
}
break;
case ParseStyle.structDefinition:
final isExternal = expect([lexicon.kExternal], consume: true);
final isStatic = expect([lexicon.kStatic], consume: true);
if (curTok.type == lexicon.kVar) {
stmt = _parseVarDecl(
classId: _currentStructId,
isField: true,
isExternal: isExternal,
isMutable: true,
isStatic: isStatic,
lateInitialize: true);
} else if (curTok.type == lexicon.kFinal) {
stmt = _parseVarDecl(
classId: _currentStructId,
isField: true,
isExternal: isExternal,
isStatic: isStatic,
lateInitialize: true);
} else if (curTok.type == lexicon.kFun) {
stmt = _parseFunction(
category: FunctionCategory.method,
classId: _currentStructId,
isExternal: isExternal,
isField: true,
isStatic: isStatic);
}
// else if (curTok.type == lexicon.kAsync) {
// if (isExternal) {
// final err = HTError.external(Semantic.asyncFunction,
// filename: currrentFileName,
// line: curTok.line,
// column: curTok.column,
// offset: curTok.offset,
// length: curTok.length);
// errors.add(err);
// final errToken = advance();
// stmt = ASTEmptyLine(
// source: currentSource,
// line: errToken.line,
// column: errToken.column,
// offset: errToken.offset);
// } else {
// stmt = _parseFunction(
// category: FunctionCategory.method,
// classId: _currentStructId,
// isAsync: true,
// isField: true,
// isExternal: isExternal,
// isStatic: isStatic);
// }
// }
else if (curTok.type == lexicon.kGet) {
stmt = _parseFunction(
category: FunctionCategory.getter,
classId: _currentStructId,
isField: true,
isExternal: isExternal,
isStatic: isStatic);
} else if (curTok.type == lexicon.kSet) {
stmt = _parseFunction(
category: FunctionCategory.setter,
classId: _currentStructId,
isField: true,
isExternal: isExternal,
isStatic: isStatic);
} else if (curTok.type == lexicon.kConstruct) {
if (isStatic) {
final err = HTError.unexpected(
lexicon.kStatic, Semantic.declStmt, lexicon.kConstruct,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else if (isExternal) {
final err = HTError.external(Semantic.ctorFunction,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
} else {
stmt = _parseFunction(
category: FunctionCategory.constructor,
classId: _currentStructId,
isExternal: isExternal,
isField: true);
}
} else {
final err = HTError.unexpected(
Semantic.structDefinition, Semantic.declStmt, curTok.lexeme,
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
final errToken = advance();
stmt = ASTEmptyLine(
source: currentSource,
line: errToken.line,
column: errToken.column,
offset: errToken.offset);
}
break;
case ParseStyle.functionDefinition:
if (curTok.lexeme == lexicon.kType) {
stmt = _parseTypeAliasDecl();
} else if (curTok.lexeme == lexicon.kNamespace) {
stmt = _parseNamespaceDecl();
} else if (curTok.type == lexicon.kAbstract) {
advance();
stmt = _parseClassDecl(isAbstract: true, lateResolve: false);
} else if (curTok.type == lexicon.kClass) {
stmt = _parseClassDecl(lateResolve: false);
} else if (curTok.type == lexicon.kEnum) {
stmt = _parseEnumDecl();
} else if (curTok.type == lexicon.kVar) {
if (lexicon.destructuringDeclarationMark.contains(peek(1).type)) {
stmt = _parseDestructuringDecl(isMutable: true);
} else {
stmt = _parseVarDecl(isMutable: true);
}
} else if (curTok.type == lexicon.kFinal) {
if (lexicon.destructuringDeclarationMark.contains(peek(1).type)) {
stmt = _parseDestructuringDecl();
} else {
stmt = _parseVarDecl();
}
} else if (curTok.type == lexicon.kLate) {
stmt = _parseVarDecl(lateFinalize: true);
} else if (curTok.type == lexicon.kConst) {
stmt = _parseVarDecl(isConst: true);
} else if (curTok.type == lexicon.kFun) {
if (expect([lexicon.kFun, Semantic.identifier]) ||
expect([
lexicon.kFun,
lexicon.externalFunctionTypeDefStart,
Semantic.identifier,
lexicon.externalFunctionTypeDefEnd,
Semantic.identifier
])) {
stmt = _parseFunction();
} else {
stmt = _parseFunction(category: FunctionCategory.literal);
}
}
// else if (curTok.type == lexicon.kAsync) {
// if (expect([lexicon.kAsync, Semantic.identifier]) ||
// expect([
// lexicon.kFun,
// lexicon.externalFunctionTypeDefStart,
// Semantic.identifier,
// lexicon.externalFunctionTypeDefEnd,
// Semantic.identifier
// ])) {
// stmt = _parseFunction(isAsync: true);
// } else {
// stmt = _parseFunction(
// category: FunctionCategory.literal, isAsync: true);
// }
// }
else if (curTok.type == lexicon.kStruct) {
stmt = _parseStructDecl(); // (lateInitialize: false);
} else if (curTok.type == lexicon.kDelete) {
stmt = _parseDeleteStmt();
} else if (curTok.type == lexicon.kIf) {
stmt = _parseIf();
} else if (curTok.type == lexicon.kWhile) {
stmt = _parseWhileStmt();
} else if (curTok.type == lexicon.kDo) {
stmt = _parseDoStmt();
} else if (curTok.type == lexicon.kFor) {
stmt = _parseForStmt();
} else if (curTok.type == lexicon.kWhen) {
stmt = _parseWhen();
} else if (curTok.type == lexicon.kAssert) {
stmt = _parseAssertStmt();
} else if (curTok.type == lexicon.kThrow) {
stmt = _parseThrowStmt();
} else if (curTok.type == lexicon.kBreak) {
if (!_isInLoop) {
final err = HTError.misplacedBreak(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
}
final keyword = advance();
final hasEndOfStmtMark =
expect([lexicon.endOfStatementMark], consume: true);
stmt = BreakStmt(keyword,
hasEndOfStmtMark: hasEndOfStmtMark,
source: currentSource,
line: keyword.line,
column: keyword.column,
offset: keyword.offset,
length: keyword.length);
} else if (curTok.type == lexicon.kContinue) {
if (!_isInLoop) {
final err = HTError.misplacedContinue(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
}
final keyword = advance();
final hasEndOfStmtMark =
expect([lexicon.endOfStatementMark], consume: true);
stmt = ContinueStmt(keyword,
hasEndOfStmtMark: hasEndOfStmtMark,
source: currentSource,
line: keyword.line,
column: keyword.column,
offset: keyword.offset,
length: keyword.length);
} else if (curTok.type == lexicon.kReturn) {
if (_currentFunctionCategory == null ||
_currentFunctionCategory == FunctionCategory.constructor) {
final err = HTError.misplacedReturn(
filename: currrentFileName,
line: curTok.line,
column: curTok.column,
offset: curTok.offset,
length: curTok.length);
errors.add(err);
}
stmt = _parseReturnStmt();
} else {
stmt = _parseExprStmt();
}
break;
case ParseStyle.expression:
stmt = parseExpr();
}
currentPrecedings = savedPrecedings;
setPrecedings(stmt);
// it's possible that there's trailing comment after end of stmt mark (;).
handleTrailing(stmt);
return stmt;
}