summaryrefslogtreecommitdiff
path: root/stylis.js/src/Tokenizer.js
diff options
context:
space:
mode:
Diffstat (limited to 'stylis.js/src/Tokenizer.js')
-rw-r--r--stylis.js/src/Tokenizer.js218
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)
+}