import {from, trim, charat, strlen, substr, append, assign} 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 = ''
export function node (value, root, parent, type, props, children, length, siblings) {
return {value: value, root: root, parent: parent, type: type, props: props, children: children, line: line, column: column, length: length, return: '', siblings: siblings}
}
export function copy (root, props) {
return assign(node('', null, null, '', null, null, 0, root.siblings), root, {length: -root.length}, props)
}
export function lift (root) {
while (root.root)
root = copy(root.root, {children: [root]})
append(root, root.siblings)
}
export function char () {
return character
}
export function prev () {
character = position > 0 ? charat(characters, --position) : 0
if (column--, character === 10)
column = 1, line--
return character
}
export function next () {
character = position < length ? charat(characters, position++) : 0
if (column++, character === 10)
column = 1, line++
return character
}
export function peek () {
return charat(characters, position)
}
export function caret () {
return position
}
export function slice (begin, end) {
return substr(characters, begin, end)
}
export function token (type) {
switch (type) {
case 0: case 9: case 10: case 13: case 32:
return 5
case 33: case 43: case 44: case 47: case 62: case 64: case 126:
case 59: case 123: case 125:
return 4
case 58:
return 3
case 34: case 39: case 40: case 91:
return 2
case 41: case 93:
return 1
}
return 0
}
export function alloc (value) {
return line = column = 1, length = strlen(characters = value), position = 0, []
}
export function dealloc (value) {
return characters = '', value
}
export function delimit (type) {
return trim(slice(position - 1, delimiter(type === 91 ? type + 2 : type === 40 ? type + 1 : type)))
}
export function tokenize (value) {
return dealloc(tokenizer(alloc(value)))
}
export function whitespace (type) {
while (character = peek())
if (character < 33)
next()
else
break
return token(type) > 2 || token(character) > 3 ? '' : ' '
}
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
}
export function escaping (index, count) {
while (--count && next())
if (character < 48 || character > 102 || (character > 57 && character < 65) || (character > 70 && character < 97))
break
return slice(index, caret() + (count < 6 && peek() == 32 && next() == 32))
}
export function delimiter (type) {
while (next())
switch (character) {
case type:
return position
case 34: case 39:
if (type !== 34 && type !== 39)
delimiter(character)
break
case 40:
if (type === 41)
delimiter(type)
break
case 92:
next()
break
}
return position
}
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())
}
export function identifier (index) {
while (!token(peek()))
next()
return slice(index, position)
}