about summary refs log tree commit diff
path: root/pkg/lang/vm/setup.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/lang/vm/setup.go')
-rw-r--r--pkg/lang/vm/setup.go58
1 files changed, 34 insertions, 24 deletions
diff --git a/pkg/lang/vm/setup.go b/pkg/lang/vm/setup.go
index db44b8a..201538d 100644
--- a/pkg/lang/vm/setup.go
+++ b/pkg/lang/vm/setup.go
@@ -1,44 +1,54 @@
 package vm
 
 import (
-	"jinx/pkg/lang/vm/mem"
+	"fmt"
+	"jinx/pkg/lang/modules"
+	"jinx/pkg/lang/modules/core"
+	"jinx/pkg/lang/modules/natives"
 	"jinx/pkg/lang/vm/value"
 )
 
 func (vm *VM) setup() error {
-	if err := vm.setupCoreLib(); err != nil {
-		return err
-	}
+	vm.modules = make([]modules.Module, 0, len(vm.main.Deps()))
 
-	return nil
-}
+	// Add all natives to the VM as globals.
+	for _, native := range natives.Natives {
+		decollidedName := fmt.Sprintf("%s#native", native.Name)
 
-func (vm *VM) setupCoreLib() error {
-	type allocationJob struct {
-		at mem.Ptr
-		t  value.Type
-	}
+		if _, ok := vm.globals[decollidedName]; ok {
+			return fmt.Errorf("native %s already exists", decollidedName)
+		}
 
-	toAllocate := []allocationJob{
-		{at: value.CORE_TYPE_NULL, t:  vm.createCoreNullType()},
-		{at: value.CORE_TYPE_INT, t:  vm.createCoreIntType()},
-		{at: value.CORE_TYPE_FLOAT, t:  vm.createCoreFloatType()},
-		{at: value.CORE_TYPE_STRING, t:  vm.createCoreStringType()},
-		{at: value.CORE_TYPE_BOOL, t:  vm.createCoreBoolType()},
-		{at: value.CORE_TYPE_ARRAY, t:  vm.createCoreArrayType()},
-		{at: value.CORE_TYPE_FUNCTION, t:  vm.createCoreFunctionType()},
-		{at: value.CORE_TYPE_TYPE_REF, t:  vm.createCoreTypeRefType()},
-	}
+		nativeFunc := native.Fn // Capture the native function, because Go is fun.
+		wrappedFunc := func(args []value.Value) (value.Value, error) {
+			return nativeFunc(vm, args)
+		}
 
-	for _, job := range toAllocate {
-		if err := vm.memory.AllocateAt(job.at, mem.CellKindType); err != nil {
+		nativeFunction := value.NewNativeFunction(wrappedFunc, uint(native.ArgCount))
+		if err := vm.AddGlobal(decollidedName, nativeFunction); err != nil {
 			return err
 		}
+	}
 
-		if err := vm.memory.Set(job.at, value.TypeCell(job.t)); err != nil {
+	for _, depRef := range vm.main.Deps() {
+		dep, err := vm.resolveModule(depRef)
+		if err != nil {
 			return err
 		}
+
+		vm.modules = append(vm.modules, dep)
 	}
 
 	return nil
 }
+
+// TODO: Make an actual module resolver.
+func (vm *VM) resolveModule(ref modules.ModuleRef) (modules.Module, error) {
+	// TODO: Support other modules than core.
+	switch ref.Name() {
+	case "core":
+		return core.Module, nil
+	default:
+		return modules.Module{}, fmt.Errorf("unknown module: %s", ref.Name())
+	}
+}