Skip to content

Instantly share code, notes, and snippets.

@YannickFricke
Last active October 4, 2023 22:06
Show Gist options
  • Save YannickFricke/29034768dba7409dc7321234e1a6e868 to your computer and use it in GitHub Desktop.
Save YannickFricke/29034768dba7409dc7321234e1a6e868 to your computer and use it in GitHub Desktop.
import { TokenType } from "./TokenType";
import { Keyword } from "./Keywords";
import { SpecialCharacters } from "./SpecialCharacters";
import { type Token } from "./Token";
export type ExpectedToken =
| [TokenType.Identifier]
| [TokenType.String]
| [TokenType.Char]
| [TokenType.Number]
| [TokenType.Keyword, Keyword]
| [TokenType.SpecialCharacter, SpecialCharacters[]]
| [TokenType.SingleLineComment]
| [TokenType.MultiLineComment];
function doesValueMatch(
[expectedType, expectedValue]: ExpectedToken,
{ value: actualValue }: Token,
): boolean {
switch (expectedType) {
case TokenType.Identifier:
case TokenType.String:
case TokenType.Char:
case TokenType.Number:
case TokenType.SingleLineComment:
case TokenType.MultiLineComment:
// We can't perform any checks against the value of the above defined token types
return true;
case TokenType.Keyword:
// Check if the token value matches against our needed keyword
return expectedValue === actualValue;
case TokenType.SpecialCharacter:
// Check if the token value matches against our needed special characters
return expectedValue.join("") === actualValue;
default:
return false;
}
}
export function isTokenExpected(
expectedTokens: ExpectedToken[],
tokenToCheck: Token,
): boolean {
if (expectedTokens.length === 0) {
return false;
}
for (let expectedToken of expectedTokens) {
const [expectedType] = expectedToken;
// Check if the token types are matching
if (tokenToCheck.type !== expectedType) {
// The types do not match
// We need to find another entry
continue;
}
// Check if the values are matching
if (!doesValueMatch(expectedToken, tokenToCheck)) {
// The values do not match
// We need to find another entry
continue;
}
// The current entry matches against the given token
return true;
}
return false;
}
export function isConditionSeparatorToken(tokenToCheck: Token): boolean {
return isTokenExpected(
[
[
TokenType.SpecialCharacter,
[SpecialCharacters.Ampersand, SpecialCharacters.Ampersand],
],
[
TokenType.SpecialCharacter,
[SpecialCharacters.Pipe, SpecialCharacters.Pipe],
],
],
tokenToCheck,
);
}
export function isClassModifierToken(tokenToCheck: Token): boolean {
return isTokenExpected(
[
[TokenType.Keyword, Keyword.Abstract],
[TokenType.Keyword, Keyword.Final],
],
tokenToCheck,
);
}
export function isDataTypeToken(tokenToCheck: Token): boolean {
return isTokenExpected(
[
// Built-in data types
[TokenType.Keyword, Keyword.Void],
[TokenType.Keyword, Keyword.Boolean],
[TokenType.Keyword, Keyword.String],
[TokenType.Keyword, Keyword.Char],
[TokenType.Keyword, Keyword.Byte],
[TokenType.Keyword, Keyword.Int8],
[TokenType.Keyword, Keyword.Int16],
[TokenType.Keyword, Keyword.Int32],
[TokenType.Keyword, Keyword.Int64],
[TokenType.Keyword, Keyword.Uint8],
[TokenType.Keyword, Keyword.Uint16],
[TokenType.Keyword, Keyword.Uint32],
[TokenType.Keyword, Keyword.Uint64],
[TokenType.Keyword, Keyword.Float32],
[TokenType.Keyword, Keyword.Float64],
// For user defined data types or type arguments (generics)
[TokenType.Identifier],
],
tokenToCheck,
);
}
export function isFunctionVisibilityToken(tokenToCheck: Token): boolean {
return isTokenExpected(
[
[TokenType.Keyword, Keyword.Public],
[TokenType.Keyword, Keyword.Protected],
[TokenType.Keyword, Keyword.Private],
],
tokenToCheck,
);
}
export function isCommentToken(tokenToCheck: Token): boolean {
return isTokenExpected(
[[TokenType.SingleLineComment], [TokenType.MultiLineComment]],
tokenToCheck,
);
}
export function isValidTopLevelToken(tokenToCheck: Token): boolean {
if (isClassModifierToken(tokenToCheck)) {
return true;
}
if (isDataTypeToken(tokenToCheck)) {
return true;
}
if (isCommentToken(tokenToCheck)) {
// All kind of comments are allowed in the global scope
return true;
}
return isTokenExpected(
[
[TokenType.Keyword, Keyword.Import],
[TokenType.Keyword, Keyword.Export],
[TokenType.Keyword, Keyword.Enum],
[TokenType.Keyword, Keyword.Struct],
[TokenType.Keyword, Keyword.Class],
[TokenType.Keyword, Keyword.Trait],
[TokenType.Keyword, Keyword.Const],
[TokenType.Keyword, Keyword.Impl],
],
tokenToCheck,
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment