126 lines
3.1 KiB
Go
126 lines
3.1 KiB
Go
package generator
|
|
|
|
import "testing"
|
|
import "strings"
|
|
import "github.com/google/uuid"
|
|
import "git.tebibyte.media/fspl/fspl/lexer"
|
|
import "git.tebibyte.media/fspl/fspl/errors"
|
|
import "git.tebibyte.media/fspl/fspl/entity"
|
|
import "git.tebibyte.media/fspl/fspl/analyzer"
|
|
import "git.tebibyte.media/fspl/fspl/testcommon"
|
|
import "git.tebibyte.media/fspl/fspl/parser/fspl"
|
|
|
|
func testString (test *testing.T, correct string, input string) {
|
|
address := entity.Address("main.fspl")
|
|
ast, ok := treeOf(test, address, input, false)
|
|
if !ok { return }
|
|
|
|
tree := analyzer.Tree { }
|
|
err := tree.Analyze(address.UUID(), nil, ast)
|
|
if err != nil {
|
|
test.Error("analyzer returned error:\n" + errors.Format(err))
|
|
return
|
|
}
|
|
|
|
testSemanticTree(test, correct, input, tree)
|
|
}
|
|
|
|
func testUnits (
|
|
test *testing.T,
|
|
correct string,
|
|
main string,
|
|
dependencies ...string,
|
|
) {
|
|
if len(dependencies) % 2 != 0 {
|
|
panic("dependencies len must be even. forget an address?")
|
|
}
|
|
tree := analyzer.Tree { }
|
|
nicknames := make(map[string] uuid.UUID)
|
|
|
|
// dependencies
|
|
for index := 0; index < len(dependencies) - 1; index += 2 {
|
|
address := entity.Address(dependencies[index])
|
|
test.Log("analyzing", address, "UUID", address.UUID())
|
|
source := dependencies[index + 1]
|
|
ast, ok := treeOf(test, address, source, true)
|
|
if !ok { return }
|
|
|
|
err := tree.Analyze(address.UUID(), nicknames, ast)
|
|
if err != nil {
|
|
test.Error("analyzer returned error:\n" + errors.Format(err))
|
|
return
|
|
}
|
|
|
|
unit := address.UUID()
|
|
nickname, ok := address.Nickname()
|
|
if !ok {
|
|
test.Errorf("could not generate nickname for %v", address)
|
|
return
|
|
}
|
|
nicknames[nickname] = unit
|
|
}
|
|
|
|
// main
|
|
address := entity.Address("main.fspl")
|
|
test.Log("analyzing MAIN", address, "UUID", address.UUID())
|
|
ast, ok := treeOf(test, address, main, false)
|
|
if !ok { return }
|
|
err := tree.Analyze(address.UUID(), nicknames, ast)
|
|
if err != nil {
|
|
test.Error("analyzer returned error:\n" + errors.Format(err))
|
|
return
|
|
}
|
|
|
|
testSemanticTree(test, correct, "", tree)
|
|
}
|
|
|
|
func testSemanticTree (test *testing.T, correct string, input string, tree analyzer.Tree) {
|
|
module, err := (&Target {
|
|
WordSize: 64,
|
|
Arch: "x86_64",
|
|
}).Generate(tree)
|
|
if err != nil {
|
|
test.Error("generator returned error:", err)
|
|
return
|
|
}
|
|
output := new(strings.Builder)
|
|
_, err = module.WriteTo(output)
|
|
if err != nil {
|
|
test.Error("generator returned error:", err)
|
|
return
|
|
}
|
|
|
|
got := output.String()
|
|
if got != correct {
|
|
test.Logf("results do not match")
|
|
testcommon.Compare(test, correct, got)
|
|
if input != "" {
|
|
test.Log("SOURCE FSPL CODE:")
|
|
test.Log("\033[32m" + input + "\033[0m")
|
|
}
|
|
test.Fail()
|
|
}
|
|
}
|
|
|
|
func treeOf (test *testing.T, address entity.Address, input string, skim bool) (fsplParser.Tree, bool) {
|
|
ast := fsplParser.Tree { }
|
|
lx, err := lexer.LexReader (
|
|
string(address),
|
|
strings.NewReader(input))
|
|
if err != nil {
|
|
test.Error("lexer returned error:\n" + errors.Format(err))
|
|
return ast, false
|
|
}
|
|
if skim {
|
|
err = ast.Skim(lx)
|
|
} else {
|
|
err = ast.Parse(lx)
|
|
}
|
|
if err != nil {
|
|
test.Error("parser returned error:\n" + errors.Format(err))
|
|
return ast, false
|
|
}
|
|
|
|
return ast, true
|
|
}
|