test mml document
This commit is contained in:
parent
baa2ceede8
commit
502e17ebb5
54
mml_test.go
54
mml_test.go
@ -1,6 +1,12 @@
|
||||
package treerack
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestMML(t *testing.T) {
|
||||
test(t, "mml.parser", "mml", []testItem{{
|
||||
@ -2855,3 +2861,49 @@ func TestMML(t *testing.T) {
|
||||
ignorePosition: true,
|
||||
}})
|
||||
}
|
||||
|
||||
func TestMMLFile(t *testing.T) {
|
||||
const n = 18
|
||||
|
||||
s, err := testSyntax("mml.parser", 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
s.Init()
|
||||
|
||||
f, err := os.Open("test.mml")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
defer f.Close()
|
||||
|
||||
var d time.Duration
|
||||
for i := 0; i < n && !t.Failed(); i++ {
|
||||
func() {
|
||||
if _, err := f.Seek(0, 0); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
b := bytes.NewBuffer(nil)
|
||||
if _, err := io.Copy(b, f); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
_, err = s.Parse(b)
|
||||
d += time.Now().Sub(start)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
t.Log("average duration:", d/n)
|
||||
}
|
||||
|
163
test.mml
Normal file
163
test.mml
Normal file
@ -0,0 +1,163 @@
|
||||
fn defaultCompare(a, b) {
|
||||
switch {
|
||||
case a < b: -1
|
||||
case a > b: 1
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
|
||||
let undefined {}
|
||||
|
||||
fn treeWithCompare(compare) {
|
||||
compare: compare
|
||||
node: undefined
|
||||
}
|
||||
|
||||
let tree treeWithCompare(defaultCompare)
|
||||
|
||||
fn nextNode(compare, node, value) {
|
||||
if node == undefined {
|
||||
undefined
|
||||
} else {
|
||||
let c compare(node.value, value)
|
||||
switch {
|
||||
case c > 0:
|
||||
match node {
|
||||
case {less}: nextNode(compare, node.less, value)
|
||||
default: node
|
||||
}
|
||||
default:
|
||||
match node {
|
||||
case {greater}: nextNode(compare, node.greater, value)
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prevNode(compare, node, value) {
|
||||
if node == undefined {
|
||||
undefined
|
||||
} else {
|
||||
let c compare(node.value, value)
|
||||
switch {
|
||||
case c < 0:
|
||||
match node {
|
||||
case {greater}: prevNode(compare, node.greater, value)
|
||||
default: node
|
||||
}
|
||||
default:
|
||||
match node {
|
||||
case {less}: prevNode(compare, node.less, value)
|
||||
default: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn findNode(compare, node, value) {
|
||||
switch {
|
||||
case node == undefined: false
|
||||
case node.value == value: true
|
||||
case compare(node.value, value) < 0:
|
||||
findNode(compare, node.greater, value)
|
||||
default:
|
||||
findNode(compare, node.less, value)
|
||||
}
|
||||
}
|
||||
|
||||
fn delNode(compare, node, value) {
|
||||
fn delBetween() {
|
||||
let next nextNode(compare, node, node.value)
|
||||
{ node...
|
||||
value: next.value
|
||||
greater: delNode(compare, node.greater, next.value)
|
||||
} /* -> updateDepth() */ -> balance()
|
||||
}
|
||||
|
||||
fn delCurrent() {
|
||||
match node {
|
||||
case {less, greater}: delBetween()
|
||||
case {less}: node.less
|
||||
case {greater}: node.greater
|
||||
}
|
||||
}
|
||||
|
||||
fn delGreater() {
|
||||
match node {
|
||||
case {greater}:
|
||||
{ node...
|
||||
greater: delNode(compare, node.greater, node.value)
|
||||
} /* -> udpateDepth() */ -> balance()
|
||||
default:
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
fn delLess() {
|
||||
match node {
|
||||
case {less}:
|
||||
{ node...
|
||||
less: delNode(compare, node.less, node.value)
|
||||
} /* -> udpateDepth() */ -> balance()
|
||||
default:
|
||||
node
|
||||
}
|
||||
}
|
||||
|
||||
fn delNode() {
|
||||
let c compare(node.value, value)
|
||||
switch {
|
||||
case c == 0: delCurrent()
|
||||
case c < 0: delGreater()
|
||||
default: delLess()
|
||||
}
|
||||
}
|
||||
|
||||
node == undefined ? undefined : delNode()
|
||||
}
|
||||
|
||||
fn insertNode(compare, node, value) {
|
||||
if node == undefined {
|
||||
{value: value}
|
||||
} else {
|
||||
let c compare(node.value, value)
|
||||
switch {
|
||||
case c > 0:
|
||||
{node..., greater: insertNode(compare, node.greater, value)} /* -> updateDepth() */ -> balance()
|
||||
case c < 0:
|
||||
{node..., less: insertNode(compare, node.less, value)} /* -> updateDepth() */ -> balance()
|
||||
default:
|
||||
node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prevNextValue(f, tree, value) {
|
||||
let node f(tree.compare, tree.node, value)
|
||||
node == undefined ? value : node.value
|
||||
}
|
||||
|
||||
fn update(f, tree, value) {
|
||||
tree...
|
||||
node: f(tree.compare, tree.node, value)
|
||||
}
|
||||
|
||||
type alias tree {compare: fn (a, a) int, node: {}}
|
||||
type next fn (tree, a) a
|
||||
type prev fn (tree, a) a
|
||||
type find fn (tree, a) bool
|
||||
type delete fn (tree, a) tree
|
||||
type insert fn (tree, a) tree
|
||||
|
||||
let (
|
||||
next = prevNextValue(prevNode)
|
||||
prev = prevNextValue(nextNode)
|
||||
)
|
||||
|
||||
fn find(tree, value) findNode(tree.compare, tree.node, value) != undefined
|
||||
|
||||
let (
|
||||
del update(delNode)
|
||||
insert update(insertNode)
|
||||
)
|
Loading…
Reference in New Issue
Block a user