Documentation
¶
Overview ¶
Package globals provides core functionality for module imports and dependency resolution in the Xel programming language. It handles both local file imports and remote package resolution, including dependency management and circular import detection.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var Import = values.MK_NATIVE_FN(func(args []shared.RuntimeValue, env *environment.Environment) (*shared.RuntimeValue, *errors.RuntimeError) { if len(args) != 1 { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("`import` requires exactly one argument, but received %d", len(args)), } } if args[0].Type != shared.String { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("`import` expects a string argument, but received %s (%s)", helpers.Stringify(args[0], false), shared.Stringify(args[0].Type)), } } libname := args[0].Value.(string) if loader, isNative := modules.GetNativeModuleLoader(libname); isNative { return loader() } libpath := fmt.Sprintf("%s.xel", libname) useCache := true modEnv := environment.NewEnvironment(xShared.XelRootEnv) if libname[0] == '.' { dirname := filepath.Dir(xShared.XelRootDebugger.CurrentFile) libpath = filepath.Join(dirname, libpath) } else { processRuntimeVal, err := env.LookupVar("proc") if err != nil { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Failed to lookup process information: %v", err), } } if processRuntimeVal.Type != shared.Object { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Expected 'proc' to be an object, but got %s (%s)", helpers.Stringify(*processRuntimeVal, false), shared.Stringify(processRuntimeVal.Type)), } } processObj := processRuntimeVal.Value.(map[string]*shared.RuntimeValue) manifestRuntimeVal, exists := processObj["manifest"] if !exists || manifestRuntimeVal == nil { return nil, &errors.RuntimeError{ Message: "Project manifest is not available in process object", } } if manifestRuntimeVal.Type != shared.Object { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Expected manifest to be an object, but got %s (%s)", helpers.Stringify(*manifestRuntimeVal, false), shared.Stringify(manifestRuntimeVal.Type)), } } manifest := manifestRuntimeVal.Value.(map[string]*shared.RuntimeValue) depsVal, depsExists := manifest["deps"] if !depsExists || depsVal.Type != shared.Object { return nil, &errors.RuntimeError{ Message: "Project manifest is missing or has invalid 'dependencies' section", } } dependencies := depsVal.Value.(map[string]*shared.RuntimeValue) pkgConstraint, exists := dependencies[libname] if !exists { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Package '%s' is not listed in the project's dependencies", libname), } } constraint := pkgConstraint.Value.(string) pkgManifestPath, pkgManifest, resolutionErr := helpers.ResolveModuleLocal(libname, constraint) if resolutionErr != nil { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Failed to resolve package '%s' (constraint: %s): %v", libname, constraint, resolutionErr), } } manifestConverted := map[string]*shared.RuntimeValue{} addStringField := func(key, value string) { val := values.MK_STRING(value) manifestConverted[key] = &val } addStringField("name", pkgManifest.Name) addStringField("description", pkgManifest.Description) addStringField("version", pkgManifest.Version) addStringField("xel", *pkgManifest.Xel) addStringField("engine", *pkgManifest.Engine) addStringField("main", pkgManifest.Main) addStringField("author", pkgManifest.Author) addStringField("license", pkgManifest.License) depsMap := make(map[string]*shared.RuntimeValue, len(*pkgManifest.Deps)) for depName, depConstraint := range *pkgManifest.Deps { depVal := values.MK_STRING(depConstraint) depsMap[depName] = &depVal } depsObj := values.MK_OBJECT(depsMap) manifestConverted["deps"] = &depsObj modifiedProc := helpers.DeepCopyObject(processRuntimeVal.Value.(map[string]*shared.RuntimeValue)) manifestVal := values.MK_OBJECT(manifestConverted) modifiedProc["manifest"] = &manifestVal modEnv.DeclareVar("proc", values.MK_OBJECT(modifiedProc), true) pkgPath := filepath.Dir(pkgManifestPath) libpath = filepath.Join(pkgPath, pkgManifest.Main) } if resolvingImports[libpath] { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("Circular import detected while importing '%s'", libpath), } } if val, exists := importCache[libpath]; exists && useCache { return val, nil } resolvingImports[libpath] = true defer delete(resolvingImports, libpath) libExports, err := evaluateModule(libpath, modEnv) if err != nil { return nil, err } return libExports, nil })
Import is the native function implementation for the `import` statement in Xel. It handles module resolution, caching, and circular dependency detection.
Supported import patterns:
- Local file: import("./path/to/file")
- Scoped package: import("@scope/package")
- Regular package: import("package")
The function performs the following operations: 1. Validates the import statement syntax 2. Resolves the module path (local or remote) 3. Checks for circular dependencies 4. Returns cached module if available 5. Otherwise, loads and evaluates the module
var Len = values.MK_NATIVE_FN(func(args []shared.RuntimeValue, env *environment.Environment) (*shared.RuntimeValue, *errors.RuntimeError) { if len(args) != 1 { return nil, &errors.RuntimeError{ Message: "len() takes exactly one argument", } } if args[0].Type != shared.Array && args[0].Type != shared.String { return nil, &errors.RuntimeError{ Message: "len() takes an array or string as an argument", } } result := values.MK_NIL() if args[0].Type == shared.String { result = values.MK_NUMBER(float64(len(args[0].Value.(string)))) } else { result = values.MK_NUMBER(float64(len(args[0].Value.([]shared.RuntimeValue)))) } return &result, nil })
var Print = values.MK_NATIVE_FN(func(args []shared.RuntimeValue, env *environment.Environment) (*shared.RuntimeValue, *errors.RuntimeError) { out := "" for i, arg := range args { out += helpers.Stringify(arg, false) if len(args)-1 != i { out += " " } } fmt.Printf("%s\r\n", out) result := values.MK_NIL() return &result, nil })
var Throw = values.MK_NATIVE_FN(func(args []shared.RuntimeValue, env *environment.Environment) (*shared.RuntimeValue, *errors.RuntimeError) { if len(args) != 1 { return nil, &errors.RuntimeError{Message: "throw() takes exactly one argument"} } if args[0].Type != shared.String { return nil, &errors.RuntimeError{ Message: fmt.Sprintf("throw() takes a string as an argument, but got %s", shared.Stringify(args[0].Type)), } } out := args[0].Value.(string) return nil, &errors.RuntimeError{Message: out} })
var Typeof = values.MK_NATIVE_FN(func(args []shared.RuntimeValue, env *environment.Environment) (*shared.RuntimeValue, *errors.RuntimeError) { if len(args) != 1 { return nil, &errors.RuntimeError{ Message: "typeof() takes exactly one argument", } } result := values.MK_STRING(shared.Stringify(args[0].Type)) return &result, nil })
Functions ¶
func Globalize ¶
func Globalize(env *environment.Environment)
func Proc ¶
func Proc() shared.RuntimeValue
Types ¶
This section is empty.