1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
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())
}
}
|