Last active
October 4, 2023 22:06
-
-
Save YannickFricke/29034768dba7409dc7321234e1a6e868 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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