remove semi-colons

This commit is contained in:
Kurt Hutten IrevDev
2022-11-26 08:34:23 +11:00
parent ab9fb05e30
commit 48e59ac710
19 changed files with 1159 additions and 1122 deletions

View File

@ -1,44 +1,55 @@
const NUMBER = /^[0-9]+/;
const WHITESPACE = /\s+/;
const WORD = /^[a-zA-Z_][a-zA-Z0-9_]*/;
const NUMBER = /^[0-9]+/
const WHITESPACE = /\s+/
const WORD = /^[a-zA-Z_][a-zA-Z0-9_]*/
// regex that captures everything between two non escaped quotes and the quotes aren't captured in the match
const STRING = /^(["'])(?:(?=(\\?))\2.)*?\1/;
const STRING = /^(["'])(?:(?=(\\?))\2.)*?\1/
// verbose regex for finding operators, multiple character operators need to be first
const OPERATOR = /^(>=|<=|==|=>|!=|\*|\+|-|\/|%|=|<|>|\||\^)/;
const OPERATOR = /^(>=|<=|==|=>|!=|\*|\+|-|\/|%|=|<|>|\||\^)/
const BLOCK_START = /^\{/;
const BLOCK_END = /^\}/;
const PARAN_START = /^\(/;
const PARAN_END = /^\)/;
const COMMA = /^,/;
const BLOCK_START = /^\{/
const BLOCK_END = /^\}/
const PARAN_START = /^\(/
const PARAN_END = /^\)/
const COMMA = /^,/
export const isNumber = (character: string) => NUMBER.test(character);
export const isWhitespace = (character: string) => WHITESPACE.test(character);
export const isWord = (character: string) => WORD.test(character);
export const isString = (character: string) => STRING.test(character);
export const isOperator = (character: string) => OPERATOR.test(character);
export const isBlockStart = (character: string) => BLOCK_START.test(character);
export const isBlockEnd = (character: string) => BLOCK_END.test(character);
export const isParanStart = (character: string) => PARAN_START.test(character);
export const isParanEnd = (character: string) => PARAN_END.test(character);
export const isComma = (character: string) => COMMA.test(character);
export const isNumber = (character: string) => NUMBER.test(character)
export const isWhitespace = (character: string) => WHITESPACE.test(character)
export const isWord = (character: string) => WORD.test(character)
export const isString = (character: string) => STRING.test(character)
export const isOperator = (character: string) => OPERATOR.test(character)
export const isBlockStart = (character: string) => BLOCK_START.test(character)
export const isBlockEnd = (character: string) => BLOCK_END.test(character)
export const isParanStart = (character: string) => PARAN_START.test(character)
export const isParanEnd = (character: string) => PARAN_END.test(character)
export const isComma = (character: string) => COMMA.test(character)
function matchFirst(str: string, regex: RegExp) {
const theMatch = str.match(regex);
const theMatch = str.match(regex)
if (!theMatch) {
throw new Error("Should always be a match:" + str);
throw new Error('Should always be a match:' + str)
}
return theMatch[0];
return theMatch[0]
}
export interface Token {
type: "number" | "word" | "operator" | "string" | "brace" | "whitespace" | "comma";
value: string;
start: number;
end: number;
type:
| 'number'
| 'word'
| 'operator'
| 'string'
| 'brace'
| 'whitespace'
| 'comma'
value: string
start: number
end: number
}
const makeToken = (type: Token["type"], value: string, start: number): Token => ({
const makeToken = (
type: Token['type'],
value: string,
start: number
): Token => ({
type,
value,
start,
@ -46,39 +57,43 @@ const makeToken = (type: Token["type"], value: string, start: number): Token =>
})
const returnTokenAtIndex = (str: string, startIndex: number): Token | null => {
const strFromIndex = str.slice(startIndex);
const strFromIndex = str.slice(startIndex)
if (isOperator(strFromIndex)) {
return makeToken("operator", matchFirst(strFromIndex, OPERATOR), startIndex);
return makeToken('operator', matchFirst(strFromIndex, OPERATOR), startIndex)
}
if (isString(strFromIndex)) {
return makeToken("string", matchFirst(strFromIndex, STRING), startIndex);
return makeToken('string', matchFirst(strFromIndex, STRING), startIndex)
}
if (isParanEnd(strFromIndex)) {
return makeToken("brace", matchFirst(strFromIndex, PARAN_END), startIndex);
return makeToken('brace', matchFirst(strFromIndex, PARAN_END), startIndex)
}
if (isParanStart(strFromIndex)) {
return makeToken("brace", matchFirst(strFromIndex, PARAN_START), startIndex);
return makeToken('brace', matchFirst(strFromIndex, PARAN_START), startIndex)
}
if (isBlockStart(strFromIndex)) {
return makeToken("brace", matchFirst(strFromIndex, BLOCK_START), startIndex);
return makeToken('brace', matchFirst(strFromIndex, BLOCK_START), startIndex)
}
if (isBlockEnd(strFromIndex)) {
return makeToken("brace", matchFirst(strFromIndex, BLOCK_END), startIndex);
return makeToken('brace', matchFirst(strFromIndex, BLOCK_END), startIndex)
}
if (isComma(strFromIndex)) {
return makeToken("comma", matchFirst(strFromIndex, COMMA), startIndex);
return makeToken('comma', matchFirst(strFromIndex, COMMA), startIndex)
}
if (isNumber(strFromIndex)) {
return makeToken("number", matchFirst(strFromIndex, NUMBER), startIndex);
return makeToken('number', matchFirst(strFromIndex, NUMBER), startIndex)
}
if (isWord(strFromIndex)) {
return makeToken("word", matchFirst(strFromIndex, WORD), startIndex);
return makeToken('word', matchFirst(strFromIndex, WORD), startIndex)
}
if (isWhitespace(strFromIndex)) {
return makeToken("whitespace", matchFirst(strFromIndex, WHITESPACE), startIndex);
return makeToken(
'whitespace',
matchFirst(strFromIndex, WHITESPACE),
startIndex
)
}
return null;
};
return null
}
export const lexer = (str: string): Token[] => {
const recursivelyTokenise = (
@ -87,14 +102,14 @@ export const lexer = (str: string): Token[] => {
previousTokens: Token[] = []
): Token[] => {
if (currentIndex >= str.length) {
return previousTokens;
return previousTokens
}
const token = returnTokenAtIndex(str, currentIndex);
const token = returnTokenAtIndex(str, currentIndex)
if (!token) {
return recursivelyTokenise(str, currentIndex + 1, previousTokens);
return recursivelyTokenise(str, currentIndex + 1, previousTokens)
}
const nextIndex = currentIndex + token.value.length;
return recursivelyTokenise(str, nextIndex, [...previousTokens, token]);
};
return recursivelyTokenise(str);
};
const nextIndex = currentIndex + token.value.length
return recursivelyTokenise(str, nextIndex, [...previousTokens, token])
}
return recursivelyTokenise(str)
}