playground
This commit is contained in:
parent
a906d51228
commit
474e6ae7ca
3 changed files with 109 additions and 0 deletions
82
benchmark/compiler/compiler.mjs
Normal file
82
benchmark/compiler/compiler.mjs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import { printTree } from "./utils.mjs"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child {
|
||||||
|
* char: 'a',
|
||||||
|
* children: [Child, Child],
|
||||||
|
* path: null / 'full/path',
|
||||||
|
* count: 0
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
function Child(char) {
|
||||||
|
this.char = char
|
||||||
|
this.children = []
|
||||||
|
this.path = null
|
||||||
|
this.count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildChild(i, arr) {
|
||||||
|
let letter = new Child(arr[0][i])
|
||||||
|
let consume = []
|
||||||
|
if (arr[0].length === i + 1) {
|
||||||
|
letter.path = arr[0]
|
||||||
|
letter.count += 1
|
||||||
|
} else {
|
||||||
|
consume = [arr[0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let y = 1; y < arr.length; y++) {
|
||||||
|
if (arr[y][i] !== letter.char) break
|
||||||
|
consume.push(arr[y])
|
||||||
|
}
|
||||||
|
|
||||||
|
letter.count += consume.length
|
||||||
|
while (consume.length) {
|
||||||
|
letter.children.push(buildChild(i + 1, consume))
|
||||||
|
consume.splice(0, letter.children[letter.children.length - 1].count)
|
||||||
|
}
|
||||||
|
return letter
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildTree(all) {
|
||||||
|
let paths = Array.from(new Set(all)).sort()
|
||||||
|
let builder = []
|
||||||
|
while (paths.length) {
|
||||||
|
builder.push(buildChild(0, paths))
|
||||||
|
paths.splice(0, builder[builder.length - 1].count)
|
||||||
|
}
|
||||||
|
printTree(builder)
|
||||||
|
return builder
|
||||||
|
}
|
||||||
|
|
||||||
|
function IfTreeBranch(branches, indent = 0) {
|
||||||
|
let output = ''
|
||||||
|
let indentation = ''.padStart(indent * 2)
|
||||||
|
|
||||||
|
for (let i = 0; i < branches.length; i++) {
|
||||||
|
let branch = branches[i]
|
||||||
|
output += `${i > 0 ? 'else ': ''}if (str.charCodeAt(${indent}) === ${branch.char.charCodeAt(0)}) {`
|
||||||
|
|
||||||
|
if (branch.path) {
|
||||||
|
output += '\n' + indentation + ` if (str.length === ${branch.path.length}) {`
|
||||||
|
output += '\n' + indentation + ` return "${branch.path}"`
|
||||||
|
output += '\n' + indentation + ` }`
|
||||||
|
}
|
||||||
|
if (branch.children.length) {
|
||||||
|
if (branch.path) {
|
||||||
|
output += ' else '
|
||||||
|
} else {
|
||||||
|
output += '\n' + indentation + ' '
|
||||||
|
}
|
||||||
|
output += IfTreeBranch(branch.children, indent + 1)
|
||||||
|
}
|
||||||
|
output += '\n' + indentation + '} '
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
export function compileTreeIntoIfs(tree) {
|
||||||
|
let output = IfTreeBranch(tree)
|
||||||
|
output += '\nreturn null'
|
||||||
|
return new Function(output)
|
||||||
|
}
|
8
benchmark/compiler/utils.mjs
Normal file
8
benchmark/compiler/utils.mjs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
export function printTree(children, indent = 0) {
|
||||||
|
if (!children.length) return
|
||||||
|
|
||||||
|
for (let child of children) {
|
||||||
|
console.log(child.char.padStart(1 + indent * 2))
|
||||||
|
printTree(child.children, indent + 1)
|
||||||
|
}
|
||||||
|
}
|
19
benchmark/strings.mjs
Normal file
19
benchmark/strings.mjs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { buildTree, compileTreeIntoIfs } from "./compiler/compiler.mjs"
|
||||||
|
|
||||||
|
let paths = [
|
||||||
|
'test1',
|
||||||
|
'test',
|
||||||
|
'test3',
|
||||||
|
'test5',
|
||||||
|
'something',
|
||||||
|
'sometimes',
|
||||||
|
'else',
|
||||||
|
'goes',
|
||||||
|
'here',
|
||||||
|
'too',
|
||||||
|
]
|
||||||
|
|
||||||
|
let tree = buildTree(paths)
|
||||||
|
|
||||||
|
const ifTree = compileTreeIntoIfs(tree)
|
||||||
|
console.log(ifTree.toString())
|
Loading…
Reference in a new issue