initial commit

This commit is contained in:
mae
2026-01-23 03:20:34 -06:00
commit 2566f9dbf3
8 changed files with 468 additions and 0 deletions

91
schema/parse_test.go Normal file
View File

@@ -0,0 +1,91 @@
package schema
import (
"fmt"
"os"
"os/exec"
"strings"
"testing"
"unsafe"
gv "github.com/dominikbraun/graph"
"github.com/dominikbraun/graph/draw"
)
func TestParse(t *testing.T) {
in := "()" +
"(test)" +
"(test a)" +
"(test a b)" +
"(test a b c)" +
"(test (a b c))" +
"(test (a b c d))" +
"(\"hello world\")" +
"(concat \"hello\" \"world\")" +
"(+ 1 2)"
want := "( <nil> <nil>)\n" +
"(test <nil> <nil>)\n" +
"(test [n'a'] <nil>)\n" +
"(test [n'a'] [n'b'])\n" +
"(. [n'test'] (. [n'a'] (. [n'b'] [n'c'])))\n" +
"(test (a [n'b'] [n'c']) <nil>)\n" +
"(test (. [n'a'] (. [n'b'] (. [n'c'] [n'd']))) <nil>)\n" +
"[l'hello world']\n" +
"(concat [l'hello'] [l'world'])\n" +
"(+ [l1] [l2])\n"
tokens, err := Tokenize([]byte(in))
if err != nil {
t.Fatal(err)
}
parse, err := Parse(tokens)
if err != nil {
t.Fatal(err)
}
test := strings.Builder{}
for _, line := range parse {
test.Write([]byte(fmt.Sprintf("%s\n", line)))
}
if test.String() != want {
t.Errorf("\ngot:\n%s\nwant:\n%s", test.String(), want)
}
if os.Getenv("AZALEA_TEST_VISUALIZE") == "1" {
Visualize(parse)
}
}
func hash(n *Node) uintptr {
return uintptr(unsafe.Pointer(n))
}
func Visualize(nodes []*Node) {
g := gv.New(hash, gv.Tree(), gv.Directed())
for _, node := range nodes {
addNode(node, g)
}
dot, _ := os.CreateTemp("", "azalea-graph-*.gv")
_ = draw.DOT(g, dot)
_ = exec.Command("dot", "-Tsvg", "-O", dot.Name()).Run()
_ = exec.Command("qimgv", dot.Name()+".svg").Run()
_ = os.Remove(dot.Name())
_ = os.Remove(dot.Name() + ".svg")
}
func addNode(node *Node, g gv.Graph[uintptr, *Node]) *Node {
str := ""
if node.Function != "" {
str = node.Function
} else {
if node.Token != nil {
str = node.Token.String()
} else {
return nil
}
}
_ = g.AddVertex(node, gv.VertexAttribute("label", str))
if node.Left != nil {
left := addNode(node.Left, g)
_ = g.AddEdge(hash(node), hash(left), gv.EdgeAttribute("splines", "line"))
}
if node.Right != nil {
right := addNode(node.Right, g)
_ = g.AddEdge(hash(node), hash(right), gv.EdgeAttribute("splines", "line"))
}
return node
}