package vm import ( "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 { vm.modules = make([]modules.Module, 0, len(vm.main.Deps())) // Add all natives to the VM as globals. for _, native := range natives.Natives { decollidedName := fmt.Sprintf("%s#native", native.Name) if _, ok := vm.globals[decollidedName]; ok { return fmt.Errorf("native %s already exists", decollidedName) } nativeFunc := native.Fn // Capture the native function, because Go is fun. wrappedFunc := func(args []value.Value) (value.Value, error) { return nativeFunc(vm, args) } nativeFunction := value.NewNativeFunction(wrappedFunc, uint(native.ArgCount)) if err := vm.AddGlobal(decollidedName, nativeFunction); err != nil { return err } } 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()) } }