diff options
Diffstat (limited to 'stylis.js/src/Tokenizer.js')
-rw-r--r-- | stylis.js/src/Tokenizer.js | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/stylis.js/src/Tokenizer.js b/stylis.js/src/Tokenizer.js new file mode 100644 index 0000000..d14c136 --- /dev/null +++ b/stylis.js/src/Tokenizer.js @@ -0,0 +1,218 @@ +import {from, trim, charat, strlen, substr, append} from './Utility.js' + +export var line = 1 +export var column = 1 +export var length = 0 +export var position = 0 +export var character = 0 +export var characters = '' + +/** + * @param {string} value + * @param {object} root + * @param {object?} parent + * @param {string} type + * @param {string[]} props + * @param {object[]} children + * @param {number} length + */ +export function node (value, root, parent, type, props, children, length) { + return {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: ''} +} + +/** + * @param {string} value + * @param {object} root + * @param {string} type + */ +export function copy (value, root, type) { + return node(value, root.root, root.parent, type, root.props, root.children, 0) +} + +/** + * @return {number} + */ +export function char () { + return character +} + +/** + * @return {number} + */ +export function next () { + character = position < length ? charat(characters, position++) : 0 + + if (column++, character === 10) + column = 1, line++ + + return character +} + +/** + * @return {number} + */ +export function peek () { + return charat(characters, position) +} + +/** + * @return {number} + */ +export function caret () { + return position +} + +/** + * @param {number} begin + * @param {number} end + * @return {string} + */ +export function slice (begin, end) { + return substr(characters, begin, end) +} + +/** + * @param {number} type + * @return {number} + */ +export function token (type) { + switch (type) { + // \0 \t \n \r \s whitespace token + case 0: case 9: case 10: case 13: case 32: + return 5 + // ! + , / > @ ~ isolate token + case 33: case 43: case 44: case 47: case 62: case 64: case 126: + // ; { } / breakpoint token + case 59: case 123: case 125: + return 4 + // : accompanied token + case 58: + return 3 + // " ' ( [ opening delimit token + case 34: case 39: case 40: case 91: + return 2 + // ) ] closing delimit token + case 41: case 93: + return 1 + } + + return 0 +} + +/** + * @param {string} value + * @return {any[]} + */ +export function alloc (value) { + return line = column = 1, length = strlen(characters = value), position = 0, [] +} + +/** + * @param {any} value + * @return {any} + */ +export function dealloc (value) { + return characters = '', value +} + +/** + * @param {number} type + * @return {string} + */ +export function delimit (type) { + return trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type))) +} + +/** + * @param {string} value + * @return {string[]} + */ +export function tokenize (value) { + return dealloc(tokenizer(alloc(value))) +} + +/** + * @param {number} type + * @return {string} + */ +export function whitespace (type) { + while (character = peek()) + if (character < 33) + next() + else + break + + return token(type) > 2 || token(character) > 3 ? '' : ' ' +} + +/** + * @param {string[]} children + * @return {string[]} + */ +export function tokenizer (children) { + while (next()) + switch (token(character)) { + case 0: append(identifier(position - 1), children) + break + case 2: append(delimit(character), children) + break + default: append(from(character), children) + } + + return children +} + +/** + * @param {number} type + * @return {number} + */ +export function delimiter (type) { + while (next()) + switch (character) { + // ] ) " ' + case type: + return position + // " ' + case 34: case 39: + return delimiter(type === 34 || type === 39 ? type : character) + // ( + case 40: + if (type === 41) + delimiter(type) + break + // \ + case 92: + next() + break + } + + return position +} + +/** + * @param {number} type + * @param {number} index + * @return {number} + */ +export function commenter (type, index) { + while (next()) + // // + if (type + character === 47 + 10) + break + // /* + else if (type + character === 42 + 42 && peek() === 47) + break + + return '/*' + slice(index, position - 1) + '*' + from(type === 47 ? type : next()) +} + +/** + * @param {number} index + * @return {string} + */ +export function identifier (index) { + while (!token(peek())) + next() + + return slice(index, position) +} |