package text_test import ( "jinx/pkg/lang/vm/code" "jinx/pkg/lang/vm/text" "strings" "testing" "github.com/stretchr/testify/require" ) func TestSimple(t *testing.T) { src := ` add sub ret ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewBuilder() exp.AppendOp(code.OpAdd) exp.AppendOp(code.OpSub) exp.AppendOp(code.OpRet) require.Equal(t, exp.Code(), res.Code()) } func TestInt(t *testing.T) { src := ` push_int 1 push_int 2 add ret ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewBuilder() exp.AppendOp(code.OpPushInt) exp.AppendInt(1) exp.AppendOp(code.OpPushInt) exp.AppendInt(2) exp.AppendOp(code.OpAdd) exp.AppendOp(code.OpRet) require.Equal(t, exp.Code(), res.Code()) } func TestFloat(t *testing.T) { src := ` push_float 3.1415 push_float -2.71828 ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewBuilder() exp.AppendOp(code.OpPushFloat) exp.AppendFloat(3.1415) exp.AppendOp(code.OpPushFloat) exp.AppendFloat(-2.71828) require.Equal(t, exp.Code(), res.Code()) } func TestString(t *testing.T) { src := ` push_string "Hello, " push_string "world!" add ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewBuilder() exp.AppendOp(code.OpPushString) exp.AppendString("Hello, ") exp.AppendOp(code.OpPushString) exp.AppendString("world!") exp.AppendOp(code.OpAdd) require.Equal(t, exp.Code(), res.Code()) } func TestLabels(t *testing.T) { src := ` @1: nop @2: nop @3: nop jmp @1 jmp @2 jmp @3 ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewBuilder() exp.AppendOp(code.OpNop) exp.AppendOp(code.OpNop) exp.AppendOp(code.OpNop) exp.AppendOp(code.OpJmp) exp.AppendInt(0) exp.AppendOp(code.OpJmp) exp.AppendInt(1) exp.AppendOp(code.OpJmp) exp.AppendInt(2) require.Equal(t, exp.Code(), res.Code()) } func TestDebugInfo(t *testing.T) { src := ` push_int 1 push_int 2 add add @1: nop ret ` c := text.NewCompiler(strings.NewReader(src)) res, err := c.Compile() require.NoError(t, err) exp := code.NewDebugInfo("unknown file") exp.AppendLine(8, 1) exp.AppendLine(17, 2) exp.AppendLine(18, 4) exp.AppendLine(19, 5) exp.AppendLine(20, 8) exp.AppendLine(21, 9) require.Equal(t, exp, *res.Debug()) } // func opBin(op code.Op) []byte { // return []byte{byte(op)} // } // func uintBin(x uint64) []byte { // res := make([]byte, 8) // binary.LittleEndian.PutUint64(res, x) // return res // } // func floatBin(x float64) []byte { // res := make([]byte, 8) // binary.LittleEndian.PutUint64(res, math.Float64bits(x)) // return res // } // func stringBin(x string) []byte { // res := []byte(x) // res = append(res, 0) // return res // } // func joinSlices[T any](slices [][]T) []T { // res := []T{} // for _, slice := range slices { // res = append(res, slice...) // } // return res // }