about summary refs log tree commit diff
path: root/pkg/lang/compiler/compiler_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/compiler/compiler_test.go')
-rw-r--r--pkg/lang/compiler/compiler_test.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/pkg/lang/compiler/compiler_test.go b/pkg/lang/compiler/compiler_test.go
new file mode 100644
index 0000000..2477b21
--- /dev/null
+++ b/pkg/lang/compiler/compiler_test.go
@@ -0,0 +1,83 @@
+package compiler_test
+
+import (
+	"jinx/pkg/lang/compiler"
+	"jinx/pkg/lang/parser"
+	"jinx/pkg/lang/scanner"
+	"jinx/pkg/lang/vm/text"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+func TestSimpleAddExpr(t *testing.T) {
+	src := `
+	1 + 2
+	`
+
+	expected := `
+	push_int 2
+	push_int 1
+	add
+	`
+
+	mustCompileTo(t, src, expected)
+}
+
+func TestNestedExpr(t *testing.T) {
+	// Yeah, we don't compile identifiers yet, so here we call and index directly on literals.
+	src := `
+	1 + 2 - 3 - (123("a", "b", "c") + 456[321])
+	`
+
+	expected := `
+	push_int 321
+	push_int 456
+	index
+
+	push_string "c"
+	push_string "b"
+	push_string "a"
+	push_int 123
+	call
+
+	add
+
+	push_int 3
+	sub
+
+	push_int 2
+	sub
+
+	push_int 1
+	add
+	`
+
+	mustCompileTo(t, src, expected)
+}
+
+func mustCompileTo(t *testing.T, src, expected string) {
+	scanner := scanner.New(strings.NewReader(src))
+	tokens, err := scanner.Scan()
+	require.NoError(t, err)
+
+	parser := parser.New(tokens)
+	program, err := parser.Parse()
+	require.NoError(t, err)
+
+	langCompiler := compiler.New(program)
+	testResult, err := langCompiler.Compile()
+	require.NoError(t, err)
+
+	textCompiler := text.NewCompiler(strings.NewReader(expected))
+	expectedResult, err := textCompiler.Compile()
+	require.NoError(t, err)
+
+	if !assert.Equal(t, expectedResult.Code(), testResult.Code()) {
+		d1 := text.NewDecompiler(expectedResult)
+		d2 := text.NewDecompiler(testResult)
+		require.Equal(t, d1.Decompile(), d2.Decompile())
+	}
+}