about summary refs log tree commit diff
path: root/pkg/lang
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang')
-rw-r--r--pkg/lang/modules/core/natives.go14
-rw-r--r--pkg/lang/vm/exe.go4
-rw-r--r--pkg/lang/vm/executor/executor.go2
-rw-r--r--pkg/lang/vm/output.go45
-rw-r--r--pkg/lang/vm/vm.go6
-rw-r--r--pkg/lang/vm/vm_test.go28
6 files changed, 81 insertions, 18 deletions
diff --git a/pkg/lang/modules/core/natives.go b/pkg/lang/modules/core/natives.go
index c06b35c..8a24663 100644
--- a/pkg/lang/modules/core/natives.go
+++ b/pkg/lang/modules/core/natives.go
@@ -116,13 +116,21 @@ var Natives = []any{
 
 	n(":core:say", 1, func(exe executor.Exectutor, args []value.Value) (value.Value, error) {
 		message := args[0]
-		s, err := message.Data().String(exe.Mem())
+
+		// We don't want strings to have the "".
+		var err error
+		var s string
+		if message.Type() == value.StringType {
+			s, err = message.Data().(value.StringData).RawString(exe.Mem())
+		} else {
+			s, err = message.Data().String(exe.Mem())
+		}
+
 		if err != nil {
 			return value.Value{}, err
 		}
 
-		fmt.Println(s)
-		return value.Value{}, nil
+		return value.Value{}, exe.Write(s)
 	}),
 }
 
diff --git a/pkg/lang/vm/exe.go b/pkg/lang/vm/exe.go
index 7d6fc61..5d40133 100644
--- a/pkg/lang/vm/exe.go
+++ b/pkg/lang/vm/exe.go
@@ -60,3 +60,7 @@ func (vm *VM) GetGlobal(name string) (value.Value, bool, error) {
 
 	return v, true, nil
 }
+
+func (vm *VM) Write(message string) error {
+	return vm.output.Write(message)
+}
diff --git a/pkg/lang/vm/executor/executor.go b/pkg/lang/vm/executor/executor.go
index 0b7ccef..1ab3773 100644
--- a/pkg/lang/vm/executor/executor.go
+++ b/pkg/lang/vm/executor/executor.go
@@ -14,4 +14,6 @@ type Exectutor interface {
 
 	AddGlobal(name string, v value.Value) error
 	GetGlobal(name string) (value.Value, bool, error)
+
+	Write(message string) error
 }
diff --git a/pkg/lang/vm/output.go b/pkg/lang/vm/output.go
new file mode 100644
index 0000000..1ef2357
--- /dev/null
+++ b/pkg/lang/vm/output.go
@@ -0,0 +1,45 @@
+package vm
+
+type Output interface {
+	Write(message string) error
+}
+
+type EmptyOutput struct{}
+
+func NewEmptyOutput() *EmptyOutput {
+	return &EmptyOutput{}
+}
+
+func (o *EmptyOutput) Write(message string) error {
+	return nil
+}
+
+type GatheringOutput struct {
+	messages []string
+}
+
+func NewGatheringOutput() *GatheringOutput {
+	return &GatheringOutput{
+		messages: make([]string, 0, 8),
+	}
+}
+
+func (o *GatheringOutput) Messages() []string {
+	return o.messages
+}
+
+func (o *GatheringOutput) Write(message string) error {
+	o.messages = append(o.messages, message)
+	return nil
+}
+
+type ConsoleOutput struct{}
+
+func NewConsoleOutput() *ConsoleOutput {
+	return &ConsoleOutput{}
+}
+
+func (o *ConsoleOutput) Write(message string) error {
+	println(message)
+	return nil
+}
diff --git a/pkg/lang/vm/vm.go b/pkg/lang/vm/vm.go
index f24095d..4d4d5ca 100644
--- a/pkg/lang/vm/vm.go
+++ b/pkg/lang/vm/vm.go
@@ -21,9 +21,11 @@ type VM struct {
 	globals       map[string]mem.Ptr
 
 	corePtrs value.CorePtrs
+
+	output Output
 }
 
-func New(main modules.Module) *VM {
+func New(main modules.Module, output Output) *VM {
 	vm := &VM{
 		pos: code.NewPos(-1, 0),
 
@@ -37,6 +39,8 @@ func New(main modules.Module) *VM {
 		globals:       make(map[string]mem.Ptr),
 
 		corePtrs: value.CorePtrs{},
+
+		output: output,
 	}
 
 	if err := vm.setup(); err != nil {
diff --git a/pkg/lang/vm/vm_test.go b/pkg/lang/vm/vm_test.go
index 8f961ef..8c31d1f 100644
--- a/pkg/lang/vm/vm_test.go
+++ b/pkg/lang/vm/vm_test.go
@@ -5,7 +5,6 @@ import (
 	"jinx/pkg/lang/vm"
 	"jinx/pkg/lang/vm/code"
 	"jinx/pkg/lang/vm/text"
-	"os"
 	"strings"
 	"testing"
 
@@ -496,18 +495,7 @@ func TestCoreSay(t *testing.T) {
 	halt
 	`
 
-	previous := os.Stdout
-	r, w, _ := os.Pipe()
-	defer w.Close()
-	os.Stdout = w
-	test(t, src, "0")
-	os.Stdout = previous
-
-	result := make([]byte, 8)
-	_, err := r.Read(result)
-	require.NoError(t, err)
-
-	require.Equal(t, "\"Meow!!\"", string(result))
+	testOutput(t, src, "Meow!!")
 }
 
 func TestSetAtArray(t *testing.T) {
@@ -539,7 +527,7 @@ func TestSetAtArray(t *testing.T) {
 
 func test(t *testing.T, src string, expected string) {
 	bc := compile(t, src)
-	vm := vm.New(modules.NewUnknownModule(&bc))
+	vm := vm.New(modules.NewUnknownModule(&bc), vm.NewEmptyOutput())
 	err := vm.Run()
 	require.NoError(t, err)
 
@@ -549,6 +537,18 @@ func test(t *testing.T, src string, expected string) {
 	require.Equal(t, expected, res)
 }
 
+func testOutput(t *testing.T, src string, expected string) {
+	output := vm.NewGatheringOutput()
+
+	bc := compile(t, src)
+	vm := vm.New(modules.NewUnknownModule(&bc), output)
+	err := vm.Run()
+	require.NoError(t, err)
+
+	lastMessage := output.Messages()[len(output.Messages())-1]
+	require.Equal(t, expected, lastMessage)
+}
+
 func compile(t *testing.T, src string) code.Code {
 	comp := text.NewCompiler(strings.NewReader(src))
 	bc, err := comp.Compile()