Documentation
¶
Index ¶
Constants ¶
View Source
const ( SocketTypeTCP = "tcp" SocketTypeUDP = "udp" SocketTypeWeb = "web" SocketTypeUnix = "unix" )
Socket types
Variables ¶
View Source
var FileBuiltins = map[string]*object.Builtin{ "fileOpen": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "fileOpen requires 1-2 arguments: path, [mode]"} } pathStr, ok := extractStringFile(args[0]) if !ok { return &object.Error{Message: "fileOpen: path must be a string"} } mode := "r" if len(args) == 2 { modeStr, ok := extractStringFile(args[1]) if !ok { return &object.Error{Message: "fileOpen: mode must be a string"} } mode = modeStr } var file *os.File var err error switch mode { case "r": file, err = os.Open(pathStr) case "w": file, err = os.Create(pathStr) case "a": file, err = os.OpenFile(pathStr, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) case "r+": file, err = os.OpenFile(pathStr, os.O_RDWR, 0644) case "w+": file, err = os.OpenFile(pathStr, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) case "a+": file, err = os.OpenFile(pathStr, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644) default: return &object.Error{Message: "fileOpen: unsupported mode '" + mode + "'. Use r, w, a, r+, w+, a+"} } if err != nil { return &object.Error{Message: "failed to open file '" + pathStr + "': " + err.Error()} } handleID := storeFileHandle(file) return &object.Integer{Value: handleID} }, }, "fileReadHandle": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "fileReadHandle requires 1-2 arguments: handleID, [size]"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileReadHandle: handleID must be an integer"} } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileReadHandle: invalid file handle"} } // Conditional size parameter var data []byte var err error if len(args) == 2 { size, ok := extractIntFile(args[1]) if !ok { return &object.Error{Message: "fileReadHandle: size must be an integer"} } if size <= 0 { data, err = io.ReadAll(file) } else { data = make([]byte, size) n, readErr := file.Read(data) if readErr != nil && readErr != io.EOF { err = readErr } else { data = data[:n] } } } else { data, err = io.ReadAll(file) } if err != nil { return &object.Error{Message: "failed to read from file: " + err.Error()} } return &object.String{Value: string(data)} }, }, "fileWriteHandle": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "fileWriteHandle requires 2 arguments: handleID, content"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileWriteHandle: handleID must be an integer"} } contentStr, ok := extractStringFile(args[1]) if !ok { return &object.Error{Message: "fileWriteHandle: content must be a string"} } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileWriteHandle: invalid file handle"} } n, err := file.WriteString(contentStr) if err != nil { return &object.Error{Message: "failed to write to file: " + err.Error()} } return &object.Integer{Value: int64(n)} }, }, "fileClose": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileClose requires 1 argument: handleID"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileClose: handleID must be an integer"} } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileClose: invalid file handle"} } err := file.Close() removeFileHandle(handleID) if err != nil { return &object.Error{Message: "failed to close file: " + err.Error()} } return &object.None{} }, }, "fileSeek": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 || len(args) > 3 { return &object.Error{Message: "fileSeek requires 2-3 arguments: handleID, offset, [whence]"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileSeek: handleID must be an integer"} } offset, ok := extractIntFile(args[1]) if !ok { return &object.Error{Message: "fileSeek: offset must be an integer"} } whence := int(io.SeekStart) if len(args) == 3 { whenceVal, ok := extractIntFile(args[2]) if !ok { return &object.Error{Message: "fileSeek: whence must be an integer"} } whence = int(whenceVal) } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileSeek: invalid file handle"} } newPos, err := file.Seek(offset, whence) if err != nil { return &object.Error{Message: "failed to seek in file: " + err.Error()} } return &object.Integer{Value: newPos} }, }, "fileTell": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileTell requires 1 argument: handleID"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileTell: handleID must be an integer"} } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileTell: invalid file handle"} } pos, err := file.Seek(0, io.SeekCurrent) if err != nil { return &object.Error{Message: "failed to get file position: " + err.Error()} } return &object.Integer{Value: pos} }, }, "fileFlush": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileFlush requires 1 argument: handleID"} } handleID, ok := extractIntFile(args[0]) if !ok { return &object.Error{Message: "fileFlush: handleID must be an integer"} } file, exists := getFileHandle(handleID) if !exists { return &object.Error{Message: "fileFlush: invalid file handle"} } err := file.Sync() if err != nil { return &object.Error{Message: "failed to flush file: " + err.Error()} } return &object.None{} }, }, "fileReadPath": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileReadPath requires 1 argument: path"} } pathStr, ok := extractStringFile(args[0]) if !ok { return &object.Error{Message: "fileReadPath: path must be a string"} } data, err := os.ReadFile(pathStr) if err != nil { return &object.Error{Message: "failed to read file '" + pathStr + "': " + err.Error()} } return &object.String{Value: string(data)} }, }, "fileWritePath": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "fileWritePath requires 2 arguments: path, content"} } pathStr, ok1 := extractStringFile(args[0]) contentStr, ok2 := extractStringFile(args[1]) if !ok1 || !ok2 { return &object.Error{Message: "fileWritePath: path/content must be strings"} } err := os.WriteFile(pathStr, []byte(contentStr), 0644) if err != nil { return &object.Error{Message: "failed to write file '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, "fileAppendPath": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "fileAppendPath requires 2 arguments: path, content"} } pathStr, ok1 := extractStringFile(args[0]) contentStr, ok2 := extractStringFile(args[1]) if !ok1 || !ok2 { return &object.Error{Message: "fileAppendPath: path/content must be strings"} } f, err := os.OpenFile(pathStr, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { return &object.Error{Message: "failed to open file '" + pathStr + "' for append: " + err.Error()} } defer f.Close() _, err = f.WriteString(contentStr) if err != nil { return &object.Error{Message: "failed to append to file '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, "fileExists": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileExists requires 1 argument: path"} } pathStr, ok := extractStringFile(args[0]) if !ok { return &object.Error{Message: "fileExists: path must be a string, got " + string(args[0].Type()) + " with value: " + args[0].Inspect()} } stat, err := os.Stat(pathStr) if err != nil { if os.IsNotExist(err) { return &object.Boolean{Value: false} } return &object.Error{Message: "error checking fileExists for '" + pathStr + "': " + err.Error()} } fileType := "file" if stat.IsDir() { fileType = "directory" } _ = fileType return &object.Boolean{Value: true} }, }, "fileRead": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fileRead requires 1 argument: path"} } pathStr, ok := extractStringFile(args[0]) if !ok { return &object.Error{Message: "fileRead: path must be a string"} } data, err := os.ReadFile(pathStr) if err != nil { return &object.Error{Message: "failed to read file '" + pathStr + "': " + err.Error()} } return &object.String{Value: string(data)} }, }, "fileWrite": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "fileWrite requires 2 arguments: path, content"} } pathStr, ok1 := extractStringFile(args[0]) contentStr, ok2 := extractStringFile(args[1]) if !ok1 || !ok2 { return &object.Error{Message: "fileWrite: path/content must be strings"} } err := os.WriteFile(pathStr, []byte(contentStr), 0644) if err != nil { return &object.Error{Message: "failed to write file '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, "fileAppend": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "fileAppend requires 2 arguments: path, content"} } pathStr, ok1 := extractStringFile(args[0]) contentStr, ok2 := extractStringFile(args[1]) if !ok1 || !ok2 { return &object.Error{Message: "fileAppend: path/content must be strings"} } f, err := os.OpenFile(pathStr, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) if err != nil { return &object.Error{Message: "failed to open file '" + pathStr + "' for append: " + err.Error()} } defer f.Close() _, err = f.WriteString(contentStr) if err != nil { return &object.Error{Message: "failed to append to file '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, }
View Source
var HttpModule = map[string]*object.Builtin{ "httpGet": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "httpGet expects 1 or 2 arguments: httpGet(url, [headers])"} } urlObj, ok := args[0].(*object.String) if !ok { if instance, ok := args[0].(*object.Instance); ok { if value, ok := instance.Env.Get("value"); ok { if str, ok := value.(*object.String); ok { urlObj = str } else { return &object.Error{Message: "httpGet expects URL as string"} } } else { return &object.Error{Message: "httpGet expects URL as string"} } } else { return &object.Error{Message: "httpGet expects URL as string"} } } client := &http.Client{ Timeout: 30 * time.Second, } req, err := http.NewRequest("GET", urlObj.Value, nil) if err != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", err)} } if len(args) == 2 { if err := setHeaders(req, args[1]); err != nil { return err } } resp, err := client.Do(req) if err != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", err)} } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return &object.Error{Message: fmt.Sprintf("Failed to read response: %v", err)} } result := &object.Hash{ Pairs: make(map[object.HashKey]object.HashPair), } statusKey := &object.String{Value: "status"} result.Pairs[statusKey.HashKey()] = object.HashPair{ Key: statusKey, Value: &object.Integer{Value: int64(resp.StatusCode)}, } bodyKey := &object.String{Value: "body"} result.Pairs[bodyKey.HashKey()] = object.HashPair{ Key: bodyKey, Value: &object.String{Value: string(body)}, } headersKey := &object.String{Value: "headers"} result.Pairs[headersKey.HashKey()] = object.HashPair{ Key: headersKey, Value: headersToHash(resp.Header), } return result }, }, "httpPost": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 || len(args) > 3 { return &object.Error{Message: "httpPost expects 2 or 3 arguments: httpPost(url, body, [headers])"} } urlObj, err := extractString(args[0], "URL") if err != nil { return err } bodyStr, err := extractString(args[1], "body") if err != nil { return err } client := &http.Client{ Timeout: 30 * time.Second, } req, reqErr := http.NewRequest("POST", urlObj, strings.NewReader(bodyStr)) if reqErr != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", reqErr)} } req.Header.Set("Content-Type", "application/json") if len(args) == 3 { if err := setHeaders(req, args[2]); err != nil { return err } } resp, respErr := client.Do(req) if respErr != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", respErr)} } defer resp.Body.Close() return buildResponse(resp) }, }, "httpPut": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 || len(args) > 3 { return &object.Error{Message: "httpPut expects 2 or 3 arguments: httpPut(url, body, [headers])"} } urlObj, err := extractString(args[0], "URL") if err != nil { return err } bodyStr, err := extractString(args[1], "body") if err != nil { return err } client := &http.Client{ Timeout: 30 * time.Second, } req, reqErr := http.NewRequest("PUT", urlObj, strings.NewReader(bodyStr)) if reqErr != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", reqErr)} } req.Header.Set("Content-Type", "application/json") if len(args) == 3 { if err := setHeaders(req, args[2]); err != nil { return err } } resp, respErr := client.Do(req) if respErr != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", respErr)} } defer resp.Body.Close() return buildResponse(resp) }, }, "httpDelete": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "httpDelete expects 1 or 2 arguments: httpDelete(url, [headers])"} } urlObj, err := extractString(args[0], "URL") if err != nil { return err } client := &http.Client{ Timeout: 30 * time.Second, } req, reqErr := http.NewRequest("DELETE", urlObj, nil) if reqErr != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", reqErr)} } if len(args) == 2 { if err := setHeaders(req, args[1]); err != nil { return err } } resp, respErr := client.Do(req) if respErr != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", respErr)} } defer resp.Body.Close() return buildResponse(resp) }, }, "httpHead": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "httpHead expects 1 or 2 arguments: httpHead(url, [headers])"} } urlObj, err := extractString(args[0], "URL") if err != nil { return err } client := &http.Client{ Timeout: 30 * time.Second, } req, reqErr := http.NewRequest("HEAD", urlObj, nil) if reqErr != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", reqErr)} } if len(args) == 2 { if err := setHeaders(req, args[1]); err != nil { return err } } resp, respErr := client.Do(req) if respErr != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", respErr)} } defer resp.Body.Close() result := &object.Hash{ Pairs: make(map[object.HashKey]object.HashPair), } statusKey := &object.String{Value: "status"} result.Pairs[statusKey.HashKey()] = object.HashPair{ Key: statusKey, Value: &object.Integer{Value: int64(resp.StatusCode)}, } headersKey := &object.String{Value: "headers"} result.Pairs[headersKey.HashKey()] = object.HashPair{ Key: headersKey, Value: headersToHash(resp.Header), } return result }, }, "httpRequest": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "httpRequest expects 1 argument: httpRequest(options)"} } options, ok := args[0].(*object.Hash) if !ok { return &object.Error{Message: "httpRequest expects options as hash"} } method, err := getHashString(options, "method") if err != nil { method = "GET" } url, err := getHashString(options, "url") if err != nil { return &object.Error{Message: "httpRequest requires 'url' in options"} } var bodyReader io.Reader if body, err := getHashString(options, "body"); err == nil { bodyReader = strings.NewReader(body) } timeout := 30 if timeoutVal, err := getHashInt(options, "timeout"); err == nil { timeout = int(timeoutVal) } client := &http.Client{ Timeout: time.Duration(timeout) * time.Second, } req, reqErr := http.NewRequest(method, url, bodyReader) if reqErr != nil { return &object.Error{Message: fmt.Sprintf("Failed to create request: %v", reqErr)} } if headers, err := getHashValue(options, "headers"); err == nil { if err := setHeaders(req, headers); err != nil { return err } } resp, respErr := client.Do(req) if respErr != nil { return &object.Error{Message: fmt.Sprintf("Request failed: %v", respErr)} } defer resp.Body.Close() return buildResponse(resp) }, }, "httpParseJSON": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "httpParseJSON expects 1 argument: httpParseJSON(jsonString)"} } jsonStr, err := extractString(args[0], "JSON string") if err != nil { return err } var result interface{} if err := json.Unmarshal([]byte(jsonStr), &result); err != nil { return &object.Error{Message: fmt.Sprintf("Failed to parse JSON: %v", err)} } return jsonToObject(result) }, }, "httpStringifyJSON": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "httpStringifyJSON expects 1 argument: httpStringifyJSON(object)"} } data := objectToInterface(args[0]) jsonBytes, err := json.Marshal(data) if err != nil { return &object.Error{Message: fmt.Sprintf("Failed to stringify JSON: %v", err)} } return &object.String{Value: string(jsonBytes)} }, }, "httpBuildQuery": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "httpBuildQuery expects 1 argument: httpBuildQuery(params)"} } params, ok := args[0].(*object.Hash) if !ok { return &object.Error{Message: "httpBuildQuery expects params as hash"} } var queryParts []string for _, pair := range params.Pairs { key := pair.Key.Inspect() value := pair.Value.Inspect() queryParts = append(queryParts, fmt.Sprintf("%s=%s", key, value)) } return &object.String{Value: strings.Join(queryParts, "&")} }, }, "http_parse_request": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "http_parse_request requires 1 argument: request_data"} } requestData, err := extractString(args[0], "request_data") if err != nil { return err } return parseHTTPRequest(requestData) }, }, "http_response": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 || len(args) > 3 { return &object.Error{Message: "http_response requires 2-3 arguments: status_code, body, [headers]"} } statusCode, ok := args[0].(*object.Integer) if !ok { return &object.Error{Message: "http_response: status_code must be an integer"} } body, err := extractString(args[1], "body") if err != nil { return err } headers := make(map[string]string) if len(args) == 3 { if headerHash, ok := args[2].(*object.Hash); ok { for _, pair := range headerHash.Pairs { key := pair.Key.Inspect() value := pair.Value.Inspect() headers[key] = value } } } return buildHTTPResponse(int(statusCode.Value), body, headers) }, }, "serve_static_file": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "serve_static_file requires 1 argument: file_path"} } filePath, err := extractString(args[0], "file_path") if err != nil { return err } return serveStaticFile(filePath) }, }, "list_directory": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "list_directory requires 1 argument: directory_path"} } dirPath, err := extractString(args[0], "directory_path") if err != nil { return err } return listDirectory(dirPath) }, }, }
View Source
var OSBuiltins = map[string]*object.Builtin{ "osRunCommand": { Fn: func(args ...object.Object) object.Object { var command string var cmdArgs []string var capture bool if len(args) < 1 { return &object.Error{Message: "osRunCommand requires at least 1 argument (command)"} } command, ok := extractStringOS(args[0]) if !ok { errMsg := "osRunCommand command must be a STRING, got=" + string(args[0].Type()) if inst, isInst := args[0].(*object.Instance); isInst { if inst.Grimoire != nil { errMsg += " (grimoire: " + inst.Grimoire.Name + ")" } errMsg += " with inspect: " + args[0].Inspect() } return &object.Error{Message: errMsg} } if len(args) > 1 { arrArg, isArr := args[1].(*object.Array) if isArr { for _, elem := range arrArg.Elements { elemStr, ok := extractStringOS(elem) if !ok { return &object.Error{Message: "osRunCommand arg array must contain only STRINGs"} } cmdArgs = append(cmdArgs, elemStr) } } } if len(args) > 2 { capture, ok = extractBoolOS(args[2]) if !ok { return &object.Error{Message: "osRunCommand third arg must be BOOLEAN for captureOutput"} } } cmd := exec.Command(command, cmdArgs...) var outputBytes []byte var err error if capture { outputBytes, err = cmd.CombinedOutput() } else { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() } if err != nil { return &object.Error{Message: "error running command '" + command + "': " + err.Error()} } if capture { return &object.String{Value: string(outputBytes)} } return &object.None{} }, }, "osGetEnv": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "osGetEnv requires 1 argument: key"} } keyStr, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osGetEnv argument must be STRING, got=" + string(args[0].Type())} } val := os.Getenv(keyStr) return &object.String{Value: val} }, }, "osSetEnv": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "osSetEnv requires 2 arguments: key, value"} } key, okKey := extractStringOS(args[0]) val, okVal := extractStringOS(args[1]) if !okKey || !okVal { return &object.Error{Message: "osSetEnv arguments must be STRINGS, got types: " + string(args[0].Type()) + " and " + string(args[1].Type())} } err := os.Setenv(key, val) if err != nil { return &object.Error{Message: "failed to set env var: " + err.Error()} } return &object.None{} }, }, "osGetCwd": { Fn: func(args ...object.Object) object.Object { if len(args) != 0 { return &object.Error{Message: "osGetCwd takes no arguments"} } dir, err := os.Getwd() if err != nil { return &object.Error{Message: "failed to get current directory: " + err.Error()} } return &object.String{Value: dir} }, }, "osChdir": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "osChdir requires 1 argument: directory path"} } dirPath, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osChdir argument must be STRING"} } err := os.Chdir(dirPath) if err != nil { return &object.Error{Message: "failed to chdir to '" + dirPath + "': " + err.Error()} } return &object.None{} }, }, "osSleep": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "osSleep requires 1 argument: seconds (INT or FLOAT)"} } if intVal, ok := extractIntOS(args[0]); ok { time.Sleep(time.Duration(intVal) * time.Second) } else if floatVal, ok := extractFloatOS(args[0]); ok { nanos := int64(floatVal * 1_000_000_000) time.Sleep(time.Duration(nanos)) } else { return &object.Error{Message: "osSleep argument must be INTEGER or FLOAT, got " + string(args[0].Type())} } return &object.None{} }, }, "osListDir": { Fn: func(args ...object.Object) object.Object { var dir string if len(args) == 0 { dir = "." } else if len(args) == 1 { dirStr, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osListDir argument must be STRING, got=" + string(args[0].Type()) + " with value: " + args[0].Inspect()} } dir = dirStr } else { return &object.Error{Message: "osListDir requires 0 or 1 arguments"} } entries, err := os.ReadDir(dir) if err != nil { return &object.Error{Message: "failed to read directory '" + dir + "': " + err.Error()} } var results []object.Object for _, e := range entries { results = append(results, &object.String{Value: e.Name()}) } return &object.Array{Elements: results} }, }, "osRemove": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "osRemove requires 1 argument: path"} } pathStr, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osRemove argument must be STRING"} } err := os.Remove(pathStr) if err != nil { return &object.Error{Message: "failed to remove '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, "osMkdir": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "osMkdir requires 1 or 2 arguments: path, [perm int]"} } pathStr, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osMkdir path must be STRING, got=" + string(args[0].Type())} } perm := os.FileMode(0755) if len(args) == 2 { permVal, ok := extractIntOS(args[1]) if !ok { return &object.Error{Message: "osMkdir second arg must be an INTEGER for permissions"} } perm = os.FileMode(permVal) } err := os.Mkdir(pathStr, perm) if err != nil { return &object.Error{Message: "failed to create directory '" + pathStr + "': " + err.Error()} } return &object.None{} }, }, "osExpandEnv": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "osExpandEnv requires 1 argument: string"} } strArg, ok := extractStringOS(args[0]) if !ok { return &object.Error{Message: "osExpandEnv argument must be STRING, got " + string(args[0].Type())} } expanded := os.ExpandEnv(strArg) return &object.String{Value: expanded} }, }, }
View Source
var SocketsModule = map[string]*object.Builtin{ "new_socket": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 { return &object.Error{Message: "new_socket requires at least 1 argument: type, [protocol], [port/address], [timeout]"} } socketType, ok := extractSocketString(args[0]) if !ok { return &object.Error{Message: "new_socket: type must be a string"} } protocol := "tcp" if len(args) > 1 { if p, ok := extractSocketString(args[1]); ok { protocol = p } } address := "localhost:8080" if len(args) > 2 { if addr, ok := extractSocketString(args[2]); ok { address = addr } } timeout := 30 * time.Second if len(args) > 3 { if t, ok := extractSocketInt(args[3]); ok { if t < 0 { timeout = 30 * time.Second } else { timeout = time.Duration(t) * time.Second } } } switch strings.ToLower(socketType) { case "tcp": return createTCPSocket(protocol, address, timeout) case "udp": return createUDPSocket(address, timeout) case "web", "http": return createWebSocket(address, timeout) case "unix": return createUnixSocket(address, timeout) default: return &object.Error{Message: fmt.Sprintf("unsupported socket type: %s", socketType)} } }, }, "client": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 { return &object.Error{Message: "client requires at least 2 arguments: type, address, [timeout]"} } socketType, ok := extractSocketString(args[0]) if !ok { return &object.Error{Message: "client: type must be a string"} } address, ok := extractSocketString(args[1]) if !ok { return &object.Error{Message: "client: address must be a string"} } timeout := 30 * time.Second if len(args) > 2 { if t, ok := extractSocketInt(args[2]); ok { timeout = time.Duration(t) * time.Second } } switch strings.ToLower(socketType) { case "tcp": return connectTCPClient(address, timeout) case "udp": return connectUDPClient(address, timeout) case "unix": return connectUnixClient(address, timeout) default: return &object.Error{Message: fmt.Sprintf("unsupported client type: %s", socketType)} } }, }, "server": { Fn: func(args ...object.Object) object.Object { if len(args) < 2 { return &object.Error{Message: "server requires at least 2 arguments: type, port/address, [timeout]"} } socketType, ok := extractSocketString(args[0]) if !ok { return &object.Error{Message: "server: type must be a string"} } address, ok := extractSocketString(args[1]) if !ok { return &object.Error{Message: "server: address must be a string"} } timeout := 30 * time.Second if len(args) > 2 { if t, ok := extractSocketInt(args[2]); ok { timeout = time.Duration(t) * time.Second } } switch strings.ToLower(socketType) { case "tcp": return startTCPServer(address, timeout) case "udp": return startUDPServer(address, timeout) case "web", "http": return startWebServer(address, timeout) case "unix": return startUnixServer(address, timeout) default: return &object.Error{Message: fmt.Sprintf("unsupported server type: %s", socketType)} } }, }, "socket_send": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "socket_send requires 2 arguments: handleID, data"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_send: handleID must be an integer"} } data, ok := extractSocketString(args[1]) if !ok { return &object.Error{Message: "socket_send: data must be a string"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_send: invalid socket handle"} } return sendData(socket, data) }, }, "socket_receive": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "socket_receive requires 1-2 arguments: handleID, [bufferSize]"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_receive: handleID must be an integer"} } bufferSize := int64(1024) if len(args) > 1 { if size, ok := extractSocketInt(args[1]); ok { bufferSize = size } } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_receive: invalid socket handle"} } return receiveData(socket, bufferSize) }, }, "socket_close": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "socket_close requires 1 argument: handleID"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_close: handleID must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_close: invalid socket handle"} } err := closeSocket(socket) removeSocketHandle(handleID) if err != nil { return &object.Error{Message: fmt.Sprintf("failed to close socket: %v", err)} } return &object.None{} }, }, "socket_listen": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "socket_listen requires 1 argument: handleID"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_listen: handleID must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_listen: invalid socket handle"} } return listenForConnections(socket) }, }, "socket_accept": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "socket_accept requires 1 argument: handleID"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_accept: handleID must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_accept: invalid socket handle"} } return acceptConnection(socket) }, }, "socket_set_timeout": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "socket_set_timeout requires 2 arguments: handleID, timeoutSeconds"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_set_timeout: handleID must be an integer"} } timeoutSecs, ok := extractSocketInt(args[1]) if !ok { return &object.Error{Message: "socket_set_timeout: timeoutSeconds must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_set_timeout: invalid socket handle"} } return setSocketTimeout(socket, time.Duration(timeoutSecs)*time.Second) }, }, "socket_get_info": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "socket_get_info requires 1 argument: handleID"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_get_info: handleID must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_get_info: invalid socket handle"} } return getSocketInfo(socket) }, }, "socket_send_to": { Fn: func(args ...object.Object) object.Object { if len(args) != 3 { return &object.Error{Message: "socket_send_to requires 3 arguments: handleID, data, targetAddress"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_send_to: handleID must be an integer"} } data, ok := extractSocketString(args[1]) if !ok { return &object.Error{Message: "socket_send_to: data must be a string"} } targetAddress, ok := extractSocketString(args[2]) if !ok { return &object.Error{Message: "socket_send_to: targetAddress must be a string"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_send_to: invalid socket handle"} } return sendDataTo(socket, data, targetAddress) }, }, "socket_receive_from": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "socket_receive_from requires 2 arguments: handleID, bufferSize"} } handleID, ok := extractSocketInt(args[0]) if !ok { return &object.Error{Message: "socket_receive_from: handleID must be an integer"} } bufferSize, ok := extractSocketInt(args[1]) if !ok { return &object.Error{Message: "socket_receive_from: bufferSize must be an integer"} } socket, exists := getSocketHandle(handleID) if !exists { return &object.Error{Message: "socket_receive_from: invalid socket handle"} } return receiveDataFrom(socket, bufferSize) }, }, }
View Source
var TimeModule = map[string]*object.Builtin{ "now": { Fn: func(args ...object.Object) object.Object { if len(args) != 0 { return &object.Error{Message: "now() takes no arguments"} } return &object.Time{Value: time.Now()} }, }, "timeNow": { Fn: func(args ...object.Object) object.Object { if len(args) != 0 { return &object.Error{Message: "timeNow takes no arguments"} } return &object.Integer{Value: time.Now().Unix()} }, }, "timeNowNano": { Fn: func(args ...object.Object) object.Object { if len(args) != 0 { return &object.Error{Message: "timeNowNano takes no arguments"} } return &object.Integer{Value: time.Now().UnixNano()} }, }, "timeSleep": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "timeSleep requires 1 argument: seconds (INT or FLOAT)"} } if intVal, ok := getIntegerValue(args[0]); ok { if intVal < 0 { return &object.Error{Message: "timeSleep duration cannot be negative"} } time.Sleep(time.Duration(intVal) * time.Second) return &object.None{} } if floatVal, ok := getFloatValue(args[0]); ok { if floatVal < 0 { return &object.Error{Message: "timeSleep duration cannot be negative"} } nanos := int64(floatVal * 1_000_000_000) time.Sleep(time.Duration(nanos)) return &object.None{} } if durVal, ok := args[0].(*object.Duration); ok { if durVal.Value < 0 { return &object.Error{Message: "timeSleep duration cannot be negative"} } time.Sleep(durVal.Value) return &object.None{} } return &object.Error{Message: "timeSleep argument must be INTEGER, FLOAT, or DURATION, got " + string(args[0].Type())} }, }, "parseTime": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 && len(args) != 2 { return &object.Error{Message: "parseTime() takes 1 or 2 arguments (timeString, [format])"} } timeStr, ok := args[0].(*object.String) if !ok { return &object.Error{Message: "First argument must be a STRING"} } format := time.RFC3339 if len(args) == 2 { formatStr, ok := args[1].(*object.String) if !ok { return &object.Error{Message: "Second argument must be a STRING"} } format = formatStr.Value } parsedTime, err := time.Parse(format, timeStr.Value) if err != nil { return &object.Error{Message: fmt.Sprintf("Failed to parse time: %s", err)} } return &object.Time{Value: parsedTime} }, }, "timeParse": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeParse requires 2 arguments: format, timeString"} } format, ok1 := args[0].(*object.String) timeStr, ok2 := args[1].(*object.String) if !ok1 || !ok2 { return &object.Error{Message: "timeParse arguments must be STRINGs"} } t, err := time.Parse(format.Value, timeStr.Value) if err != nil { return &object.Error{Message: "timeParse failed: " + err.Error()} } return &object.Integer{Value: t.Unix()} }, }, "formatTime": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "formatTime() requires exactly 2 arguments"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } formatStr, ok := args[1].(*object.String) if !ok { return &object.Error{Message: "Second argument must be a STRING"} } formatted := timeObj.Value.Format(formatStr.Value) return &object.String{Value: formatted} }, }, "timeFormat": { Fn: func(args ...object.Object) object.Object { if len(args) < 1 || len(args) > 2 { return &object.Error{Message: "timeFormat requires 1 or 2 arguments: timestamp, [format]"} } timestamp, ok := getIntegerValue(args[0]) if !ok { return &object.Error{Message: "timeFormat first argument must be INTEGER timestamp"} } format := "2006-01-02 15:04:05" if len(args) == 2 { formatArg, ok := args[1].(*object.String) if !ok { return &object.Error{Message: "timeFormat second argument must be STRING format"} } format = formatArg.Value } t := time.Unix(timestamp, 0) formatted := t.Format(format) return &object.String{Value: formatted} }, }, "timeSince": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "timeSince() requires exactly 1 argument"} } if t, ok := args[0].(*object.Time); ok { elapsed := time.Since(t.Value) return &object.Duration{Value: elapsed} } if timestamp, ok := getIntegerValue(args[0]); ok { elapsed := time.Since(time.Unix(timestamp, 0)) return &object.Duration{Value: elapsed} } return &object.Error{Message: "Argument must be of type TIME or INTEGER (Unix timestamp)"} }, }, "timeUntil": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "timeUntil() requires exactly 1 argument"} } if t, ok := args[0].(*object.Time); ok { until := time.Until(t.Value) return &object.Duration{Value: until} } if timestamp, ok := getIntegerValue(args[0]); ok { until := time.Until(time.Unix(timestamp, 0)) return &object.Duration{Value: until} } return &object.Error{Message: "Argument must be of type TIME or INTEGER (Unix timestamp)"} }, }, "addDuration": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "addDuration() requires exactly 2 arguments"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } durObj, ok := args[1].(*object.Duration) if !ok { return &object.Error{Message: "Second argument must be of type DURATION"} } newTime := timeObj.Value.Add(durObj.Value) return &object.Time{Value: newTime} }, }, "timeAddDuration": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeAddDuration requires 2 arguments: timestamp, seconds"} } timestamp, ok1 := getIntegerValue(args[0]) duration, ok2 := getIntegerValue(args[1]) if !ok1 || !ok2 { return &object.Error{Message: "timeAddDuration arguments must be INTEGERs"} } t := time.Unix(timestamp, 0) newTime := t.Add(time.Duration(duration) * time.Second) return &object.Integer{Value: newTime.Unix()} }, }, "timeDiff": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeDiff requires 2 arguments"} } if t1, ok1 := args[0].(*object.Time); ok1 { if t2, ok2 := args[1].(*object.Time); ok2 { diff := t1.Value.Sub(t2.Value) return &object.Duration{Value: diff} } return &object.Error{Message: "Both arguments must be of the same type"} } if val1, ok1 := getIntegerValue(args[0]); ok1 { if val2, ok2 := getIntegerValue(args[1]); ok2 { diff := val1 - val2 return &object.Integer{Value: diff} } return &object.Error{Message: "Both arguments must be of the same type"} } return &object.Error{Message: "Arguments must be INTEGERs or TIMEs"} }, }, "timeDate": { Fn: func(args ...object.Object) object.Object { var t time.Time if len(args) == 0 { t = time.Now() } else if len(args) == 1 { if timeObj, ok := args[0].(*object.Time); ok { t = timeObj.Value } else if intVal, ok := getIntegerValue(args[0]); ok { t = time.Unix(intVal, 0) } else { return &object.Error{Message: "timeDate argument must be INTEGER timestamp or TIME"} } } else { return &object.Error{Message: "timeDate requires 0 or 1 arguments"} } year, month, day := t.Date() elements := []object.Object{ &object.Integer{Value: int64(year)}, &object.Integer{Value: int64(month)}, &object.Integer{Value: int64(day)}, } return &object.Array{Elements: elements} }, }, "seconds": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "seconds() requires exactly 1 argument"} } if intVal, ok := getIntegerValue(args[0]); ok { return &object.Duration{Value: time.Duration(intVal) * time.Second} } if floatVal, ok := getFloatValue(args[0]); ok { nanos := int64(floatVal * float64(time.Second)) return &object.Duration{Value: time.Duration(nanos)} } return &object.Error{Message: "Argument must be an INTEGER or FLOAT"} }, }, "minutes": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "minutes() requires exactly 1 argument"} } if intVal, ok := getIntegerValue(args[0]); ok { return &object.Duration{Value: time.Duration(intVal) * time.Minute} } if floatVal, ok := getFloatValue(args[0]); ok { nanos := int64(floatVal * float64(time.Minute)) return &object.Duration{Value: time.Duration(nanos)} } return &object.Error{Message: "Argument must be an INTEGER or FLOAT"} }, }, "hours": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "hours() requires exactly 1 argument"} } if intVal, ok := getIntegerValue(args[0]); ok { return &object.Duration{Value: time.Duration(intVal) * time.Hour} } if floatVal, ok := getFloatValue(args[0]); ok { nanos := int64(floatVal * float64(time.Hour)) return &object.Duration{Value: time.Duration(nanos)} } return &object.Error{Message: "Argument must be an INTEGER or FLOAT"} }, }, "milliseconds": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "milliseconds() requires exactly 1 argument"} } if intVal, ok := getIntegerValue(args[0]); ok { return &object.Duration{Value: time.Duration(intVal) * time.Millisecond} } if floatVal, ok := getFloatValue(args[0]); ok { nanos := int64(floatVal * float64(time.Millisecond)) return &object.Duration{Value: time.Duration(nanos)} } return &object.Error{Message: "Argument must be an INTEGER or FLOAT"} }, }, "durationToSeconds": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "durationToSeconds() requires exactly 1 argument"} } durObj, ok := args[0].(*object.Duration) if !ok { return &object.Error{Message: "Argument must be of type DURATION"} } return &object.Float{Value: durObj.Value.Seconds()} }, }, "durationToMinutes": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "durationToMinutes() requires exactly 1 argument"} } durObj, ok := args[0].(*object.Duration) if !ok { return &object.Error{Message: "Argument must be of type DURATION"} } return &object.Float{Value: durObj.Value.Minutes()} }, }, "durationToHours": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "durationToHours() requires exactly 1 argument"} } durObj, ok := args[0].(*object.Duration) if !ok { return &object.Error{Message: "Argument must be of type DURATION"} } return &object.Float{Value: durObj.Value.Hours()} }, }, "durationToMilliseconds": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "durationToMilliseconds() requires exactly 1 argument"} } durObj, ok := args[0].(*object.Duration) if !ok { return &object.Error{Message: "Argument must be of type DURATION"} } return &object.Integer{Value: durObj.Value.Milliseconds()} }, }, "timeBefore": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeBefore() requires exactly 2 arguments"} } time1, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } time2, ok := args[1].(*object.Time) if !ok { return &object.Error{Message: "Second argument must be of type TIME"} } return &object.Boolean{Value: time1.Value.Before(time2.Value)} }, }, "timeAfter": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeAfter() requires exactly 2 arguments"} } time1, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } time2, ok := args[1].(*object.Time) if !ok { return &object.Error{Message: "Second argument must be of type TIME"} } return &object.Boolean{Value: time1.Value.After(time2.Value)} }, }, "timeEqual": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "timeEqual() requires exactly 2 arguments"} } time1, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } time2, ok := args[1].(*object.Time) if !ok { return &object.Error{Message: "Second argument must be of type TIME"} } return &object.Boolean{Value: time1.Value.Equal(time2.Value)} }, }, "year": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "year() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Year())} }, }, "month": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "month() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Month())} }, }, "day": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "day() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Day())} }, }, "weekday": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "weekday() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Weekday())} }, }, "hour": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "hour() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Hour())} }, }, "minute": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "minute() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Minute())} }, }, "second": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "second() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: int64(timeObj.Value.Second())} }, }, "unix": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "unix() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: timeObj.Value.Unix()} }, }, "unixNano": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "unixNano() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Integer{Value: timeObj.Value.UnixNano()} }, }, "fromUnix": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fromUnix() requires exactly 1 argument"} } timestamp, ok := getIntegerValue(args[0]) if !ok { return &object.Error{Message: "Argument must be an INTEGER"} } return &object.Time{Value: time.Unix(timestamp, 0)} }, }, "fromUnixNano": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "fromUnixNano() requires exactly 1 argument"} } timestamp, ok := getIntegerValue(args[0]) if !ok { return &object.Error{Message: "Argument must be an INTEGER"} } return &object.Time{Value: time.Unix(0, timestamp)} }, }, "inLocation": { Fn: func(args ...object.Object) object.Object { if len(args) != 2 { return &object.Error{Message: "inLocation() requires exactly 2 arguments"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "First argument must be of type TIME"} } locStr, ok := args[1].(*object.String) if !ok { return &object.Error{Message: "Second argument must be a STRING"} } loc, err := time.LoadLocation(locStr.Value) if err != nil { return &object.Error{Message: fmt.Sprintf("Failed to load location: %s", err)} } return &object.Time{Value: timeObj.Value.In(loc)} }, }, "utc": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "utc() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Time{Value: timeObj.Value.UTC()} }, }, "local": { Fn: func(args ...object.Object) object.Object { if len(args) != 1 { return &object.Error{Message: "local() requires exactly 1 argument"} } timeObj, ok := args[0].(*object.Time) if !ok { return &object.Error{Message: "Argument must be of type TIME"} } return &object.Time{Value: timeObj.Value.Local()} }, }, }
Functions ¶
This section is empty.
Types ¶
type TCPListener ¶ added in v0.1.8
type UnixSocket ¶ added in v0.1.8
Click to show internal directories.
Click to hide internal directories.