Documentation
¶
Overview ¶
moved to evaldo/builtins_error_handling.go
builtins.go
builtins.go
builtins_trees.go
Index ¶
- Constants
- Variables
- func ArrayFloat32FromSeries(block env.TSeries) []float32
- func BlockToJSON(block env.Block) string
- func BlockToJSONWithIdxs(block env.Block, idxs *env.Idxs) string
- func BsonToValue_Map(ps *env.ProgramState, val any, typ string, meta any, topLevel bool) env.Object
- func BsonToValue_Val(ps *env.ProgramState, val any, topLevel bool) env.Object
- func BuiConvert(ps *env.ProgramState, arg0 env.Object, arg1 env.Object) env.Object
- func BuiParseArgs(es *env.ProgramState, args env.Object, specBlock env.Object) env.Object
- func BuiParseArgsFull(es *env.ProgramState, args env.Object, specBlock env.Object) env.Object
- func ContextToJSON(ctx *env.RyeCtx, idxs *env.Idxs) string
- func Conversion_EvalBlockCtx(ps *env.ProgramState, vals *env.RyeCtx) env.Object
- func Conversion_EvalBlockDict(ps *env.ProgramState, vals env.Dict) env.Object
- func CopyMap(m map[string]any) map[string]any
- func DialectMath(env1 *env.ProgramState, arg0 env.Object) env.Object
- func DictToJSON(dict env.Dict) string
- func DictToJSONWithIdxs(dict env.Dict, idxs *env.Idxs) string
- func EmptyRM() env.Dict
- func EscapeJson(val string) string
- func EvalBlockInPersistentCtx(ps *env.ProgramState, pctx *PersistentCtx)
- func Eyr_CallBuiltin(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object, toLeft bool) *env.ProgramState
- func Eyr_CallBuiltinPipe(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object) *env.ProgramState
- func Eyr_CallFunction(fn env.Function, es *env.ProgramState, leftVal env.Object, toLeft bool, ...) *env.ProgramState
- func Eyr_EvalBlock(ps *env.ProgramState, full bool) *env.ProgramState
- func Eyr_EvalBlockInside(ps *env.ProgramState, inj env.Object, injnow bool) *env.ProgramState
- func Eyr_EvalExpression(ps *env.ProgramState) *env.ProgramState
- func Eyr_EvalLSetword(ps *env.ProgramState, word env.LSetword, leftVal env.Object, toLeft bool) *env.ProgramState
- func Eyr_EvalObject(es *env.ProgramState, object env.Object, leftVal env.Object, pipeWord bool, ...) *env.ProgramState
- func Eyr_EvalWord(ps *env.ProgramState, word env.Object, leftVal env.Object, pipeWord bool) *env.ProgramState
- func ListToJSON(list env.List) string
- func ListToJSONWithIdxs(list env.List, idxs *env.Idxs) string
- func Math_EvalBlock(es *env.ProgramState) []env.Object
- func RegisterBatteries(ps *env.ProgramState)
- func RyeToJSON(res any) string
- func RyeToJSONLines(res any) string
- func RyeToJSONWithIdxs(res any, idxs *env.Idxs) string
- func SQL_EvalBlock(es *env.ProgramState, mode int, values []any) (*env.ProgramState, []any)
- func SQL_EvalExpression(es *env.ProgramState, vals []any, mode int) (*env.ProgramState, string, []any)
- func Stck_CallBuiltin(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object, toLeft bool) *env.ProgramState
- func Stck_EvalBlock(ps *env.ProgramState) *env.ProgramState
- func Stck_EvalExpression(ps *env.ProgramState) *env.ProgramState
- func Stck_EvalObject(ps *env.ProgramState, object env.Object, leftVal env.Object, toLeft bool, ...) *env.ProgramState
- func Stck_EvalWord(ps *env.ProgramState, word env.Object, leftVal env.Object, toLeft bool) *env.ProgramState
- func TableRowToJSON(row env.TableRow) string
- func TableRowToJSONWithIdxs(row env.TableRow, idxs *env.Idxs) string
- func TableToJSON(s env.Table) string
- func TableToJSONLines(s env.Table) string
- func TableToJSONWithIdxs(s env.Table, idxs *env.Idxs) string
- func TelegramUpdateToRyeDict(update_ tgm.Update) env.Dict
- func TruncateToWidth(s string, width int, ellipsis string) string
- func ValueToBSON(arg0 env.Object, topLevel bool) any
- func VectorToJSON(vector env.Vector) string
- func VectorToJSONWithIdxs(vector env.Vector, idxs *env.Idxs) string
- func VisibleWidth(s string) int
- func WrapText(s string, width int) []string
- type ArgSpec
- type CLISpec
- type ConversionError
- type HtmlDialectNode
- type HtmlNavigCondition
- type MessageDispatcher
- func (md *MessageDispatcher) GetState() env.Dict
- func (md *MessageDispatcher) RegisterHandler(msgType string, handler env.Function)
- func (md *MessageDispatcher) Send(msg env.Object) error
- func (md *MessageDispatcher) SetState(state env.Dict)
- func (md *MessageDispatcher) Start(ps *env.ProgramState, updateCallback env.Function)
- func (md *MessageDispatcher) Stop()
- func (md *MessageDispatcher) UnregisterHandler(msgType string)
- type ParsedArgs
- type PersistentCtx
- func (pc *PersistentCtx) AsRyeCtx() *env.RyeCtx
- func (pc *PersistentCtx) Copy() env.Context
- func (pc *PersistentCtx) Get(word int) (env.Object, bool)
- func (pc *PersistentCtx) GetDoc() string
- func (pc *PersistentCtx) GetKindWord() env.Word
- func (pc *PersistentCtx) GetParent() env.Context
- func (pc *PersistentCtx) IsVariable(word int) bool
- func (pc *PersistentCtx) MarkAsVariable(word int)
- func (pc *PersistentCtx) Mod(word int, val env.Object) bool
- func (pc *PersistentCtx) Set(word int, val env.Object) env.Object
- func (pc *PersistentCtx) SetDoc(doc string)
- func (pc *PersistentCtx) SetKindWord(kind env.Word)
- func (pc *PersistentCtx) SetNew(word int, val env.Object, idxs *env.Idxs) bool
- func (pc *PersistentCtx) SetParent(parent env.Context)
- func (pc PersistentCtx) Type() env.Type
- func (pc *PersistentCtx) Unset(word int, idxs *env.Idxs) env.Object
- type PersistentCtxEvaluator
- type PersistentRyeCtx
- type RyeMutex
- type SubcommandSpec
- type TuiApp
- func (app *TuiApp) GetState() env.Dict
- func (app *TuiApp) IsRunning() bool
- func (app *TuiApp) OnKey(key string, handler env.Object)
- func (app *TuiApp) OnKeys(handler env.Object)
- func (app *TuiApp) Render()
- func (app *TuiApp) SetState(state env.Dict)
- func (app *TuiApp) SetView(view env.Object)
- func (app *TuiApp) Start(ps *env.ProgramState) error
- func (app *TuiApp) Stop()
- func (app *TuiApp) Update(updates env.Dict)
- func (app *TuiApp) Wait()
- type TuiInput
- func (inp *TuiInput) Dump(e env.Idxs) string
- func (inp *TuiInput) Equal(other env.Object) bool
- func (inp *TuiInput) GetKind() int
- func (inp *TuiInput) GetValue() string
- func (inp *TuiInput) HandleKey(key string, ps *env.ProgramState) bool
- func (inp *TuiInput) Inspect(idxs env.Idxs) string
- func (inp *TuiInput) Print(e env.Idxs) string
- func (inp *TuiInput) Render() env.Block
- func (inp *TuiInput) SetValue(val string)
- func (inp *TuiInput) Trace(msg string)
- func (inp *TuiInput) Type() env.Type
Constants ¶
const MODE_PSQL = 2 // Uses $1, $2, etc. placeholders
const MODE_SQLITE = 1 // Uses ? placeholders
SQL mode constants for different database parameter styles
const TYPE_CODE int = 2
const TYPE_SUBNODE int = 1
Variables ¶
var Builtins_auditd = map[string]*env.Builtin{ "parse-line": { Argsn: 1, Doc: "Parses a single auditd log line into a dict using go-libaudit auparse.", Fn: func(ps *env.ProgramState, arg0 env.Object, _ env.Object, _ env.Object, _ env.Object, _ env.Object) env.Object { switch s := arg0.(type) { case env.String: m := parseLineWithAuparse(s.Value) if m == nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "malformed auditd line", "auditd-parse-line") } return *env.NewDict(m) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "auditd-parse-line") } }, }, "parse-file": { Argsn: 1, Doc: "Parses all lines of an auditd log file into a block of dicts using go-libaudit auparse.", Fn: func(ps *env.ProgramState, arg0 env.Object, _ env.Object, _ env.Object, _ env.Object, _ env.Object) env.Object { switch u := arg0.(type) { case env.Uri: path := resolveAuditPath(ps.WorkingPath, u.GetPath()) f, err := os.Open(path) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "auditd-parse-file") } defer f.Close() scanner := bufio.NewScanner(f) var items []env.Object for scanner.Scan() { if m := parseLineWithAuparse(scanner.Text()); m != nil { items = append(items, *env.NewDict(m)) } } if err := scanner.Err(); err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "auditd-parse-file") } return *env.NewBlock(*env.NewTSeries(items)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "auditd-parse-file") } }, }, "tail-parse": { Argsn: 2, Doc: "Parses the last N lines of an auditd log file into a block of dicts using go-libaudit auparse.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, _ env.Object, _ env.Object, _ env.Object) env.Object { switch u := arg0.(type) { case env.Uri: path := resolveAuditPath(ps.WorkingPath, u.GetPath()) lim, ok := arg1.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "auditd-tail-parse") } lines, err := tailLastNLines(path, int(lim.Value)) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "auditd-tail-parse") } items := make([]env.Object, 0, len(lines)) for _, line := range lines { if m := parseLineWithAuparse(line); m != nil { items = append(items, *env.NewDict(m)) } } return *env.NewBlock(*env.NewTSeries(items)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "auditd-tail-parse") } }, }, }
export builtins (namespace: auditd)
var Builtins_bcrypt = map[string]*env.Builtin{ "bcrypt-hash": { Argsn: 1, Doc: "Generates a bcrypt hash from a password string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __bcrypt_hash(ps, arg0, arg1, arg2, arg3, arg4) }, }, "bcrypt-check": { Argsn: 2, Doc: "Compares a bcrypt hash with a plain text password.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __bcrypt_check(ps, arg0, arg1, arg2, arg3, arg4) }, }, "generate-token": { Argsn: 1, Doc: "Generates a cryptographically secure random token of the specified length in bytes.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __generate_token(ps, arg0, arg1, arg2, arg3, arg4) }, }, }
var Builtins_bson = map[string]*env.Builtin{ "from-bson": { Argsn: 1, Doc: "Decodes BSON data into Rye values.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var val map[string]any err := bson.Unmarshal(arg0.(env.Bytes).Value, &val) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "from-bson") } return BsonToValue_Map(ps, val["val"], val["typ"].(string), val["met"], true) }, }, "to-bson": { Argsn: 1, Doc: "Encodes a Rye value into BSON format.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { value := ValueToBSON(arg0, true) encoded, err := bson.Marshal(value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "to-bson") } return *env.NewBytes(encoded) }, }, }
var Builtins_chitosocket = map[string]*env.Builtin{ "chitosocket": { Argsn: 1, Doc: "Creates a new ChitoSocket WebSocket server with the specified number of CPU cores.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cores := arg0.(type) { case env.Integer: socket, err := chitosocket.StartUp(int(cores.Value)) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "chitosocket") } return *env.NewNative(ps.Idx, socket, "Chitosocket-server") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "chitosocket") } }, }, "Chitosocket-server//close": { Argsn: 1, Doc: "Closes the ChitoSocket server and releases resources.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: sock := server.Value.(*chitosocket.Socket) err := sock.Close() if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//close") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//close") } }, }, "Chitosocket-server//on": { Argsn: 3, Doc: "Registers an event handler for the specified event name. Handler receives subscriber and data as arguments.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch eventName := arg1.(type) { case env.String: switch handler := arg2.(type) { case env.Function: sock := server.Value.(*chitosocket.Socket) sock.On[eventName.Value] = func(sub *chitosocket.Subscriber, data []byte) { ps.FailureFlag = false ps.ErrorFlag = false ps.ReturnFlag = false subNative := *env.NewNative(ps.Idx, sub, "Chitosocket-subscriber") dataStr := *env.NewString(string(data)) evaldo.CallFunctionArgs2(handler, ps, subNative, dataStr, nil) } return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.FunctionType}, "Chitosocket-server//on") } case env.Word: switch handler := arg2.(type) { case env.Function: sock := server.Value.(*chitosocket.Socket) eventNameStr := ps.Idx.GetWord(eventName.Index) sock.On[eventNameStr] = func(sub *chitosocket.Subscriber, data []byte) { ps.FailureFlag = false ps.ErrorFlag = false ps.ReturnFlag = false subNative := *env.NewNative(ps.Idx, sub, "Chitosocket-subscriber") dataStr := *env.NewString(string(data)) evaldo.CallFunctionArgs2(handler, ps, subNative, dataStr, nil) } return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.FunctionType}, "Chitosocket-server//on") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType, env.WordType}, "Chitosocket-server//on") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//on") } }, }, "Chitosocket-server//upgrade-connection": { Argsn: 3, Doc: "Upgrades an HTTP connection to WebSocket. Returns a block with connection, response writer, and subscriber.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch req := arg1.(type) { case env.Native: switch w := arg2.(type) { case env.Native: sock := server.Value.(*chitosocket.Socket) httpReq, ok1 := req.Value.(*http.Request) httpWriter, ok2 := w.Value.(http.ResponseWriter) if !ok1 || !ok2 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Invalid HTTP request or response writer types", "Chitosocket-server//upgrade-connection") } conn, rw, sub, err := sock.UpgradeConnection(httpReq, httpWriter) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//upgrade-connection") } result := make([]env.Object, 3) result[0] = *env.NewNative(ps.Idx, conn, "Chitosocket-connection") result[1] = *env.NewNative(ps.Idx, rw, "Chitosocket-response-writer") result[2] = *env.NewNative(ps.Idx, sub, "Chitosocket-subscriber") return *env.NewBlock(*env.NewTSeries(result)) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.NativeType}, "Chitosocket-server//upgrade-connection") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-server//upgrade-connection") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//upgrade-connection") } }, }, "Chitosocket-server//emit-direct": { Argsn: 4, Doc: "Emits an event directly to a specific subscriber with the given data.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch sub := arg1.(type) { case env.Native: switch eventName := arg2.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) subscriber := sub.Value.(*chitosocket.Subscriber) var dataBytes []byte switch data := arg3.(type) { case env.String: dataBytes = []byte(data.Value) case env.Dict: jsonData, err := json.Marshal(data.Data) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//emit-direct") } dataBytes = jsonData default: dataBytes = []byte(arg3.Inspect(*ps.Idx)) } sock.EmitDirect(subscriber, eventName.Value, dataBytes) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "Chitosocket-server//emit-direct") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-server//emit-direct") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//emit-direct") } }, }, "Chitosocket-server//emit": { Argsn: 4, Doc: "Emits an event to all subscribers in a specific room (excluding none).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch eventName := arg1.(type) { case env.String: switch room := arg3.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) var dataBytes []byte switch data := arg2.(type) { case env.String: dataBytes = []byte(data.Value) case env.Dict: jsonData, err := json.Marshal(data.Data) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//emit") } dataBytes = jsonData default: dataBytes = []byte(arg2.Inspect(*ps.Idx)) } sock.Emit(eventName.Value, nil, dataBytes, room.Value) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 4, []env.Type{env.StringType}, "Chitosocket-server//emit") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Chitosocket-server//emit") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//emit") } }, }, "Chitosocket-server//broadcast": { Argsn: 3, Doc: "Broadcasts an event to all connected subscribers.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch eventName := arg1.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) var dataBytes []byte switch data := arg2.(type) { case env.String: dataBytes = []byte(data.Value) case env.Dict: jsonData, err := json.Marshal(data.Data) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//broadcast") } dataBytes = jsonData default: dataBytes = []byte(arg2.Inspect(*ps.Idx)) } sock.Broadcast(eventName.Value, dataBytes) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Chitosocket-server//broadcast") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//broadcast") } }, }, "Chitosocket-server//add-to-room": { Argsn: 3, Doc: "Adds a subscriber to a room.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch sub := arg1.(type) { case env.Native: switch room := arg2.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) subscriber := sub.Value.(*chitosocket.Subscriber) sock.AddToRoom(subscriber, room.Value) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "Chitosocket-server//add-to-room") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-server//add-to-room") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//add-to-room") } }, }, "Chitosocket-server//remove-from-room": { Argsn: 3, Doc: "Removes a subscriber from a room.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch sub := arg1.(type) { case env.Native: switch room := arg2.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) subscriber := sub.Value.(*chitosocket.Subscriber) sock.RemoveFromRoom(subscriber, room.Value) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "Chitosocket-server//remove-from-room") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-server//remove-from-room") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//remove-from-room") } }, }, "Chitosocket-server//room-count?": { Argsn: 2, Doc: "Returns the number of subscribers in a room.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch room := arg1.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) count := sock.GetRoomCount(room.Value) return *env.NewInteger(int64(count)) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Chitosocket-server//room-count?") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//room-count?") } }, }, "Chitosocket-subscriber//id?": { Argsn: 1, Doc: "Returns the unique ID of the subscriber.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sub := arg0.(type) { case env.Native: subscriber := sub.Value.(*chitosocket.Subscriber) return *env.NewString(subscriber.ID) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-subscriber//id?") } }, }, "Chitosocket-server//handler?": { Argsn: 2, Doc: "Returns the handler function for a specific event, or void if not set.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch eventName := arg1.(type) { case env.String: sock := server.Value.(*chitosocket.Socket) if handler, ok := sock.On[eventName.Value]; ok { return *env.NewNative(ps.Idx, handler, "Chitosocket-handler") } return env.Void{} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Chitosocket-server//handler?") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//handler?") } }, }, "Chitosocket-handler//call": { Argsn: 3, Doc: "Calls a handler function with the given subscriber and data.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch handler := arg0.(type) { case env.Native: switch sub := arg1.(type) { case env.Native: handlerFn := handler.Value.(chitosocket.HandlerFunc) subscriber := sub.Value.(*chitosocket.Subscriber) var dataBytes []byte switch data := arg2.(type) { case env.String: dataBytes = []byte(data.Value) case env.Void: dataBytes = nil default: dataBytes = []byte(arg2.Inspect(*ps.Idx)) } handlerFn(subscriber, dataBytes) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-handler//call") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-handler//call") } }, }, "Chitosocket-server//remove": { Argsn: 2, Doc: "Removes a subscriber from the server.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch sub := arg1.(type) { case env.Native: sock := server.Value.(*chitosocket.Socket) subscriber := sub.Value.(*chitosocket.Subscriber) err := sock.Remove(subscriber) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Chitosocket-server//remove") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "Chitosocket-server//remove") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Chitosocket-server//remove") } }, }, }
Builtins_chitosocket provides WebSocket server functionality with room support
var Builtins_cli = map[string]*env.Builtin{ "parse-args": { Argsn: 2, Doc: "Parses command line arguments according to a specification block, returning a dictionary with the parsed values.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return BuiParseArgs(es, arg0, arg1) }, }, "parse-args\\ctx": { Argsn: 2, Doc: "Parses command line arguments according to a specification block, returning a context for easy field access.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { result := BuiParseArgs(es, arg0, arg1) if es.FailureFlag || es.ErrorFlag || es.ReturnFlag { return result } switch dict := result.(type) { case env.Dict: ctx := env.NewEnv(es.Ctx) for k, v := range dict.Data { idx := es.Idx.IndexWord(k) if obj, ok := v.(env.Object); ok { ctx.Set(idx, obj) } else { ctx.Set(idx, env.ToRyeValue(v)) } } return ctx default: return result } }, }, "parse-args\\full": { Argsn: 2, Doc: "Parses command line arguments and on failure prints parse errors plus generated help, returning the parsed Dict or help text.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return BuiParseArgsFull(es, arg0, arg1) }, }, "Rye-itself//Parse-args\\full": { Argsn: 2, Doc: "Parses process arguments using a CLI specification, printing parse errors and generated help on failure. Equivalent to rye .Args? |parse-args spec with automatic error/help output.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return BuiParseArgsFull(es, ryeItselfArgsForCLI(es), arg1) }, }, "generate-help": { Argsn: 1, Doc: "Generates help text from a CLI specification block.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { spec, ok := arg0.(env.Block) if !ok { es.FailureFlag = true return evaldo.MakeArgError(es, 1, []env.Type{env.BlockType}, "generate-help") } cliSpec, err := CLI_ParseSpec(es, spec) if err != nil { es.FailureFlag = true return env.NewError2(400, "spec error: "+err.Error()) } helpText := generateHelpText(es, cliSpec, nil) return *env.NewString(helpText) }, }, "generate-help\\command": { Argsn: 2, Doc: "Generates help text for a specific subcommand.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { spec, ok := arg0.(env.Block) if !ok { es.FailureFlag = true return evaldo.MakeArgError(es, 1, []env.Type{env.BlockType}, "generate-help\\command") } cmdPath := make([]string, 0) switch cmd := arg1.(type) { case env.String: if cmd.Value != "" { cmdPath = strings.Split(cmd.Value, " ") } case env.Block: ser := cmd.Series ser.Reset() for ser.Pos() < ser.Len() { obj := ser.Pop() if s, ok := obj.(env.String); ok { cmdPath = append(cmdPath, s.Value) } else if w, ok := obj.(env.Word); ok { cmdPath = append(cmdPath, es.Idx.GetWord(w.Index)) } } default: es.FailureFlag = true return evaldo.MakeArgError(es, 2, []env.Type{env.StringType, env.BlockType}, "generate-help\\command") } cliSpec, err := CLI_ParseSpec(es, spec) if err != nil { es.FailureFlag = true return env.NewError2(400, "spec error: "+err.Error()) } helpText := generateHelpText(es, cliSpec, cmdPath) return *env.NewString(helpText) }, }, "format-parse-errors": { Argsn: 1, Doc: "Formats parse errors into human-readable messages.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch errObj := arg0.(type) { case env.Dict: errors := make(map[string]env.Object) for k, v := range errObj.Data { if obj, ok := v.(env.Object); ok { errors[k] = obj } } return *env.NewString(formatParseErrors(errors)) case *env.Error: if errObj.Values != nil { return *env.NewString(formatParseErrors(errObj.Values)) } return *env.NewString(errObj.Message) default: es.FailureFlag = true return evaldo.MakeArgError(es, 1, []env.Type{env.DictType}, "format-parse-errors") } }, }, }
var Builtins_complex = map[string]*env.Builtin{ "complex": { Argsn: 2, Doc: "Creates a complex number from real and imaginary parts.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var real, imag float64 switch r := arg0.(type) { case env.Integer: real = float64(r.Value) case env.Decimal: real = r.Value default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "complex") } switch i := arg1.(type) { case env.Integer: imag = float64(i.Value) case env.Decimal: imag = i.Value default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "complex") } return *env.NewComplexFromParts(real, imag) }, }, "complex?": { Argsn: 1, Doc: "Checks if a value is a complex number.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { _, ok := arg0.(env.Complex) return *env.NewBoolean(ok) }, }, "real": { Argsn: 1, Doc: "Returns the real part of a complex number.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch c := arg0.(type) { case env.Complex: return *env.NewDecimal(real(c.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.ComplexType}, "real") } }, }, "imag": { Argsn: 1, Doc: "Returns the imaginary part of a complex number.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch c := arg0.(type) { case env.Complex: return *env.NewDecimal(imag(c.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.ComplexType}, "imag") } }, }, "complex-conj": { Argsn: 1, Doc: "Returns the complex conjugate of a complex number.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch z := arg0.(type) { case env.Complex: return *env.NewComplex(cmplx.Conj(z.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.ComplexType}, "complex-conj") } }, }, "complex-phase": { Argsn: 1, Doc: "Returns the phase (argument) of a complex number.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch z := arg0.(type) { case env.Complex: return *env.NewDecimal(cmplx.Phase(z.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.ComplexType}, "complex-phase") } }, }, }
var Builtins_console = map[string]*env.Builtin{ "enter-console": { Argsn: 1, Doc: "Stops execution and gives you an interactive Rye console to test code in the current environment.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch name := arg0.(type) { case env.String: ser := ps.Ser fmt.Println("Welcome to console: \033[1m" + name.Value + "\033[0m") fmt.Println("* use \033[1mlc\033[0m to list current context") fmt.Println("-------------------------------------------------------------") console.DoRyeRepl(ps, "rye", evaldo.ShowResults, false, "") fmt.Println("-------------------------------------------------------------") ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "enter-console") } }, }, }
var Builtins_control = map[string]*env.Builtin{ "case": { Argsn: 1, Doc: "Evaluates condition expressions followed by action blocks. Returns the result of the first block whose condition is boolean true, or the default block marked with _ if no condition matches. Returns void if none match. Non-boolean conditions fail.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { pairs, ok := arg0.(env.Block) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "case") } ser := ps.Ser defer func() { ps.Ser = ser }() ps.Ser = pairs.Series for ps.Ser.Pos() < ps.Ser.Len() { _, isDefault := ps.Ser.Peek().(env.Void) condition := env.Boolean{Value: isDefault} if isDefault { ps.Ser.Pop() } else { evaldo.EvalExpression_CollectArg(ps, false, false) if ps.ErrorFlag || ps.FailureFlag || ps.ReturnFlag { return ps.Res } var ok bool condition, ok = ps.Res.(env.Boolean) if !ok { return evaldo.MakeBuiltinError(ps, "Condition must evaluate to boolean", "case") } } if ps.Ser.Pos() >= ps.Ser.Len() { return evaldo.MakeBuiltinError(ps, "Expected block after condition", "case") } action, ok := ps.Ser.Pop().(env.Block) if !ok { return evaldo.MakeBuiltinError(ps, "Expected block after condition", "case") } if condition.Value { ps.Ser = action.Series ps.Res = *env.NewVoid() evaldo.EvalBlockInj(ps, nil, false) return ps.Res } evaldo.MaybeAcceptComma(ps, nil, false) } return *env.NewVoid() }, }, }
Builtins_control contains control flow helpers.
var Builtins_conversion = map[string]*env.Builtin{ "convert": { Argsn: 2, Doc: "Converts value from one kind to another based on a conversion specification block.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return BuiConvert(ps, arg0, arg1) }, }, "converter": { Argsn: 3, Doc: "Registers a converter between two kinds of objects.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch obj1 := arg0.(type) { case env.Kind: switch obj2 := arg1.(type) { case env.Kind: switch spec := arg2.(type) { case env.Block: obj2.SetConverter(obj1.Kind.Index, spec) return obj2 default: return evaldo.MakeArgError(ps, 3, []env.Type{env.BlockType}, "converter") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.KindType, env.BlockType}, "converter") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.KindType}, "converter") } }, }, }
var Builtins_crypto = map[string]*env.Builtin{ "Ed25519-pub-key//To-string": { Argsn: 1, Doc: "Converts an Ed25519 public key to its hexadecimal string representation.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch addr := arg0.(type) { case env.Native: return *env.NewString(hex.EncodeToString(addr.Value.(ed25519.PublicKey))) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Ed25519-pub-key//To-string") } }, }, "Ed25519-priv-key//To-string": { Argsn: 1, Doc: "Converts an Ed25519 private key to its hexadecimal string representation.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch addr := arg0.(type) { case env.Native: return *env.NewString(hex.EncodeToString(addr.Value.(ed25519.PrivateKey))) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Ed25519-priv-key//To-string") } }, }, "ed25519-generate-keys": { Argsn: 0, Doc: "Generates a new Ed25519 key pair and returns them in a block with public key first, then private key.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { keys := make([]env.Object, 2) puk, pvk, err := ed25519.GenerateKey(nil) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to generate keys.", "ed25519-generate-keys") } keys[0] = *env.NewNative(ps.Idx, puk, "Ed25519-pub-key") keys[1] = *env.NewNative(ps.Idx, pvk, "Ed25519-priv-key") ser := *env.NewTSeries(keys) return *env.NewBlock(ser) }, }, "ed25519-private-key": { Argsn: 1, Doc: "Creates an Ed25519 private key from a hexadecimal string or bytes value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var pkey []byte var err error switch server := arg0.(type) { case env.Native: pkey = server.Value.([]byte) case env.String: pkey, err = hex.DecodeString(server.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in decoding string.", "ed25519-private-key") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType, env.StringType}, "ed25519-private-key") } return *env.NewNative(ps.Idx, ed25519.PrivateKey(pkey), "Ed25519-priv-key") }, }, "ed25519-public-key": { Argsn: 1, Doc: "Creates an Ed25519 public key from a hexadecimal string or bytes value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var pkey []byte var err error switch server := arg0.(type) { case env.Native: pkey = server.Value.([]byte) case env.String: pkey, err = hex.DecodeString(server.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in decoding string.", "ed25519-public-key") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType, env.StringType}, "ed25519-public-key") } return *env.NewNative(ps.Idx, ed25519.PublicKey(pkey), "Ed25519-pub-key") }, }, "Ed25519-priv-key//Sign": { Argsn: 2, Doc: "Signs a string message with an Ed25519 private key and returns the signature as bytes.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch pvk := arg0.(type) { case env.Native: switch buff := arg1.(type) { case env.String: sigb := ed25519.Sign(pvk.Value.(ed25519.PrivateKey), []byte(buff.Value)) return *env.NewBytes(sigb) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "Ed25519-priv-key//Sign") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Ed25519-priv-key//Sign") } }, }, "md5": { Argsn: 1, Doc: "Calculates the MD5 hash of a string or bytes and returns the result as a hexadecimal string. MD5 is not suitable for security-sensitive use.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, md5.New, "md5") }, }, "sha1": { Argsn: 1, Doc: "Calculates the SHA-1 hash of a string or bytes and returns the result as a hexadecimal string. SHA-1 is not suitable for security-sensitive use.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, sha1.New, "sha1") }, }, "sha224": { Argsn: 1, Doc: "Calculates the SHA-224 hash of a string or bytes and returns the result as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, sha256.New224, "sha224") }, }, "sha256": { Argsn: 1, Doc: "Calculates the SHA-256 hash of a string or bytes and returns the result as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, sha256.New, "sha256") }, }, "sha384": { Argsn: 1, Doc: "Calculates the SHA-384 hash of a string or bytes and returns the result as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, sha512.New384, "sha384") }, }, "sha512": { Argsn: 1, Doc: "Calculates the SHA-512 hash of a string or bytes and returns the result as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, sha512.New, "sha512") }, }, "crc32": { Argsn: 1, Doc: "Calculates the CRC-32 (IEEE) checksum of a string or bytes and returns it as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, func() hash.Hash { return crc32.NewIEEE() }, "crc32") }, }, "adler32": { Argsn: 1, Doc: "Calculates the Adler-32 checksum of a string or bytes and returns it as a hexadecimal string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return hashToHex(ps, arg0, func() hash.Hash { return adler32.New() }, "adler32") }, }, "age-generate-keys": { Argsn: 0, Doc: "Generates a new age key pair (identity and recipient).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { identity, err := age.GenerateX25519Identity() if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to generate key pair.", "age-generate-keys") } keys := make([]env.Object, 2) keys[0] = *env.NewNative(ps.Idx, identity, "age-identity") keys[1] = *env.NewNative(ps.Idx, identity.Recipient(), "age-recipient") ser := *env.NewTSeries(keys) return *env.NewBlock(ser) }, }, "age-identity": { Argsn: 1, Doc: "Creates an age identity from a string or bytes.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var identity *age.X25519Identity var err error switch ident := arg0.(type) { case env.Bytes: identity, err = age.ParseX25519Identity(hex.EncodeToString(ident.Value)) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in parsing identity: "+err.Error(), "age-identity") } case env.String: identity, err = age.ParseX25519Identity(ident.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in decoding string: "+err.Error(), "age-identity") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.BytesType, env.StringType}, "age-identity") } return *env.NewNative(ps.Idx, identity, "age-identity") }, }, "age-recipient": { Argsn: 1, Doc: "Creates an age recipient from a string or bytes.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var recipient *age.X25519Recipient var err error switch rec := arg0.(type) { case env.Bytes: recipient, err = age.ParseX25519Recipient(hex.EncodeToString(rec.Value)) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in parsing recipient: "+err.Error(), "age-recipient") } case env.String: recipient, err = age.ParseX25519Recipient(rec.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in decoding string: "+err.Error(), "age-recipient") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.BytesType, env.StringType}, "age-recipient") } return *env.NewNative(ps.Idx, recipient, "age-recipient") }, }, "age-encrypt": { Argsn: 2, Doc: "Encrypts a reader with age for the provided age recipient or string password and returns a reader.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch r := arg0.(type) { case env.Native: if ps.Idx.GetWord(r.GetKind()) != "reader" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-encrypt") } reader := r.Value.(io.Reader) var recipient age.Recipient switch rec := arg1.(type) { case env.Native: if ps.Idx.GetWord(rec.GetKind()) != "age-recipient" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-encrypt") } recipient = rec.Value.(*age.X25519Recipient) case env.String: var err error recipient, err = age.NewScryptRecipient(rec.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in creating recipient: "+err.Error(), "age-encrypt") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType, env.StringType}, "age-encrypt") } buf := new(bytes.Buffer) w, err := age.Encrypt(buf, recipient) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in encrypting: "+err.Error(), "age-encrypt") } data, err := io.ReadAll(reader) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error reading from reader: "+err.Error(), "age-encrypt") } if _, err := w.Write(data); err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in writing to buffer: "+err.Error(), "age-encrypt") } w.Close() return *env.NewNative(ps.Idx, bytes.NewReader(buf.Bytes()), "reader") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-encrypt") } }, }, "age-decrypt": { Argsn: 2, Doc: "Decrypts a reader with age using the provided age identity or string password and returns a reader with the decrypted content.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch r := arg0.(type) { case env.Native: if ps.Idx.GetWord(r.GetKind()) != "reader" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-decrypt") } reader := r.Value.(io.Reader) var identity age.Identity switch ident := arg1.(type) { case env.Native: if ps.Idx.GetWord(ident.GetKind()) != "age-identity" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-decrypt") } identity = ident.Value.(*age.X25519Identity) case env.String: var err error identity, err = age.NewScryptIdentity(ident.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in creating identity: "+err.Error(), "age-decrypt") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType, env.StringType}, "age-decrypt") } decrypted, err := age.Decrypt(reader, identity) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error in decrypting: "+err.Error(), "age-decrypt") } return *env.NewNative(ps.Idx, decrypted, "reader") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "age-decrypt") } }, }, "pkcs12-to-pem": { Argsn: 2, Doc: "Converts a PKCS#12 (.p12) file bytes to PEM blocks using the provided password. Returns a block of pem-block native values.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p12Data := arg0.(type) { case env.Bytes: switch password := arg1.(type) { case env.String: blocks, err := pkcs12.ToPEM(p12Data.Value, password.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to convert .p12 to PEM: %v", err), "pkcs12-to-pem") } objects := make([]env.Object, len(blocks)) for i, block := range blocks { objects[i] = *env.NewNative(ps.Idx, block, "pem-block") } ser := *env.NewTSeries(objects) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "pkcs12-to-pem") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.BytesType}, "pkcs12-to-pem") } }, }, "pkcs12-decode": { Argsn: 2, Doc: "Decodes a PKCS#12 (.p12) file bytes into private key and certificates using the provided password. Returns a block with [private-key, certificates, ca-certificates].", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p12Data := arg0.(type) { case env.Bytes: switch password := arg1.(type) { case env.String: key, cert, caCerts, err := sslmate.DecodeChain(p12Data.Value, password.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to decode .p12: %v", err), "pkcs12-decode") } certObjects := make([]env.Object, 0) if cert != nil { certObjects = append(certObjects, *env.NewNative(ps.Idx, cert, "x509-certificate")) } certSer := *env.NewTSeries(certObjects) certBlock := *env.NewBlock(certSer) caCertObjects := make([]env.Object, len(caCerts)) for i, caCert := range caCerts { caCertObjects[i] = *env.NewNative(ps.Idx, caCert, "x509-certificate") } caCertSer := *env.NewTSeries(caCertObjects) caCertBlock := *env.NewBlock(caCertSer) objects := make([]env.Object, 3) if key != nil { objects[0] = *env.NewNative(ps.Idx, key, "private-key") } else { objects[0] = *env.NewNative(ps.Idx, nil, "private-key") } objects[1] = certBlock objects[2] = caCertBlock ser := *env.NewTSeries(objects) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "pkcs12-decode") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.BytesType}, "pkcs12-decode") } }, }, "pem-block//Block-type?": { Argsn: 1, Doc: "Returns the type of a PEM block as a string (e.g., 'CERTIFICATE', 'RSA PRIVATE KEY').", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch certData := arg0.(type) { case env.Native: if ps.Idx.GetWord(certData.GetKind()) != "pem-block" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } pb, ok := certData.Value.(*pem.Block) if ok { return *env.NewString(pb.Type) } return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to parse certificate"), "x509-parse-certificate") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } }, }, "pem-block//Headers?": { Argsn: 1, Doc: "Returns the headers of a PEM block as a dictionary.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch certData := arg0.(type) { case env.Native: if ps.Idx.GetWord(certData.GetKind()) != "pem-block" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } pb, ok := certData.Value.(*pem.Block) if ok { headers := make(map[string]interface{}, len(pb.Headers)) for k, v := range pb.Headers { headers[k] = v } return *env.NewDict(headers) } return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to parse certificate"), "x509-parse-certificate") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } }, }, "x509-parse-certificate": { Argsn: 1, Doc: "Parses a PEM block into an X.509 certificate native value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch certData := arg0.(type) { case env.Native: if ps.Idx.GetWord(certData.GetKind()) != "pem-block" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } pb, ok := certData.Value.(*pem.Block) if ok { cert, err := x509.ParseCertificate(pb.Bytes) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to parse certificate: %v", err), "x509-parse-certificate") } return *env.NewNative(ps.Idx, cert, "x509-certificate") } return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to parse certificate"), "x509-parse-certificate") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-parse-certificate") } }, }, "x509-certificate//Not-after?": { Argsn: 1, Doc: "Returns the expiration date (NotAfter) of an X.509 certificate as a time value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } c := cert.Value.(*x509.Certificate) return *env.NewTime(c.NotAfter) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } }, }, "x509-certificate//Not-before?": { Argsn: 1, Doc: "Returns the start date (NotBefore) of an X.509 certificate as a time value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } c := cert.Value.(*x509.Certificate) return *env.NewTime(c.NotBefore) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } }, }, "x509-certificate//Is-expired": { Argsn: 1, Doc: "Checks if an X.509 certificate has expired. Returns 1 if expired, 0 otherwise.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } c := cert.Value.(*x509.Certificate) if time.Now().After(c.NotAfter) { return env.Integer{1} } return env.Integer{0} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//is-expired") } }, }, "generate-self-signed-certificate": { Argsn: 2, Doc: "Generates a self-signed X.509 certificate with a new RSA key pair.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch keySize := arg0.(type) { case env.Integer: if keySize.Value < 2048 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Key size must be at least 2048 bits", "generate-self-signed-certificate") } switch subjectDict := arg1.(type) { case env.Dict: privateKey, err := rsa.GenerateKey(rand.Reader, int(keySize.Value)) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to generate RSA key: %v", err), "generate-self-signed-certificate") } serialNumber, _ := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{}, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, IsCA: true, } if cn, ok := subjectDict.Data["CommonName"]; ok { if cnStr, ok := cn.(string); ok { template.Subject.CommonName = cnStr } } if org, ok := subjectDict.Data["Organization"]; ok { if orgStr, ok := org.(string); ok { template.Subject.Organization = []string{orgStr} } } certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to create certificate: %v", err), "generate-self-signed-certificate") } objects := []env.Object{ *env.NewNative(ps.Idx, &x509.Certificate{Raw: certBytes}, "x509-certificate"), *env.NewNative(ps.Idx, privateKey, "rsa-private-key"), } ser := *env.NewTSeries(objects) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.DictType}, "generate-self-signed-certificate") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "generate-self-signed-certificate") } }, }, "encode-to-pem": { Argsn: 2, Doc: "Encodes a certificate and private key as PEM-formatted data.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch certObj := arg0.(type) { case env.Native: if ps.Idx.GetWord(certObj.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "encode-to-pem") } cert := certObj.Value.(*x509.Certificate) switch keyObj := arg1.(type) { case env.Native: if ps.Idx.GetWord(keyObj.GetKind()) != "rsa-private-key" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "encode-to-pem") } privateKey := keyObj.Value.(*rsa.PrivateKey) certPEM := &bytes.Buffer{} err := pem.Encode(certPEM, &pem.Block{ Type: "CERTIFICATE", Bytes: cert.Raw, }) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to encode certificate to PEM: %v", err), "encode-to-pem") } keyPEM := &bytes.Buffer{} err = pem.Encode(keyPEM, &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), }) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to encode private key to PEM: %v", err), "encode-to-pem") } objects := []env.Object{ *env.NewNative(ps.Idx, certPEM.Bytes(), "Go-bytes"), *env.NewNative(ps.Idx, keyPEM.Bytes(), "Go-bytes"), } ser := *env.NewTSeries(objects) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "encode-to-pem") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "encode-to-pem") } }, }, "encode-to-p12": { Argsn: 3, Doc: "Encodes a certificate and private key into a PKCS#12 (.p12) file with password protection.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch certObj := arg0.(type) { case env.Native: if ps.Idx.GetWord(certObj.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "encode-to-p12") } cert := certObj.Value.(*x509.Certificate) switch keyObj := arg1.(type) { case env.Native: if ps.Idx.GetWord(keyObj.GetKind()) != "rsa-private-key" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "encode-to-p12") } privateKey := keyObj.Value.(*rsa.PrivateKey) switch password := arg2.(type) { case env.String: p12Bytes, err := sslmate.Encode(rand.Reader, privateKey, cert, nil, password.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to encode to .p12: %v", err), "encode-to-p12") } return *env.NewNative(ps.Idx, p12Bytes, "Go-bytes") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "encode-to-p12") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "encode-to-p12") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "encode-to-p12") } }, }, "x509-certificate//Subject?": { Argsn: 1, Doc: "Returns the subject Distinguished Name (DN) of an X.509 certificate as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//Subject?") } c := cert.Value.(*x509.Certificate) return *env.NewString(c.Subject.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//Subject?") } }, }, "x509-certificate//Issuer?": { Argsn: 1, Doc: "Returns the issuer Distinguished Name (DN) of an X.509 certificate as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//issuer?") } c := cert.Value.(*x509.Certificate) return *env.NewString(c.Issuer.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//issuer?") } }, }, "x509-certificate//Serial-number?": { Argsn: 1, Doc: "Returns the serial number of an X.509 certificate as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//serial-number?") } c := cert.Value.(*x509.Certificate) return *env.NewString(c.SerialNumber.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//serial-number?") } }, }, "x509-certificate//Signature-algorithm?": { Argsn: 1, Doc: "Returns the signature algorithm of an X.509 certificate as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//signature-algorithm?") } c := cert.Value.(*x509.Certificate) return *env.NewString(c.SignatureAlgorithm.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//signature-algorithm?") } }, }, "x509-certificate//Public-key-algorithm?": { Argsn: 1, Doc: "Returns the public key algorithm of an X.509 certificate as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//public-key-algorithm?") } c := cert.Value.(*x509.Certificate) return *env.NewString(c.PublicKeyAlgorithm.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//public-key-algorithm?") } }, }, "x509-certificate//Key-usage?": { Argsn: 1, Doc: "Returns the key usage flags of an X.509 certificate as a block of strings.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//key-usage?") } c := cert.Value.(*x509.Certificate) var usages []env.Object if c.KeyUsage&x509.KeyUsageDigitalSignature > 0 { usages = append(usages, *env.NewString("Digital Signature")) } if c.KeyUsage&x509.KeyUsageContentCommitment > 0 { usages = append(usages, *env.NewString("Content Commitment")) } if c.KeyUsage&x509.KeyUsageKeyEncipherment > 0 { usages = append(usages, *env.NewString("Key Encipherment")) } if c.KeyUsage&x509.KeyUsageDataEncipherment > 0 { usages = append(usages, *env.NewString("Data Encipherment")) } if c.KeyUsage&x509.KeyUsageKeyAgreement > 0 { usages = append(usages, *env.NewString("Key Agreement")) } if c.KeyUsage&x509.KeyUsageCertSign > 0 { usages = append(usages, *env.NewString("Cert Sign")) } if c.KeyUsage&x509.KeyUsageCRLSign > 0 { usages = append(usages, *env.NewString("CRL Sign")) } if c.KeyUsage&x509.KeyUsageEncipherOnly > 0 { usages = append(usages, *env.NewString("Encipher Only")) } if c.KeyUsage&x509.KeyUsageDecipherOnly > 0 { usages = append(usages, *env.NewString("Decipher Only")) } ser := *env.NewTSeries(usages) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//key-usage?") } }, }, "x509-certificate//Extended-key-usage?": { Argsn: 1, Doc: "Returns the extended key usage flags of an X.509 certificate as a block of strings.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//extended-key-usage?") } c := cert.Value.(*x509.Certificate) usages := make([]env.Object, len(c.ExtKeyUsage)) for i, extKeyUsage := range c.ExtKeyUsage { var usageStr string switch extKeyUsage { case x509.ExtKeyUsageServerAuth: usageStr = "Server Authentication" case x509.ExtKeyUsageClientAuth: usageStr = "Client Authentication" case x509.ExtKeyUsageCodeSigning: usageStr = "Code Signing" case x509.ExtKeyUsageEmailProtection: usageStr = "Email Protection" case x509.ExtKeyUsageTimeStamping: usageStr = "Time Stamping" case x509.ExtKeyUsageOCSPSigning: usageStr = "OCSP Signing" default: usageStr = fmt.Sprintf("Unknown (%d)", int(extKeyUsage)) } usages[i] = *env.NewString(usageStr) } ser := *env.NewTSeries(usages) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//extended-key-usage?") } }, }, "x509-certificate//Dns-names?": { Argsn: 1, Doc: "Returns the DNS names from Subject Alternative Names of an X.509 certificate as a block of strings.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//dns-names?") } c := cert.Value.(*x509.Certificate) names := make([]env.Object, len(c.DNSNames)) for i, name := range c.DNSNames { names[i] = *env.NewString(name) } ser := *env.NewTSeries(names) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//dns-names?") } }, }, "x509-certificate//Ip-addresses?": { Argsn: 1, Doc: "Returns the IP addresses from Subject Alternative Names of an X.509 certificate as a block of strings.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//ip-addresses?") } c := cert.Value.(*x509.Certificate) addresses := make([]env.Object, len(c.IPAddresses)) for i, addr := range c.IPAddresses { addresses[i] = *env.NewString(addr.String()) } ser := *env.NewTSeries(addresses) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//ip-addresses?") } }, }, "x509-certificate//Email-addresses?": { Argsn: 1, Doc: "Returns the email addresses from Subject Alternative Names of an X.509 certificate as a block of strings.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//email-addresses?") } c := cert.Value.(*x509.Certificate) emails := make([]env.Object, len(c.EmailAddresses)) for i, email := range c.EmailAddresses { emails[i] = *env.NewString(email) } ser := *env.NewTSeries(emails) return *env.NewBlock(ser) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//email-addresses?") } }, }, "x509-certificate//To-pem": { Argsn: 1, Doc: "Converts an X.509 certificate to PEM-encoded string format.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//to-pem") } c := cert.Value.(*x509.Certificate) pemBlock := &pem.Block{Type: "CERTIFICATE", Bytes: c.Raw} pemBytes := pem.EncodeToMemory(pemBlock) return *env.NewString(string(pemBytes)) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//to-pem") } }, }, "private-key//Type?": { Argsn: 1, Doc: "Returns the type of a private key as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch key := arg0.(type) { case env.Native: if ps.Idx.GetWord(key.GetKind()) != "private-key" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "private-key//type?") } return *env.NewString(fmt.Sprintf("%T", key.Value)) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "private-key//type?") } }, }, "x509-certificate//To-dict": { Argsn: 1, Doc: "Converts an X.509 certificate to a dictionary containing all certificate information for easy display and manipulation.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cert := arg0.(type) { case env.Native: if ps.Idx.GetWord(cert.GetKind()) != "x509-certificate" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//to-dict") } c := cert.Value.(*x509.Certificate) certDict := make(map[string]interface{}) certDict["Subject"] = c.Subject.String() certDict["Issuer"] = c.Issuer.String() certDict["SerialNumber"] = c.SerialNumber.String() certDict["NotBefore"] = c.NotBefore.Format("2006-01-02 15:04:05 MST") certDict["NotAfter"] = c.NotAfter.Format("2006-01-02 15:04:05 MST") certDict["SignatureAlgorithm"] = c.SignatureAlgorithm.String() certDict["PublicKeyAlgorithm"] = c.PublicKeyAlgorithm.String() certDict["Version"] = int64(c.Version) certDict["IsCA"] = c.IsCA // Key Usage var keyUsages []interface{} if c.KeyUsage&x509.KeyUsageDigitalSignature > 0 { keyUsages = append(keyUsages, "Digital Signature") } if c.KeyUsage&x509.KeyUsageContentCommitment > 0 { keyUsages = append(keyUsages, "Content Commitment") } if c.KeyUsage&x509.KeyUsageKeyEncipherment > 0 { keyUsages = append(keyUsages, "Key Encipherment") } if c.KeyUsage&x509.KeyUsageDataEncipherment > 0 { keyUsages = append(keyUsages, "Data Encipherment") } if c.KeyUsage&x509.KeyUsageKeyAgreement > 0 { keyUsages = append(keyUsages, "Key Agreement") } if c.KeyUsage&x509.KeyUsageCertSign > 0 { keyUsages = append(keyUsages, "Cert Sign") } if c.KeyUsage&x509.KeyUsageCRLSign > 0 { keyUsages = append(keyUsages, "CRL Sign") } if c.KeyUsage&x509.KeyUsageEncipherOnly > 0 { keyUsages = append(keyUsages, "Encipher Only") } if c.KeyUsage&x509.KeyUsageDecipherOnly > 0 { keyUsages = append(keyUsages, "Decipher Only") } certDict["KeyUsage"] = keyUsages // Extended Key Usage var extKeyUsages []interface{} for _, extKeyUsage := range c.ExtKeyUsage { var usageStr string switch extKeyUsage { case x509.ExtKeyUsageServerAuth: usageStr = "Server Authentication" case x509.ExtKeyUsageClientAuth: usageStr = "Client Authentication" case x509.ExtKeyUsageCodeSigning: usageStr = "Code Signing" case x509.ExtKeyUsageEmailProtection: usageStr = "Email Protection" case x509.ExtKeyUsageTimeStamping: usageStr = "Time Stamping" case x509.ExtKeyUsageOCSPSigning: usageStr = "OCSP Signing" default: usageStr = fmt.Sprintf("Unknown (%d)", int(extKeyUsage)) } extKeyUsages = append(extKeyUsages, usageStr) } certDict["ExtendedKeyUsage"] = extKeyUsages // Subject Alternative Names var dnsNames []interface{} for _, name := range c.DNSNames { dnsNames = append(dnsNames, name) } certDict["DNSNames"] = dnsNames var ipAddresses []interface{} for _, addr := range c.IPAddresses { ipAddresses = append(ipAddresses, addr.String()) } certDict["IPAddresses"] = ipAddresses var emailAddresses []interface{} for _, email := range c.EmailAddresses { emailAddresses = append(emailAddresses, email) } certDict["EmailAddresses"] = emailAddresses pemBlock := &pem.Block{Type: "CERTIFICATE", Bytes: c.Raw} pemBytes := pem.EncodeToMemory(pemBlock) certDict["PEM"] = string(pemBytes) certDict["IsExpired"] = time.Now().After(c.NotAfter) return *env.NewDict(certDict) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "x509-certificate//to-dict") } }, }, }
var Builtins_echarts = map[string]*env.Builtin{ "bar-chart": { Argsn: 0, Doc: "Creates a new ECharts bar chart instance.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { bar := charts.NewBar() return *env.NewNative(ps.Idx, bar, "echarts-bar") }, }, "bar-data": { Argsn: 1, Doc: "Converts a block of numbers into ECharts bar data items.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch blk := arg0.(type) { case env.Block: items, err := blockToBarData(ps, blk) if err != nil { return err } return *env.NewNative(ps.Idx, items, "echarts-bar-data") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "bar-data") } }, }, "title-opts": { Argsn: 2, Doc: "Creates ECharts title options with title and subtitle.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { title, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "title-opts") } subtitle, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "title-opts") } titleOpts := opts.Title{ Title: title.Value, Subtitle: subtitle.Value, } return *env.NewNative(ps.Idx, titleOpts, "echarts-title-opts") }, }, "with-title-opts": { Argsn: 1, Doc: "Wraps title options into a chart global option.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch nat := arg0.(type) { case env.Native: titleOpts, ok := nat.Value.(opts.Title) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-title-opts"}, "with-title-opts") } opt := charts.WithTitleOpts(titleOpts) return *env.NewNative(ps.Idx, opt, "echarts-global-opts") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "with-title-opts") } }, }, "echarts-bar//Global-options!": { Argsn: 2, Doc: "Sets global options on an ECharts bar chart. Accepts a single option or a block of options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { barNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-bar//Global-options!") } bar, ok := barNat.Value.(*charts.Bar) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-bar"}, "echarts-bar//Global-options!") } // Collect options var gopts []charts.GlobalOpts switch opt := arg1.(type) { case env.Native: gopt, ok := opt.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"echarts-global-opts"}, "echarts-bar//Global-options!") } gopts = append(gopts, gopt) case env.Block: for i := 0; i < opt.Series.Len(); i++ { obj := opt.Series.Get(i) nat, ok := obj.(env.Native) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain native echarts-global-opts", "echarts-bar//Global-options!") } gopt, ok := nat.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain echarts-global-opts natives", "echarts-bar//Global-options!") } gopts = append(gopts, gopt) } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType, env.BlockType}, "echarts-bar//Global-options!") } bar.SetGlobalOptions(gopts...) return barNat }, }, "echarts-bar//X-axis!": { Argsn: 2, Doc: "Sets the x-axis labels on an ECharts bar chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { barNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-bar//X-axis!") } bar, ok := barNat.Value.(*charts.Bar) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-bar"}, "echarts-bar//X-axis!") } switch blk := arg1.(type) { case env.Block: labels, err := blockToStringSlice(ps, blk) if err != nil { return err } bar.SetXAxis(labels) return barNat default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "echarts-bar//X-axis!") } }, }, "echarts-bar//Add-series": { Argsn: 3, Doc: "Adds a data series to an ECharts bar chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { barNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-bar//Add-series") } bar, ok := barNat.Value.(*charts.Bar) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-bar"}, "echarts-bar//Add-series") } name, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "echarts-bar//Add-series") } dataNat, ok := arg2.(env.Native) if !ok { return evaldo.MakeArgError(ps, 3, []env.Type{env.NativeType}, "echarts-bar//Add-series") } data, ok := dataNat.Value.([]opts.BarData) if !ok { return evaldo.MakeNativeArgError(ps, 3, []string{"echarts-bar-data"}, "echarts-bar//Add-series") } bar.AddSeries(name.Value, data) return barNat }, }, "echarts-bar//Render": { Argsn: 2, Doc: "Renders an ECharts bar chart to a writer (file, etc.).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { barNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-bar//Render") } bar, ok := barNat.Value.(*charts.Bar) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-bar"}, "echarts-bar//Render") } writerNat, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "echarts-bar//Render") } writer, ok := writerNat.Value.(io.Writer) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"io.Writer (e.g., file)"}, "echarts-bar//Render") } err := bar.Render(writer) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "echarts-bar//Render") } return barNat }, }, "line-chart": { Argsn: 0, Doc: "Creates a new ECharts line chart instance.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { line := charts.NewLine() return *env.NewNative(ps.Idx, line, "echarts-line") }, }, "line-data": { Argsn: 1, Doc: "Converts a block of numbers into ECharts line data items.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch blk := arg0.(type) { case env.Block: items, err := blockToLineData(ps, blk) if err != nil { return err } return *env.NewNative(ps.Idx, items, "echarts-line-data") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "line-data") } }, }, "echarts-line//Global-options!": { Argsn: 2, Doc: "Sets global options on an ECharts line chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { lineNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-line//Global-options!") } line, ok := lineNat.Value.(*charts.Line) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-line"}, "echarts-line//Global-options!") } var gopts []charts.GlobalOpts switch opt := arg1.(type) { case env.Native: gopt, ok := opt.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"echarts-global-opts"}, "echarts-line//Global-options!") } gopts = append(gopts, gopt) case env.Block: for i := 0; i < opt.Series.Len(); i++ { obj := opt.Series.Get(i) nat, ok := obj.(env.Native) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain native echarts-global-opts", "echarts-line//Global-options!") } gopt, ok := nat.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain echarts-global-opts natives", "echarts-line//Global-options!") } gopts = append(gopts, gopt) } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType, env.BlockType}, "echarts-line//Global-options!") } line.SetGlobalOptions(gopts...) return lineNat }, }, "echarts-line//X-axis!": { Argsn: 2, Doc: "Sets the x-axis labels on an ECharts line chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { lineNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-line//X-axis!") } line, ok := lineNat.Value.(*charts.Line) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-line"}, "echarts-line//X-axis!") } switch blk := arg1.(type) { case env.Block: labels, err := blockToStringSlice(ps, blk) if err != nil { return err } line.SetXAxis(labels) return lineNat default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "echarts-line//X-axis!") } }, }, "echarts-line//Add-series": { Argsn: 3, Doc: "Adds a data series to an ECharts line chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { lineNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-line//Add-series") } line, ok := lineNat.Value.(*charts.Line) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-line"}, "echarts-line//Add-series") } name, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "echarts-line//Add-series") } dataNat, ok := arg2.(env.Native) if !ok { return evaldo.MakeArgError(ps, 3, []env.Type{env.NativeType}, "echarts-line//Add-series") } data, ok := dataNat.Value.([]opts.LineData) if !ok { return evaldo.MakeNativeArgError(ps, 3, []string{"echarts-line-data"}, "echarts-line//Add-series") } line.AddSeries(name.Value, data) return lineNat }, }, "echarts-line//Render": { Argsn: 2, Doc: "Renders an ECharts line chart to a writer (file, etc.).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { lineNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-line//Render") } line, ok := lineNat.Value.(*charts.Line) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-line"}, "echarts-line//Render") } writerNat, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "echarts-line//Render") } writer, ok := writerNat.Value.(io.Writer) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"io.Writer"}, "echarts-line//Render") } err := line.Render(writer) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "echarts-line//Render") } return lineNat }, }, "pie-chart": { Argsn: 0, Doc: "Creates a new ECharts pie chart instance.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { pie := charts.NewPie() return *env.NewNative(ps.Idx, pie, "echarts-pie") }, }, "pie-data": { Argsn: 1, Doc: "Converts a block of name-value pairs into ECharts pie data items.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch blk := arg0.(type) { case env.Block: items, err := blockToPieData(ps, blk) if err != nil { return err } return *env.NewNative(ps.Idx, items, "echarts-pie-data") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "pie-data") } }, }, "echarts-pie//Global-options!": { Argsn: 2, Doc: "Sets global options on an ECharts pie chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { pieNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-pie//Global-options!") } pie, ok := pieNat.Value.(*charts.Pie) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-pie"}, "echarts-pie//Global-options!") } var gopts []charts.GlobalOpts switch opt := arg1.(type) { case env.Native: gopt, ok := opt.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"echarts-global-opts"}, "echarts-pie//Global-options!") } gopts = append(gopts, gopt) case env.Block: for i := 0; i < opt.Series.Len(); i++ { obj := opt.Series.Get(i) nat, ok := obj.(env.Native) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain native echarts-global-opts", "echarts-pie//Global-options!") } gopt, ok := nat.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain echarts-global-opts natives", "echarts-pie//Global-options!") } gopts = append(gopts, gopt) } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType, env.BlockType}, "echarts-pie//Global-options!") } pie.SetGlobalOptions(gopts...) return pieNat }, }, "echarts-pie//Add-series": { Argsn: 2, Doc: "Adds a data series to an ECharts pie chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { pieNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-pie//Add-series") } pie, ok := pieNat.Value.(*charts.Pie) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-pie"}, "echarts-pie//Add-series") } dataNat, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "echarts-pie//Add-series") } data, ok := dataNat.Value.([]opts.PieData) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"echarts-pie-data"}, "echarts-pie//Add-series") } pie.AddSeries("pie", data) return pieNat }, }, "echarts-pie//Render": { Argsn: 2, Doc: "Renders an ECharts pie chart to a writer (file, etc.).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { pieNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-pie//Render") } pie, ok := pieNat.Value.(*charts.Pie) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-pie"}, "echarts-pie//Render") } writerNat, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "echarts-pie//Render") } writer, ok := writerNat.Value.(io.Writer) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"io.Writer"}, "echarts-pie//Render") } err := pie.Render(writer) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "echarts-pie//Render") } return pieNat }, }, "scatter-chart": { Argsn: 0, Doc: "Creates a new ECharts scatter chart instance.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { scatter := charts.NewScatter() return *env.NewNative(ps.Idx, scatter, "echarts-scatter") }, }, "scatter-data": { Argsn: 1, Doc: "Converts a block of [x y] pairs into ECharts scatter data items.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch blk := arg0.(type) { case env.Block: items, err := blockToScatterData(ps, blk) if err != nil { return err } return *env.NewNative(ps.Idx, items, "echarts-scatter-data") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "scatter-data") } }, }, "echarts-scatter//Global-options!": { Argsn: 2, Doc: "Sets global options on an ECharts scatter chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { scatterNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-scatter//Global-options!") } scatter, ok := scatterNat.Value.(*charts.Scatter) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-scatter"}, "echarts-scatter//Global-options!") } var gopts []charts.GlobalOpts switch opt := arg1.(type) { case env.Native: gopt, ok := opt.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"echarts-global-opts"}, "echarts-scatter//Global-options!") } gopts = append(gopts, gopt) case env.Block: for i := 0; i < opt.Series.Len(); i++ { obj := opt.Series.Get(i) nat, ok := obj.(env.Native) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain native echarts-global-opts", "echarts-scatter//Global-options!") } gopt, ok := nat.Value.(charts.GlobalOpts) if !ok { return evaldo.MakeBuiltinError(ps, "block must contain echarts-global-opts natives", "echarts-scatter//Global-options!") } gopts = append(gopts, gopt) } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType, env.BlockType}, "echarts-scatter//Global-options!") } scatter.SetGlobalOptions(gopts...) return scatterNat }, }, "echarts-scatter//X-axis!": { Argsn: 2, Doc: "Sets the x-axis labels on an ECharts scatter chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { scatterNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-scatter//X-axis!") } scatter, ok := scatterNat.Value.(*charts.Scatter) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-scatter"}, "echarts-scatter//X-axis!") } switch blk := arg1.(type) { case env.Block: labels, err := blockToStringSlice(ps, blk) if err != nil { return err } scatter.SetXAxis(labels) return scatterNat default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "echarts-scatter//X-axis!") } }, }, "echarts-scatter//Add-series": { Argsn: 3, Doc: "Adds a data series to an ECharts scatter chart.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { scatterNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-scatter//Add-series") } scatter, ok := scatterNat.Value.(*charts.Scatter) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-scatter"}, "echarts-scatter//Add-series") } name, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "echarts-scatter//Add-series") } dataNat, ok := arg2.(env.Native) if !ok { return evaldo.MakeArgError(ps, 3, []env.Type{env.NativeType}, "echarts-scatter//Add-series") } data, ok := dataNat.Value.([]opts.ScatterData) if !ok { return evaldo.MakeNativeArgError(ps, 3, []string{"echarts-scatter-data"}, "echarts-scatter//Add-series") } scatter.AddSeries(name.Value, data) return scatterNat }, }, "echarts-scatter//Render": { Argsn: 2, Doc: "Renders an ECharts scatter chart to a writer (file, etc.).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { scatterNat, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "echarts-scatter//Render") } scatter, ok := scatterNat.Value.(*charts.Scatter) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-scatter"}, "echarts-scatter//Render") } writerNat, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "echarts-scatter//Render") } writer, ok := writerNat.Value.(io.Writer) if !ok { return evaldo.MakeNativeArgError(ps, 2, []string{"io.Writer"}, "echarts-scatter//Render") } err := scatter.Render(writer) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "echarts-scatter//Render") } return scatterNat }, }, "legend-opts": { Argsn: 0, Doc: "Creates ECharts legend options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { legendOpts := opts.Legend{} return *env.NewNative(ps.Idx, legendOpts, "echarts-legend-opts") }, }, "with-legend-opts": { Argsn: 1, Doc: "Wraps legend options into a chart global option.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch nat := arg0.(type) { case env.Native: legendOpts, ok := nat.Value.(opts.Legend) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-legend-opts"}, "with-legend-opts") } opt := charts.WithLegendOpts(legendOpts) return *env.NewNative(ps.Idx, opt, "echarts-global-opts") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "with-legend-opts") } }, }, "tooltip-opts": { Argsn: 0, Doc: "Creates ECharts tooltip options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { tooltipOpts := opts.Tooltip{} return *env.NewNative(ps.Idx, tooltipOpts, "echarts-tooltip-opts") }, }, "with-tooltip-opts": { Argsn: 1, Doc: "Wraps tooltip options into a chart global option.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch nat := arg0.(type) { case env.Native: tooltipOpts, ok := nat.Value.(opts.Tooltip) if !ok { return evaldo.MakeNativeArgError(ps, 1, []string{"echarts-tooltip-opts"}, "with-tooltip-opts") } opt := charts.WithTooltipOpts(tooltipOpts) return *env.NewNative(ps.Idx, opt, "echarts-global-opts") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "with-tooltip-opts") } }, }, }
var Builtins_email = map[string]*env.Builtin{ "email-message": { Argsn: 0, Doc: "Creates a new empty email message object that can be configured with headers, body, and attachments.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __newMessage(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-message//Set-header": { Argsn: 3, Doc: "Sets a standard email header field such as Subject, To, From, Cc, or Bcc with the specified value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __setHeader(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-message//Set-address-header": { Argsn: 4, Doc: "Sets an email address header with both email address and display name, commonly used for From, To, Cc, and Bcc fields.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __setAddressHeader(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-message//Set-body": { Argsn: 3, Doc: "Sets the main body content of the email with the specified MIME content type, supporting plain text and HTML formats.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __setBody(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-message//Attach": { Argsn: 2, Doc: "Attaches a file to the email message using a file URI, making the file available as an email attachment.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __attach(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-message//Add-alternative": { Argsn: 3, Doc: "Adds alternative content to the email (e.g., HTML version alongside plain text), allowing email clients to choose their preferred format.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __addAlternative(ps, arg0, arg1, arg2, arg3, arg4) }, }, "new-email-dialer": { Argsn: 4, Doc: "Creates a new SMTP dialer configured with server details and authentication credentials for sending emails.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __newDialer(ps, arg0, arg1, arg2, arg3, arg4) }, }, "gomail-dialer//Dial-and-send": { Argsn: 2, Doc: "Connects to the SMTP server and sends the specified email message, handling authentication and delivery.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return __dialAndSend(ps, arg0, arg1, arg2, arg3, arg4) }, }, }
var Builtins_encoding = map[string]*env.Builtin{ "decode\\hex-string": { Argsn: 1, Doc: "Decodes a hexadecimal string to a UTF-8 string.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch hexStr := arg0.(type) { case env.String: decoded, err := hex.DecodeString(hexStr.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to decode hex string: "+err.Error(), "decode\\hex-string") } return *env.NewString(string(decoded)) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "decode\\hex-string") } }, }, "encode-to\\hex-string": { Argsn: 1, Doc: "Encodes a string to its hexadecimal representation.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.String: encoded := hex.EncodeToString([]byte(str.Value)) return *env.NewString(encoded) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "encode-to\\hex-string") } }, }, "clean\\hex-string": { Argsn: 1, Doc: "Removes all whitespace from a hex string and ensures even length.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch hexStr := arg0.(type) { case env.String: var sb strings.Builder for _, r := range hexStr.Value { if !unicode.IsSpace(r) { sb.WriteRune(r) } } result := sb.String() if len(result)%2 != 0 { result = result[:len(result)-1] } return *env.NewString(result) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "clean\\hex-string") } }, }, "charmap\\windows-1250": { Argsn: 0, Doc: "Returns the Windows-1250 (CP1250) character encoding for Central European languages.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.Windows1250, "charmap-encoding") }, }, "charmap\\iso-8859-1": { Argsn: 0, Doc: "Returns the ISO-8859-1 (Latin-1) character encoding.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.ISO8859_1, "charmap-encoding") }, }, "charmap\\iso-8859-2": { Argsn: 0, Doc: "Returns the ISO-8859-2 (Latin-2) character encoding for Central European languages.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.ISO8859_2, "charmap-encoding") }, }, "charmap\\windows-1252": { Argsn: 0, Doc: "Returns the Windows-1252 character encoding for Western European languages.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.Windows1252, "charmap-encoding") }, }, "charmap\\code-page-437": { Argsn: 0, Doc: "Returns the Code Page 437 (DOS/IBM PC) character encoding.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.CodePage437, "charmap-encoding") }, }, "charmap\\code-page-850": { Argsn: 0, Doc: "Returns the Code Page 850 (DOS Latin-1) character encoding.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.CodePage850, "charmap-encoding") }, }, "charmap\\koi8r": { Argsn: 0, Doc: "Returns the KOI8-R character encoding for Russian.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, charmap.KOI8R, "charmap-encoding") }, }, "charmap-encoding//Decoder": { Argsn: 1, Doc: "Creates a new text decoder for the given character encoding.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch encoding := arg0.(type) { case env.Native: if ps.Idx.GetWord(encoding.GetKind()) != "charmap-encoding" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "charmap-encoding\\new-decoder") } enc := encoding.Value.(*charmap.Charmap) decoder := enc.NewDecoder() return *env.NewNative(ps.Idx, decoder, "text-decoder") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "charmap-encoding\\new-decoder") } }, }, "charmap-encoding//Encoder": { Argsn: 1, Doc: "Creates a new text encoder for the given character encoding.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch encoding := arg0.(type) { case env.Native: if ps.Idx.GetWord(encoding.GetKind()) != "charmap-encoding" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "charmap-encoding\\new-encoder") } enc := encoding.Value.(*charmap.Charmap) encoder := enc.NewEncoder() return *env.NewNative(ps.Idx, encoder, "text-encoder") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "charmap-encoding\\new-encoder") } }, }, "text-decoder//Decode": { Argsn: 2, Doc: "Decodes a string using the given text decoder.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch decoder := arg0.(type) { case env.Native: if ps.Idx.GetWord(decoder.GetKind()) != "text-decoder" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "text-decoder\\string") } switch input := arg1.(type) { case env.String: dec := decoder.Value.(*encoding.Decoder) decoded, err := dec.String(input.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to decode string: "+err.Error(), "text-decoder\\string") } return *env.NewString(decoded) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "text-decoder\\string") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "text-decoder\\string") } }, }, "text-encoder//Encode": { Argsn: 2, Doc: "Encodes a string using the given text encoder.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch encoder := arg0.(type) { case env.Native: if ps.Idx.GetWord(encoder.GetKind()) != "text-encoder" { ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "text-encoder\\string") } switch input := arg1.(type) { case env.String: enc := encoder.Value.(*encoding.Encoder) encoded, err := enc.String(input.Value) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to encode string: "+err.Error(), "text-encoder\\string") } return *env.NewString(encoded) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "text-encoder\\string") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "text-encoder\\string") } }, }, "is-space": { Argsn: 1, Doc: "Checks if a single character string is a whitespace character.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.String: if len(str.Value) == 0 { return *env.NewBoolean(false) } for _, r := range str.Value { return *env.NewBoolean(unicode.IsSpace(r)) } return *env.NewBoolean(false) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "is-space") } }, }, "remove-all-space": { Argsn: 1, Doc: "Removes all whitespace characters from a string.", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.String: var sb strings.Builder for _, r := range str.Value { if !unicode.IsSpace(r) { sb.WriteRune(r) } } return *env.NewString(sb.String()) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "remove-all-space") } }, }, }
var Builtins_eyr = map[string]*env.Builtin{ "eyr": { Argsn: 1, Doc: "Evaluates Rye block as Eyr (postfix) stack based code.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series dialect := ps.Dialect ps.Dialect = env.EyrDialect ps.ResetStack() Eyr_EvalBlock(ps, false) ps.Dialect = dialect ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "eyr") } }, }, "rye0": { Argsn: 1, Doc: "Evaluates Rye block as Rye0 dialect.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series dialect := ps.Dialect ps.Dialect = env.Rye0Dialect evaldo.Rye0_EvalBlockInj(ps, nil, false) ps.Dialect = dialect ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "rye0") } }, }, "rye00": { Argsn: 1, Doc: "Evaluates Rye block as Rye00 dialect (builtins and integers only).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series dialect := ps.Dialect ps.Dialect = env.Rye00Dialect evaldo.Rye00_EvalBlockInj(ps, nil, false) ps.Dialect = dialect ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "rye00") } }, }, "eyr\\clear": { Argsn: 0, Doc: "Clears the EYR stack.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { ps.ResetStack() return env.NewBoolean(false) }, }, "eyr\\full": { Argsn: 1, Doc: "Evaluates Rye block as Eyr (postfix) stack based code.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series dialect := ps.Dialect ps.Dialect = env.EyrDialect Eyr_EvalBlock(ps, true) ps.Dialect = dialect ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "eyr\\full") } }, }, "eyr\\loop": { Argsn: 2, Doc: "Evaluates Rye block in loop as Eyr code (postfix stack based) N times.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cond := arg0.(type) { case env.Integer: switch bloc := arg1.(type) { case env.Block: ps.Dialect = env.EyrDialect ser := ps.Ser ps.Ser = bloc.Series for i := 0; int64(i) < cond.Value; i++ { ps = Eyr_EvalBlock(ps, false) ps.Ser.Reset() } ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "eyr\\loop") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "eyr\\loop") } }, }, "to-eyr": { Argsn: 1, Doc: "Evaluates Rye block as Eyr (postfix) stack based code.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: eBlock := env.NewBlock(*env.NewTSeries(make([]env.Object, 0))) evaldo.CompileRyeToEyr(&bloc, ps, eBlock) return *eBlock default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "eyr") } }, }, }
var Builtins_flui = map[string]*env.Builtin{ "select": { Argsn: 1, Doc: "Interactively displays a selection interface for Block, Dict, Table, List, or TableRow. Returns the selected item. Ctrl+C cancels and returns a failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() var obj env.Object var esc bool switch val := arg0.(type) { case env.Block: obj, esc = term.DisplayBlock(val, ps.Idx) case *env.Block: obj, esc = term.DisplayBlock(*val, ps.Idx) case env.Dict: obj, esc = term.DisplayDict(val, ps.Idx) case *env.Dict: obj, esc = term.DisplayDict(*val, ps.Idx) case env.List: bloc := env.NewBlock(*env.NewTSeries(make([]env.Object, len(val.Data)))) for i, item := range val.Data { bloc.Series.S[i] = env.ToRyeValue(item) } obj, esc = term.DisplayBlock(*bloc, ps.Idx) case *env.List: bloc := env.NewBlock(*env.NewTSeries(make([]env.Object, len(val.Data)))) for i, item := range val.Data { bloc.Series.S[i] = env.ToRyeValue(item) } obj, esc = term.DisplayBlock(*bloc, ps.Idx) case env.Table: obj, esc = term.DisplayTable(val, ps.Idx) case *env.Table: obj, esc = term.DisplayTable(*val, ps.Idx) case env.TableRow: obj, esc = term.DisplayTableRow(val, ps.Idx) case *env.TableRow: obj, esc = term.DisplayTableRow(*val, ps.Idx) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.DictType, env.ListType, env.TableType}, "select") } if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj }, }, "input": { Argsn: 1, Doc: "Interactively displays an input field. Takes the max input width, returns the entered string. Ctrl+C cancels and returns a failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch width := arg0.(type) { case env.Integer: obj, esc := term.DisplayInputField(0, int(width.Value)) if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "input") } }, }, "input\\integer": { Argsn: 1, Doc: "Interactive date input in format YYYY-MM-DD. Use arrow keys to navigate between year/month/day fields and increment/decrement values, or type digits. Returns date string. Ctrl+C cancels and returns a failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch initialDate := arg0.(type) { case env.String: obj, esc := term.DisplayIntInput(initialDate.Value, 0) if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "input\\integer") } }, }, "datepicker": { Argsn: 1, Doc: "Interactive date input in format YYYY-MM-DD. Use arrow keys to navigate between year/month/day fields and increment/decrement values, or type digits. Returns date string. Ctrl+C cancels and returns a failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch initialDate := arg0.(type) { case env.String: obj, esc := term.DisplayDateInput(initialDate.Value, 0) if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "datepicker") } }, }, "selectbox": { Argsn: 1, Doc: "Interactive date input in format YYYY-MM-DD. Use arrow keys to navigate between year/month/day fields and increment/decrement values, or type digits. Returns date string. Ctrl+C cancels and returns a failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch options := arg0.(type) { case env.Block: obj, esc := term.DisplaySelection(options, ps.Idx, 0) if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "datepicker") } }, }, "textarea": { Argsn: 2, Doc: "Interactive multiline text input. Takes width and height (number of lines). Use arrow keys to navigate, Enter for new line, Ctrl+D to submit. Returns string with newlines. Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch width := arg0.(type) { case env.Integer: switch height := arg1.(type) { case env.Integer: obj, esc := term.DisplayTextArea(int(width.Value), int(height.Value), "") if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "textarea") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "textarea") } }, }, "textarea\\": { Argsn: 3, Doc: "Interactive multiline text input with initial text. Takes width, height (number of lines), and initial text string. Use arrow keys to navigate, Enter for new line, Ctrl+D to submit. Returns string with newlines. Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.SaveCurPos() switch width := arg1.(type) { case env.Integer: switch height := arg2.(type) { case env.Integer: switch text := arg0.(type) { case env.String: obj, esc := term.DisplayTextArea(int(width.Value), int(height.Value), text.Value) if esc { ps.FailureFlag = true return env.NewError("canceled by user") } return obj default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "textarea\\") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "textarea\\") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "textarea\\") } }, }, "displayx": { Argsn: 1, Doc: "Returns a special !!! prefixed JSON representation of a Block for Flutter UI rendering. The JSON format is [\"block\", [[\"type\", \"value\"], ...]]. Used for interactive display in Flutter clients.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Block: return blockToDisplayJSON(val, ps.Idx) case *env.Block: return blockToDisplayJSON(*val, ps.Idx) case env.List: bloc := env.NewBlock(*env.NewTSeries(make([]env.Object, len(val.Data)))) for i, item := range val.Data { bloc.Series.S[i] = env.ToRyeValue(item) } return blockToDisplayJSON(*bloc, ps.Idx) case *env.List: bloc := env.NewBlock(*env.NewTSeries(make([]env.Object, len(val.Data)))) for i, item := range val.Data { bloc.Series.S[i] = env.ToRyeValue(item) } return blockToDisplayJSON(*bloc, ps.Idx) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.ListType}, "displayx") } }, }, }
var Builtins_flui_v2 = map[string]*env.Builtin{ "select": { Argsn: 1, Doc: "Interactively displays a selection interface. Returns the selected item. Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { items, ok := extractItems(arg0, ps.Idx) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.DictType, env.ListType, env.TableType}, "select") } _, height, termErr := goterm.GetSize(int(os.Stdout.Fd())) if termErr != nil { height = 20 } pageSize := height - 4 term.SaveCurPos() var widget term.Widget if len(items) <= pageSize { widget = term.NewSelectWidget(items, ps.Idx) } else { widget = term.NewPaginatedSelectWidget(items, pageSize, ps.Idx) } result, canceled := term.RunWidget(widget) if canceled { ps.FailureFlag = true return env.NewError("canceled by user") } return result }, }, "input": { Argsn: 1, Doc: "Interactively displays an input field. Takes max width, returns entered string. Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch width := arg0.(type) { case env.Integer: term.SaveCurPos() widget := term.NewInputWidget(int(width.Value), ps.Idx) result, canceled := term.RunWidget(widget) if canceled { ps.FailureFlag = true return env.NewError("canceled by user") } return result default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "input") } }, }, "datepicker": { Argsn: 1, Doc: "Interactive date input. Use arrow keys to navigate/change values, or type digits. Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch initialDate := arg0.(type) { case env.String: term.SaveCurPos() widget := term.NewDateWidget(initialDate.Value, ps.Idx) result, canceled := term.RunWidget(widget) if canceled { ps.FailureFlag = true return env.NewError("canceled by user") } return result default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "datepicker") } }, }, "textarea": { Argsn: 2, Doc: "Interactive multiline text input. Takes width and height. Ctrl+D to submit, Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch width := arg0.(type) { case env.Integer: switch height := arg1.(type) { case env.Integer: term.SaveCurPos() widget := term.NewTextAreaWidget(int(width.Value), int(height.Value), "", ps.Idx) result, canceled := term.RunWidget(widget) if canceled { ps.FailureFlag = true return env.NewError("canceled by user") } return result default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "textarea") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "textarea") } }, }, "textarea\\": { Argsn: 3, Doc: "Interactive multiline text input with initial text. Ctrl+D to submit, Ctrl+C cancels.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch text := arg0.(type) { case env.String: switch width := arg1.(type) { case env.Integer: switch height := arg2.(type) { case env.Integer: term.SaveCurPos() widget := term.NewTextAreaWidget(int(width.Value), int(height.Value), text.Value, ps.Idx) result, canceled := term.RunWidget(widget) if canceled { ps.FailureFlag = true return env.NewError("canceled by user") } return result default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType}, "textarea\\") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "textarea\\") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "textarea\\") } }, }, "displayx": { Argsn: 1, Doc: "Returns a !!! prefixed JSON representation for Flutter UI rendering.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Block: return blockToDisplayJSON(val, ps.Idx) case *env.Block: return blockToDisplayJSON(*val, ps.Idx) case env.List: return blockToDisplayJSON(*listToBlock(val), ps.Idx) case *env.List: return blockToDisplayJSON(*listToBlock(*val), ps.Idx) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.ListType}, "displayx") } }, }, }
var Builtins_goroutines = map[string]*env.Builtin{ "go-with": { Argsn: 2, Doc: "Executes a function in a separate goroutine, passing the specified value as an argument.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch arg := arg0.(type) { case env.Object: switch handler := arg1.(type) { case env.Function: if handler.Argsn != 1 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "function with exactly 1 argument required", "go-with") } psTemp := env.ProgramState{} err := copier.Copy(&psTemp, &ps) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to copy program state: %s", err), "go-with") } psTemp.FailureFlag = false psTemp.ErrorFlag = false psTemp.ReturnFlag = false go func() { defer func() { if r := recover(); r != nil { fmt.Printf("Goroutine panic in go-with: %v\n", r) } }() evaldo.CallFunction_CollectArgs(handler, &psTemp, arg, false, nil) }() return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.FunctionType}, "go-with") } default: ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "First argument should be object type.", "go-with") } }, }, "go": { Argsn: 1, Doc: "Executes a function in a separate goroutine without passing any arguments.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch handler := arg0.(type) { case env.Function: if handler.Argsn != 0 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "function with 0 arguments required", "go") } psTemp := env.ProgramState{} err := copier.Copy(&psTemp, &ps) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to copy program state: %s", err), "go") } psTemp.FailureFlag = false psTemp.ErrorFlag = false psTemp.ReturnFlag = false go func() { defer func() { if r := recover(); r != nil { fmt.Printf("Goroutine panic in go: %v\n", r) } }() evaldo.CallFunction_CollectArgs(handler, &psTemp, nil, false, nil) }() return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.FunctionType}, "go") } }, }, "channel": { Argsn: 1, Doc: "Creates a new channel with the specified buffer size for goroutine communication.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch buflen := arg0.(type) { case env.Integer: if buflen.Value < 0 || int64(int(buflen.Value)) != buflen.Value { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "buffer size must be a non-negative integer representable on this platform", "channel") } ch := make(chan *env.Object, int(buflen.Value)) return *env.NewNative(ps.Idx, ch, "Rye-channel") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "channel") } }, }, "Rye-channel//Read": { Argsn: 1, Doc: "Reads the next value from a channel, blocking until a value is available or the channel is closed.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch chn := arg0.(type) { case env.Native: ch, ok := chn.Value.(chan *env.Object) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Invalid channel type", "Rye-channel//Read") } msg, ok := <-ch if ok { return *msg } else { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "channel closed", "Rye-channel//Read") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-channel//Read") } }, }, "Rye-channel//Send": { Argsn: 2, Doc: "Sends a value through a channel, blocking if the channel is unbuffered or full.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (result env.Object) { defer func() { if r := recover(); r != nil { ps.FailureFlag = true result = *env.NewError("send on closed channel") } }() switch chn := arg0.(type) { case env.Native: ch, ok := chn.Value.(chan *env.Object) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Invalid channel type", "Rye-channel//Send") } ch <- &arg1 return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-channel//Send") } }, }, "Rye-channel//Close": { Argsn: 1, Doc: "Closes a channel, preventing further sends. Buffered values remain readable until the channel is drained.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) (result env.Object) { defer func() { if r := recover(); r != nil { ps.FailureFlag = true result = evaldo.MakeBuiltinError(ps, "channel already closed", "Rye-channel//Close") } }() switch chn := arg0.(type) { case env.Native: ch, ok := chn.Value.(chan *env.Object) if !ok || ch == nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Invalid channel type or nil channel", "Rye-channel//Close") } close(ch) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-channel//Close") } }, }, "mutex": { Argsn: 0, Doc: "Creates a new mutex for synchronizing access to shared resources between goroutines.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { mtx := &RyeMutex{} return *env.NewNative(ps.Idx, mtx, "Rye-mutex") }, }, "waitgroup": { Argsn: 0, Doc: "Creates a new waitgroup for coordinating multiple goroutines to wait for completion.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var wg sync.WaitGroup return *env.NewNative(ps.Idx, &wg, "Rye-waitgroup") }, }, "Rye-mutex//Lock": { Argsn: 1, Doc: "Acquires the lock on a mutex, blocking until the lock becomes available.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch mtx := arg0.(type) { case env.Native: mtx.Value.(*RyeMutex).Lock() return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mutex//Lock") } }, }, "Rye-mutex//Unlock": { Argsn: 1, Doc: "Releases the lock on a mutex, allowing other goroutines to acquire it.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch mtx := arg0.(type) { case env.Native: err := mtx.Value.(*RyeMutex).Unlock() if err != nil { ps.FailureFlag = true return *env.NewError(err.Error()) } return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mutex//Unlock") } }, }, "Rye-waitgroup//Add": { Argsn: 2, Doc: "Adds the specified count to the waitgroup counter, indicating how many goroutines to wait for.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch wg := arg0.(type) { case env.Native: switch count := arg1.(type) { case env.Integer: wg.Value.(*sync.WaitGroup).Add(int(count.Value)) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "Rye-waitgroup//Add") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-waitgroup//Add") } }, }, "Rye-waitgroup//Done": { Argsn: 1, Doc: "Decrements the waitgroup counter by one, indicating that a goroutine has completed.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch wg := arg0.(type) { case env.Native: wg.Value.(*sync.WaitGroup).Done() return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-waitgroup//Done") } }, }, "Rye-waitgroup//Wait": { Argsn: 1, Doc: "Blocks until the waitgroup counter reaches zero, meaning all goroutines have completed.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch wg := arg0.(type) { case env.Native: wg.Value.(*sync.WaitGroup).Wait() return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-waitgroup//Wait") } }, }, "select\\fn": { Argsn: 1, Doc: "Selects a channel or default function and returns its result. Selecting a drained closed channel fails without calling a handler.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return runChannelSelect(ps, arg0, true) }, }, "select": { Argsn: 1, Doc: "Selects a channel or default block and returns its result. Selecting a drained closed channel fails without running a handler.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return runChannelSelect(ps, arg0, false) }, }, }
var Builtins_gpio = map[string]*env.Builtin{}
var Builtins_html = map[string]*env.Builtin{ "unescape\\html": { Argsn: 1, Doc: "Converts HTML entities to their character equivalents.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "unescape\\html") } mkd := html.UnescapeString(text.Value) return *env.NewString(mkd) }, }, "escape\\html": { Argsn: 1, Doc: "Converts special characters to HTML entities.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "unescape\\html") } mkd := html.EscapeString(text.Value) return *env.NewString(mkd) }, }, "html->markdown": { Argsn: 1, Doc: "Converts HTML text to markdown format.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "html->markdown") } mkd, err := htmltomarkdown.ConvertString(text.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "html->markdown") } return *env.NewString(mkd) }, }, "reader//Parse-html": { Argsn: 2, Doc: "Parses HTML using a streaming approach with tag handlers.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { rm, err := load_html_Dict(ps, arg1.(env.Block)) trace8("*** _--- GOT RM ++**") if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error to load html dict.", "reader//parse-html") } return do_html(ps, arg0.(env.Native).Value.(io.Reader), rm) }, }, "rye-html-start//Attr?": { Argsn: 2, Doc: "Retrieves an attribute value by name or index from an HTML element.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch tok1 := arg0.(type) { case env.Native: switch tok := tok1.Value.(type) { case html.Token: switch n := arg1.(type) { case env.Integer: if int(n.Value) < len(tok.Attr) { return *env.NewString(tok.Attr[int(n.Value)].Val) } else { return evaldo.MakeBuiltinError(ps, "Attribute index out of bounds.", "rye-html-start//Attr?") } case env.Word: attrName := ps.Idx.GetWord(n.Index) for _, a := range tok.Attr { if a.Key == attrName { return *env.NewString(a.Val) } } return evaldo.MakeBuiltinError(ps, "Attribute '"+attrName+"' not found.", "rye-html-start//Attr?") case env.String: attrName := n.Value for _, a := range tok.Attr { if a.Key == attrName { return *env.NewString(a.Val) } } return evaldo.MakeBuiltinError(ps, "Attribute '"+attrName+"' not found.", "rye-html-start//Attr?") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.WordType, env.StringType}, "rye-html-start//Attr?") } default: return evaldo.MakeBuiltinError(ps, "Token value is not matching.", "rye-html-start//Attr?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "rye-html-start//Attr?") } }, }, "rye-html-start//Attrs?": { Argsn: 1, Doc: "Returns a dict of all attributes from an HTML element.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch tok1 := arg0.(type) { case env.Native: switch tok := tok1.Value.(type) { case html.Token: data := make(map[string]any) for _, attr := range tok.Attr { data[attr.Key] = *env.NewString(attr.Val) } return *env.NewDict(data) default: return evaldo.MakeBuiltinError(ps, "Token value is not matching.", "rye-html-start//Attrs?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "rye-html-start//Attrs?") } }, }, "rye-html-start//Name?": { Argsn: 1, Doc: "Returns the name of an HTML element.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch tok1 := arg0.(type) { case env.Native: switch tok := tok1.Value.(type) { case html.Token: return *env.NewString(tok.Data) default: return evaldo.MakeBuiltinError(ps, "Not xml-start element.", "rye-html-start//Name?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "rye-html-start//Name?") } }, }, }
var Builtins_imap = map[string]*env.Builtin{ "imap-uri//Open": { Argsn: 1, Doc: "Opens an IMAP client connection. URI format: imap[s]://user[:pass]@host[:port][/mailbox].", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch uri := arg0.(type) { case env.Uri: scheme := ps.Idx.GetWord(uri.Scheme.Index) parsed, err := parseIMAPURI(scheme, uri.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "imap-uri//Open") } return imapNewClient(ps, parsed, "", "", "password", "imap-uri//Open") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "imap-uri//Open") } }, }, "imap-uri//Open\\pwd": { Argsn: 2, Doc: "Opens an IMAP client connection with a separate password parameter.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch uri := arg0.(type) { case env.Uri: switch password := arg1.(type) { case env.String: scheme := ps.Idx.GetWord(uri.Scheme.Index) parsed, err := parseIMAPURI(scheme, uri.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "imap-uri//Open\\pwd") } return imapNewClient(ps, parsed, password.Value, "", "password", "imap-uri//Open\\pwd") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-uri//Open\\pwd") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "imap-uri//Open\\pwd") } }, }, "imap-uri//Open\\oauth2": { Argsn: 2, Doc: "Opens an IMAP client connection with OAuth2 (XOAUTH2/OAUTHBEARER) authentication.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch uri := arg0.(type) { case env.Uri: switch token := arg1.(type) { case env.String: scheme := ps.Idx.GetWord(uri.Scheme.Index) parsed, err := parseIMAPURI(scheme, uri.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "imap-uri//Open\\oauth2") } return imapNewClient(ps, parsed, "", token.Value, "oauth2", "imap-uri//Open\\oauth2") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-uri//Open\\oauth2") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "imap-uri//Open\\oauth2") } }, }, "imap-client": { Argsn: 4, Doc: "Create an IMAP client connection with username, password, server, and port.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch username := arg0.(type) { case env.String: switch password := arg1.(type) { case env.String: switch server := arg2.(type) { case env.String: switch port := arg3.(type) { case env.Integer: parsed := &imapURI{ user: username.Value, password: password.Value, host: server.Value, port: int(port.Value), implicitTLS: int(port.Value) == 993, } return imapNewClient(ps, parsed, "", "", "password", "imap-client") default: return evaldo.MakeArgError(ps, 4, []env.Type{env.IntegerType}, "imap-client") } default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "imap-client") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-client") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "imap-client") } }, }, "imap-client\\oauth2": { Argsn: 4, Doc: "Create an IMAP client connection with OAuth2 authentication (email, access_token, server, port).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch email := arg0.(type) { case env.String: switch token := arg1.(type) { case env.String: switch server := arg2.(type) { case env.String: switch port := arg3.(type) { case env.Integer: parsed := &imapURI{ user: email.Value, host: server.Value, port: int(port.Value), implicitTLS: int(port.Value) == 993, } return imapNewClient(ps, parsed, "", token.Value, "oauth2", "imap-client\\oauth2") default: return evaldo.MakeArgError(ps, 4, []env.Type{env.IntegerType}, "imap-client\\oauth2") } default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "imap-client\\oauth2") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-client\\oauth2") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "imap-client\\oauth2") } }, }, "imap-client//Select-folder": { Argsn: 2, Doc: "Selects a folder for IMAP operations (e.g., 'INBOX').", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Select-folder") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Select-folder") } switch folder := arg1.(type) { case env.String: if _, err := client.Select(folder.Value, nil).Wait(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to select folder: %s", err), "imap-client//Select-folder") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-client//Select-folder") } }, }, "imap-client//Get-folders": { Argsn: 1, Doc: "Gets the list of available folders.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Get-folders") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Get-folders") } mailboxes, err := client.List("", "*", nil).Collect() if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to get folders: %s", err), "imap-client//Get-folders") } result := make([]env.Object, len(mailboxes)) for i, mailbox := range mailboxes { result[i] = *env.NewString(mailbox.Mailbox) } return *env.NewBlock(*env.NewTSeries(result)) }, }, "imap-client//Mailbox-info": { Argsn: 1, Doc: "Gets information about the currently selected folder.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Mailbox-info") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Mailbox-info") } info, err := imapMailboxInfo(client) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "imap-client//Mailbox-info") } return info }, }, "imap-client//Search-emails": { Argsn: 2, Doc: "Searches for emails using IMAP search criteria and returns matching UIDs.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Search-emails") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Search-emails") } switch criteriaValue := arg1.(type) { case env.String: criteria, err := imapParseSearch(criteriaValue.Value) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("invalid search criteria: %s", err), "imap-client//Search-emails") } data, err := client.UIDSearch(criteria, nil).Wait() if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("search failed: %s", err), "imap-client//Search-emails") } uids := data.AllUIDs() result := make([]env.Object, len(uids)) for i, uid := range uids { result[i] = *env.NewInteger(int64(uid)) } return *env.NewBlock(*env.NewTSeries(result)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "imap-client//Search-emails") } }, }, "imap-client//Get-overviews": { Argsn: 2, Doc: "Gets email overviews (headers only, fast) for a block of UIDs.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Get-overviews") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Get-overviews") } switch uidBlock := arg1.(type) { case env.Block: uids, argErr := imapUIDsFromBlock(ps, uidBlock, "imap-client//Get-overviews") if argErr != nil { return argErr } overviews, err := imapFetchOverviews(client, uids) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to get overviews: %s", err), "imap-client//Get-overviews") } return *env.NewBlock(*env.NewTSeries(overviews)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "imap-client//Get-overviews") } }, }, "imap-client//Get-emails": { Argsn: 2, Doc: "Gets full emails with bodies and attachments (slower) for a block of UIDs.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Get-emails") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Get-emails") } switch uidBlock := arg1.(type) { case env.Block: uids, argErr := imapUIDsFromBlock(ps, uidBlock, "imap-client//Get-emails") if argErr != nil { return argErr } emails, err := imapFetchEmails(client, uids) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to get emails: %s", err), "imap-client//Get-emails") } return *env.NewBlock(*env.NewTSeries(emails)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "imap-client//Get-emails") } }, }, "imap-client//Get-raw-emails": { Argsn: 2, Doc: "Gets complete raw RFC 822 messages for a block of UIDs.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Get-raw-emails") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Get-raw-emails") } switch uidBlock := arg1.(type) { case env.Block: uids, argErr := imapUIDsFromBlock(ps, uidBlock, "imap-client//Get-raw-emails") if argErr != nil { return argErr } emails, err := imapFetchRawEmails(client, uids) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to get raw emails: %s", err), "imap-client//Get-raw-emails") } return *env.NewBlock(*env.NewTSeries(emails)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "imap-client//Get-raw-emails") } }, }, "imap-client//Mark-seen": { Argsn: 2, Doc: "Marks an email as read/seen by UID.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Mark-seen") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Mark-seen") } switch uid := arg1.(type) { case env.Integer: cmd := client.Store(imap.UIDSetNum(imap.UID(uid.Value)), &imap.StoreFlags{ Op: imap.StoreFlagsAdd, Silent: true, Flags: []imap.Flag{imap.FlagSeen}, }, nil) if err := cmd.Close(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to mark email as seen: %s", err), "imap-client//Mark-seen") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "imap-client//Mark-seen") } }, }, "imap-client//Move-email": { Argsn: 3, Doc: "Moves an email to another folder by UID.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Move-email") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Move-email") } switch uid := arg1.(type) { case env.Integer: switch folder := arg2.(type) { case env.String: if _, err := client.Move(imap.UIDSetNum(imap.UID(uid.Value)), folder.Value).Wait(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to move email: %s", err), "imap-client//Move-email") } return arg0 default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "imap-client//Move-email") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "imap-client//Move-email") } }, }, "imap-client//Delete-email": { Argsn: 2, Doc: "Marks an email for deletion by UID (use expunge to permanently delete).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Delete-email") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Delete-email") } switch uid := arg1.(type) { case env.Integer: cmd := client.Store(imap.UIDSetNum(imap.UID(uid.Value)), &imap.StoreFlags{ Op: imap.StoreFlagsAdd, Silent: true, Flags: []imap.Flag{imap.FlagDeleted}, }, nil) if err := cmd.Close(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to delete email: %s", err), "imap-client//Delete-email") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "imap-client//Delete-email") } }, }, "imap-client//Expunge": { Argsn: 1, Doc: "Permanently removes emails marked for deletion.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Expunge") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Expunge") } if err := client.Expunge().Close(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to expunge: %s", err), "imap-client//Expunge") } return arg0 }, }, "imap-client//Close": { Argsn: 1, Doc: "Logs out and closes the IMAP client connection.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { client, ok := imapClientFrom(arg0) if !ok { if _, native := arg0.(env.Native); native { return evaldo.MakeBuiltinError(ps, "Expected imap-client", "imap-client//Close") } return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "imap-client//Close") } _ = client.Logout().Wait() if err := client.Close(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("failed to close connection: %s", err), "imap-client//Close") } return env.Void{} }, }, }
var Builtins_js_interop = map[string]*env.Builtin{}
JavaScript interop functions for Rye WASM
var Builtins_json = map[string]*env.Builtin{ "parse-json": { Argsn: 1, Doc: "Parses JSON string into Rye values.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch input := arg0.(type) { case env.String: var m any err := json.Unmarshal([]byte(input.Value), &m) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to Unmarshal.", "_parse_json") } return env.ToRyeValue(m) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "_parse_json") } }, }, "parse-json\\lines": { Argsn: 1, Doc: "Parses JSON string into Rye values.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch input := arg0.(type) { case env.String: var vals []any decoder := json.NewDecoder(strings.NewReader(input.Value)) for decoder.More() { var m any err := decoder.Decode(&m) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to Unmarshal.", "_parse_json\\lines") } vals = append(vals, env.ToRyeValue(m)) } return *env.NewList(vals) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "_parse_json\\lines") } }, }, "to-json": { Argsn: 1, Doc: "Converts a Rye value to a JSON string. Supports block (like list) and context (like dict).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(RyeToJSONWithIdxs(arg0, ps.Idx)) }, }, "to-json\\lines": { Argsn: 1, Doc: "Converts a table to JSON with each row on a separate line.", Fn: func(es *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(RyeToJSONLines(arg0)) }, }, }
var Builtins_mail = map[string]*env.Builtin{ "reader//Parse-email": { Argsn: 1, Doc: "Parses email data from a reader.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch reader := arg0.(type) { case env.Native: email, err := parsemail.Parse(reader.Value.(io.Reader)) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "reader//parse-email") } return *env.NewNative(ps.Idx, email, "parsed-email") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "reader//parse-email") } }, }, "parsed-email//Subject?": { Argsn: 1, Doc: "Gets the subject from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch email := arg0.(type) { case env.Native: return *env.NewString(email.Value.(parsemail.Email).Subject) default: return *evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "parsed-email//Subject?") } }, }, "parsed-email//Message-id?": { Argsn: 1, Doc: "Gets the message ID from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch email := arg0.(type) { case env.Native: return *env.NewString(email.Value.(parsemail.Email).MessageID) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "parsed-email//message-id?") } }, }, "parsed-email//Html-body?": { Argsn: 1, Doc: "Gets the HTML body from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch email := arg0.(type) { case env.Native: return *env.NewString(email.Value.(parsemail.Email).HTMLBody) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "parsed-email//html-body?") } }, }, "parsed-email//Text-body?": { Argsn: 1, Doc: "Gets the plain text body from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch email := arg0.(type) { case env.Native: return *env.NewString(email.Value.(parsemail.Email).TextBody) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "parsed-email//text-body?") } }, }, "parsed-email//Attachments?": { Argsn: 1, Doc: "Gets the attachments from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, arg0, "smtpd") }, }, "parsed-email//Embedded-files?": { Argsn: 1, Doc: "Gets the embedded files from a parsed email.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, arg0, "smtpd") }, }, }
var Builtins_match = map[string]*env.Builtin{ "match-block": { Argsn: 2, Doc: "Tries to match and deconstruct a value into multiple values, with support for literal values, type checking, get-words, code evaluation, and nested blocks. First argument can be any value. If it doesn't match, returns failure.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { value := arg0 // Convert value to a block if it's not already var valueBlock env.Block switch v := value.(type) { case env.Block: valueBlock = v default: valueBlock = env.Block{ Series: *env.NewTSeries([]env.Object{value}), } } switch pattern := arg1.(type) { case env.Block: return matchBlock(ps, valueBlock, pattern) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "match-block") } }, }, "match": { Argsn: 2, Doc: "Matches a value against a series of pattern/action pairs. Pattern can be a single element or block. Returns the result of the first matching action, or failure if none match.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { value := arg0 switch patternsBlock := arg1.(type) { case env.Block: if patternsBlock.Series.Len()%2 != 0 { return evaldo.MakeBuiltinError(ps, "Patterns block must contain an even number of elements (pairs)", "match") } for i := 0; i < patternsBlock.Series.Len(); i += 2 { pattern := patternsBlock.Series.Get(i) action := patternsBlock.Series.Get(i + 1) actionBlock, actionOk := action.(env.Block) if !actionOk { return evaldo.MakeBuiltinError(ps, "Action must be a block", "match") } oldFailureFlag := ps.FailureFlag ps.FailureFlag = false matchResult, _ := matchValue(ps, value, pattern, matchMode{0}) if !ps.FailureFlag { ps.FailureFlag = oldFailureFlag ser := ps.Ser ps.Ser = actionBlock.Series evaldo.EvalBlockInj(ps, value, true) ps.Ser = ser return ps.Res } ps.FailureFlag = oldFailureFlag _ = matchResult } ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "No pattern matched the value", "match") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "match") } }, }, }
var Builtins_math = map[string]*env.Builtin{ "mod": { Argsn: 2, Doc: "Returns the remainder of dividing x by y.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fa, fb, errPos := assureFloats(arg0, arg1) if errPos > 0 { return evaldo.MakeArgError(ps, errPos, []env.Type{env.IntegerType, env.BlockType}, "mod") } return *env.NewDecimal(math.Mod(fa, fb)) }, }, "pow": { Argsn: 2, Doc: "Returns base raised to the power of exponent.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch base := arg0.(type) { case env.Complex: switch exp := arg1.(type) { case env.Complex: return *env.NewComplex(cmplx.Pow(base.Value, exp.Value)) case env.Integer: return *env.NewComplex(cmplx.Pow(base.Value, complex(float64(exp.Value), 0))) case env.Decimal: return *env.NewComplex(cmplx.Pow(base.Value, complex(exp.Value, 0))) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "pow") } case env.Integer: switch exp := arg1.(type) { case env.Complex: return *env.NewComplex(cmplx.Pow(complex(float64(base.Value), 0), exp.Value)) case env.Integer: return *env.NewDecimal(math.Pow(float64(base.Value), float64(exp.Value))) case env.Decimal: return *env.NewDecimal(math.Pow(float64(base.Value), exp.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "pow") } case env.Decimal: switch exp := arg1.(type) { case env.Complex: return *env.NewComplex(cmplx.Pow(complex(base.Value, 0), exp.Value)) case env.Integer: return *env.NewDecimal(math.Pow(base.Value, float64(exp.Value))) case env.Decimal: return *env.NewDecimal(math.Pow(base.Value, exp.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "pow") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "pow") } }, }, "log2": { Argsn: 1, Doc: "Returns the binary logarithm (base-2) of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Log2(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Log2(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.BlockType}, "log2") } }, }, "log10": { Argsn: 1, Doc: "Returns the decimal logarithm (base-10) of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Log10(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Log10(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "log10") } }, }, "log": { Argsn: 1, Doc: "Returns the natural logarithm of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: if val.Value <= 0 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Can't compute logarithm of zero or negative number.", "log") } return *env.NewDecimal(math.Log(float64(val.Value))) case env.Decimal: if val.Value <= 0 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Can't compute logarithm of zero or negative number.", "log") } return *env.NewDecimal(math.Log(val.Value)) case env.Complex: if val.Value == complex(0, 0) { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Can't compute logarithm of zero.", "log") } return *env.NewComplex(cmplx.Log(val.Value)) case env.Vector: data := make(govector.Vector, len(val.Value)) for i, v := range val.Value { data[i] = math.Log(v) } return *env.NewVector(data) case env.Matrix: data := make([]float64, len(val.Data)) for i, v := range val.Data { data[i] = math.Log(v) } return *env.NewMatrixWithData(val.Rows, val.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType, env.VectorType, env.MatrixType}, "log") } }, }, "log1p": { Argsn: 1, Doc: "Returns the natural logarithm of 1 plus its argument x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Log1p(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Log1p(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "log1p") } }, }, "logb": { Argsn: 1, Doc: "Returns the binary exponent of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Logb(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Logb(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "logb") } }, }, "sq": { Argsn: 1, Doc: "Returns the square of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Pow(float64(val.Value), 2.0)) case env.Decimal: return *env.NewDecimal(math.Pow(val.Value, 2.0)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.BlockType}, "sq") } }, }, "sin": { Argsn: 1, Doc: "Returns the sine of the radian argument.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Sin(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Sin(val.Value)) case env.Complex: return *env.NewComplex(cmplx.Sin(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "sin") } }, }, "cos": { Argsn: 1, Doc: "Returns the cosine of the radian argument.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Cos(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Cos(val.Value)) case env.Complex: return *env.NewComplex(cmplx.Cos(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "cos") } }, }, "tan": { Argsn: 1, Doc: "Returns the tangent of the radian argument.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Tan(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Tan(val.Value)) case env.Complex: return *env.NewComplex(cmplx.Tan(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType}, "tan") } }, }, "sqrt": { Argsn: 1, Doc: "Returns the square root of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Sqrt(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Sqrt(val.Value)) case env.Complex: return *env.NewComplex(cmplx.Sqrt(val.Value)) case env.Vector: data := make(govector.Vector, len(val.Value)) for i, v := range val.Value { data[i] = math.Sqrt(v) } return *env.NewVector(data) case env.Matrix: data := make([]float64, len(val.Data)) for i, v := range val.Data { data[i] = math.Sqrt(v) } return *env.NewMatrixWithData(val.Rows, val.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType, env.VectorType, env.MatrixType}, "sqrt") } }, }, "abs": { Argsn: 1, Doc: "Returns the absolute value of a number.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewInteger(int64(math.Abs(float64(val.Value)))) case env.Decimal: return *env.NewDecimal(math.Abs(val.Value)) case env.Complex: return *env.NewDecimal(cmplx.Abs(val.Value)) case env.Vector: data := make(govector.Vector, len(val.Value)) for i, v := range val.Value { data[i] = math.Abs(v) } return *env.NewVector(data) case env.Matrix: data := make([]float64, len(val.Data)) for i, v := range val.Data { data[i] = math.Abs(v) } return *env.NewMatrixWithData(val.Rows, val.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType, env.VectorType, env.MatrixType}, "abs") } }, }, "acos": { Argsn: 1, Doc: "Returns the arccosine (inverse cosine) in radians.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: if val.Value < -1.0 || val.Value > 1.0 { return evaldo.MakeBuiltinError(ps, "Invalid input: Acos is only defined for -1 <= x <= 1.", "acos") } return *env.NewDecimal(math.Acos(float64(val.Value))) case env.Decimal: if val.Value < -1.0 || val.Value > 1.0 { return evaldo.MakeBuiltinError(ps, "Invalid input: Acos is only defined for -1 <= x <= 1.", "acos") } return *env.NewDecimal(math.Acos(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "acos") } }, }, "acosh": { Argsn: 1, Doc: "Returns the inverse hyperbolic cosine.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: if val.Value < 1.0 { return evaldo.MakeBuiltinError(ps, " Acosh is only defined for x >= 1.", "acosh") } return *env.NewDecimal(math.Log(float64(val.Value) + math.Sqrt(float64(val.Value)*float64(val.Value)-1))) case env.Decimal: if val.Value < 1.0 { return evaldo.MakeBuiltinError(ps, " Acosh is only defined for x >= 1.", "acosh") } return *env.NewDecimal(math.Log(val.Value + math.Sqrt(val.Value*val.Value-1))) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "acosh") } }, }, "asin": { Argsn: 1, Doc: "Returns the arcsine (inverse sine) in radians.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: if val.Value < -1.0 || val.Value > 1.0 { return evaldo.MakeBuiltinError(ps, "Invalid input: Asin is only defined for -1 <= x <= 1.", "asin") } return *env.NewDecimal(math.Asin(float64(val.Value))) case env.Decimal: if val.Value < -1.0 || val.Value > 1.0 { return evaldo.MakeBuiltinError(ps, "Invalid input: Asin is only defined for -1 <= x <= 1.", "asin") } return *env.NewDecimal(math.Asin(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "asin") } }, }, "asinh": { Argsn: 1, Doc: "Returns the inverse hyperbolic sine.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Log(float64(val.Value) + math.Sqrt(float64(val.Value)*float64(val.Value)+1))) case env.Decimal: return *env.NewDecimal(math.Log(val.Value + math.Sqrt(val.Value*val.Value+1))) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "asinh") } }, }, "atan": { Argsn: 1, Doc: "Returns the arctangent (inverse tangent) in radians.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Atan(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Atan(val.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "atan") } }, }, "atan2": { Argsn: 2, Doc: "Returns the arc tangent of y/x, using the signs of the two to determine the quadrant of the return value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Atan2(float64(val.Value), float64(val2.Value))) case env.Decimal: return *env.NewDecimal(math.Atan2(float64(val.Value), val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "atan2") } case env.Decimal: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Atan2(val.Value, float64(val2.Value))) case env.Decimal: return *env.NewDecimal(math.Atan2(val.Value, val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "atan2") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "atan2") } }, }, "atanh": { Argsn: 1, Doc: "Returns the inverse hyperbolic tangent.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Atanh(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Atanh(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "atanh") } }, }, "ceil": { Argsn: 1, Doc: "Returns the least integer value greater than or equal to x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(float64(val.Value)) case env.Decimal: return *env.NewDecimal(math.Ceil(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "ceil") } }, }, "cbrt": { Argsn: 1, Doc: "Returns the cube root of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Cbrt(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Cbrt(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "cbrt") } }, }, "copysign": { Argsn: 2, Doc: "Returns a value with the magnitude of x and the sign of y.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Copysign(float64(val.Value), float64(val2.Value))) case env.Decimal: return *env.NewDecimal(math.Copysign(float64(val.Value), val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "copysign") } case env.Decimal: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Copysign(val.Value, float64(val2.Value))) case env.Decimal: return *env.NewDecimal(math.Copysign(val.Value, val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "copysign") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "copysign") } }, }, "dim": { Argsn: 2, Doc: "Returns the maximum of x-y or 0.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(util.GetDimValue(float64(val.Value), float64(val2.Value))) case env.Decimal: return *env.NewDecimal(util.GetDimValue(float64(val.Value), val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "dim") } case env.Decimal: switch val2 := arg1.(type) { case env.Integer: return *env.NewDecimal(util.GetDimValue(val.Value, float64(val2.Value))) case env.Decimal: return *env.NewDecimal(util.GetDimValue(val.Value, val2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "dim") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "dim") } }, }, "round\\to": { Argsn: 2, Doc: "Rounds a decimal to the specified number of decimal places.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Decimal: switch precision := arg1.(type) { case env.Integer: ratio := math.Pow(10, float64(precision.Value)) return *env.NewDecimal(math.Round(val.Value*ratio) / ratio) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "round\\to") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.DecimalType}, "round\\to") } }, }, "round": { Argsn: 1, Doc: "Rounds a decimal to the nearest integer.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Decimal: return *env.NewDecimal(math.Round(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.DecimalType}, "round\\to") } }, }, "roundtoeven": { Argsn: 1, Doc: "Returns the nearest integer, rounding ties to even.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Decimal: return *env.NewDecimal(math.RoundToEven(val.Value)) case env.Integer: return *env.NewDecimal(math.RoundToEven(float64(val.Value))) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.DecimalType, env.IntegerType}, "roundtoeven") } }, }, "erf": { Argsn: 1, Doc: "Returns the error function of value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Erf(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Erf(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "erf") } }, }, "erfc": { Argsn: 1, Doc: "Returns the complementary error function of value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Erfc(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Erfc(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "erfc") } }, }, "erfcinv": { Argsn: 1, Doc: "Returns the inverse of erfc(x) function.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Erfcinv(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Erfcinv(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "erfcinv") } }, }, "erfinv": { Argsn: 1, Doc: "Returns the inverse error function of value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Erfinv(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Erfinv(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "erfinv") } }, }, "exp": { Argsn: 1, Doc: "Returns e**x, the base-e exponential of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Exp(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Exp(val.Value)) case env.Complex: return *env.NewComplex(cmplx.Exp(val.Value)) case env.Vector: data := make(govector.Vector, len(val.Value)) for i, v := range val.Value { data[i] = math.Exp(v) } return *env.NewVector(data) case env.Matrix: data := make([]float64, len(val.Data)) for i, v := range val.Data { data[i] = math.Exp(v) } return *env.NewMatrixWithData(val.Rows, val.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType, env.ComplexType, env.VectorType, env.MatrixType}, "exp") } }, }, "exp2": { Argsn: 1, Doc: "Returns 2**x, the base-2 exponential of x.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Exp2(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Exp2(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "exp2") } }, }, "expm1": { Argsn: 1, Doc: "Returns e**x - 1, the base-e exponential of x minus 1. It is more accurate than exp(x) - 1 when x is near zero.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Expm1(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Expm1(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "expm1") } }, }, "fma": { Argsn: 3, Doc: "Returns x * y + z, computed with only one rounding. (That is, FMA returns the fused multiply-add of x, y, and z.)", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val1 := arg0.(type) { case env.Integer: switch val2 := arg1.(type) { case env.Integer: switch val3 := arg2.(type) { case env.Integer: return *env.NewDecimal(math.FMA(float64(val1.Value), float64(val2.Value), float64(val3.Value))) case env.Decimal: return *env.NewDecimal(math.FMA(float64(val1.Value), float64(val2.Value), val3.Value)) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType, env.DecimalType}, "fma") } case env.Decimal: switch val3 := arg2.(type) { case env.Integer: return *env.NewDecimal(math.FMA(float64(val1.Value), val2.Value, float64(val3.Value))) case env.Decimal: return *env.NewDecimal(math.FMA(float64(val1.Value), val2.Value, val3.Value)) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType, env.DecimalType}, "fma") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "fma") } case env.Decimal: switch val2 := arg1.(type) { case env.Integer: switch val3 := arg2.(type) { case env.Integer: return *env.NewDecimal(math.FMA(val1.Value, float64(val2.Value), float64(val3.Value))) case env.Decimal: return *env.NewDecimal(math.FMA(val1.Value, float64(val2.Value), val3.Value)) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType, env.DecimalType}, "fma") } case env.Decimal: switch val3 := arg2.(type) { case env.Integer: return *env.NewDecimal(math.FMA(val1.Value, val2.Value, float64(val3.Value))) case env.Decimal: return *env.NewDecimal(math.FMA(val1.Value, val2.Value, val3.Value)) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType, env.DecimalType}, "fma") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "fma") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "fma") } }, }, "j0": { Argsn: 1, Doc: "Returns the order-zero Bessel function of the first kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.J0(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.J0(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "j0") } }, }, "j1": { Argsn: 1, Doc: "Returns the order-one Bessel function of the first kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.J1(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.J1(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "j1") } }, }, "y0": { Argsn: 1, Doc: "Returns the order-zero Bessel function of the second kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Y0(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Y0(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "y0") } }, }, "y1": { Argsn: 1, Doc: "Returns the order-one Bessel function of the second kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(math.Y1(float64(val.Value))) case env.Decimal: return *env.NewDecimal(math.Y1(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "y1") } }, }, "yn": { Argsn: 2, Doc: "Returns the order-n Bessel function of the second kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Integer: switch v2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Yn(int(v1.Value), float64(v2.Value))) case env.Decimal: return *env.NewDecimal(math.Yn(int(v1.Value), v2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "yn") } case env.Decimal: switch v2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Yn(int(v1.Value), float64(v2.Value))) case env.Decimal: return *env.NewDecimal(math.Yn(int(v1.Value), v2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "yn") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "yn") } }, }, "jn": { Argsn: 2, Doc: "Returns the order-n Bessel function of the first kind.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Integer: switch v2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Jn(int(v1.Value), float64(v2.Value))) case env.Decimal: return *env.NewDecimal(math.Jn(int(v1.Value), v2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "jn") } case env.Decimal: switch v2 := arg1.(type) { case env.Integer: return *env.NewDecimal(math.Jn(int(v1.Value), float64(v2.Value))) case env.Decimal: return *env.NewDecimal(math.Jn(int(v1.Value), v2.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.DecimalType}, "jn") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "jn") } }, }, "trunc": { Argsn: 1, Doc: "Returns the integer value of input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: return *env.NewDecimal(float64(val.Value)) case env.Decimal: return *env.NewDecimal(math.Trunc(val.Value)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "trunc") } }, }, "pi": { Argsn: 0, Doc: "Returns the mathematical constant π (pi).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewDecimal(float64(math.Pi)) }, }, "deg->rad": { Argsn: 1, Doc: "Converts degrees to radians.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var fa float64 switch a := arg0.(type) { case env.Decimal: fa = a.Value case env.Integer: fa = float64(a.Value) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.DecimalType}, "deg->rad") } return *env.NewDecimal(fa * float64(math.Pi) / 180.0) }, }, "is-near": { Argsn: 2, Doc: "Returns true if two decimals are close.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fa, fb, errPos := assureFloats(arg0, arg1) if errPos > 0 { return evaldo.MakeArgError(ps, errPos, []env.Type{env.IntegerType, env.BlockType}, "is-near") } const epsilon = 0.0000000000001 // math.SmallestNonzeroFloat64 if math.Abs(fa-fb) <= (epsilon) { return env.NewBoolean(true) } else { return env.NewBoolean(false) } }, }, "near-zero": { Argsn: 1, Doc: "Returns true if a decimal is close to zero.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var fa float64 switch a := arg0.(type) { case env.Decimal: fa = a.Value case env.Integer: fa = float64(a.Value) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType, env.BlockType}, "near-zero") } // const epsilon = math.SmallestNonzeroFloat64 const epsilon = 0.0000000000001 // math.SmallestNonzeroFloat64 if math.Abs(fa) <= epsilon { return env.NewBoolean(true) } else { return env.NewBoolean(false) } }, }, "is-prime": { Argsn: 1, Doc: "Returns true if the integer is a prime number.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Integer: if val.Value <= 1 { return *env.NewBoolean(false) } if primes.IsPrime(int(val.Value)) { return *env.NewBoolean(true) } else { return *env.NewBoolean(false) } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "is-prime") } }, }, "to-eyr": { Argsn: 1, Doc: "Converts math dialect to Eyr dialect.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return DialectMath(ps, arg0) }, }, "calc": { Argsn: 1, Doc: "Evaluates expressions in math dialect.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { res := DialectMath(ps, arg0) switch block := res.(type) { case env.Block: ps.ResetStack() ser := ps.Ser ps.Ser = block.Series Eyr_EvalBlock(ps, false) ps.Ser = ser return ps.Res default: return res } }, }, "gcd": { Argsn: 2, Doc: "Returns the greatest common divisor of two integers using Euclidean algorithm.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val1 := arg0.(type) { case env.Integer: switch val2 := arg1.(type) { case env.Integer: a := val1.Value b := val2.Value if a < 0 { a = -a } if b < 0 { b = -b } for b != 0 { temp := b b = a % b a = temp } return *env.NewInteger(a) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "gcd") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "gcd") } }, }, "outer-product": { Argsn: 2, Doc: "Computes the outer product of two vectors (blocks), returning a matrix (block of blocks) where each element [i,j] = a[i] * b[j]. Similar to numpy.outer().", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch vec1 := arg0.(type) { case env.Block: switch vec2 := arg1.(type) { case env.Block: result := make([]env.Object, vec1.Series.Len()) for i := 0; i < vec1.Series.Len(); i++ { val1 := vec1.Series.Get(i) var f1 float64 var isDecimal1 bool switch v1 := val1.(type) { case env.Integer: f1 = float64(v1.Value) isDecimal1 = false case env.Decimal: f1 = v1.Value isDecimal1 = true default: return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Element at position %d in first block must be integer or decimal", i), "outer-product") } row := make([]env.Object, vec2.Series.Len()) for j := 0; j < vec2.Series.Len(); j++ { val2 := vec2.Series.Get(j) var f2 float64 var isDecimal2 bool switch v2 := val2.(type) { case env.Integer: f2 = float64(v2.Value) isDecimal2 = false case env.Decimal: f2 = v2.Value isDecimal2 = true default: return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Element at position %d in second block must be integer or decimal", j), "outer-product") } product := f1 * f2 if isDecimal1 || isDecimal2 { row[j] = *env.NewDecimal(product) } else { row[j] = *env.NewInteger(int64(product)) } } result[i] = *env.NewBlock(*env.NewTSeries(row)) } return *env.NewBlock(*env.NewTSeries(result)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "outer-product") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "outer-product") } }, }, }
var Builtins_matrix = map[string]*env.Builtin{ "matrix\\zeros": { Argsn: 2, Doc: "Creates a new matrix with the given dimensions, initialized to zeros.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch rows := arg0.(type) { case env.Integer: switch cols := arg1.(type) { case env.Integer: if rows.Value <= 0 || cols.Value <= 0 { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must be positive", "matrix") } return *env.NewMatrix(int(rows.Value), int(cols.Value)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "matrix") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "matrix") } }, }, "matrix": { Argsn: 2, Doc: "Creates a matrix from a shape block and a data block.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch shape := arg0.(type) { case env.Block: if shape.Series.Len() != 2 { return evaldo.MakeBuiltinError(ps, "Shape must be { rows cols }", "matrix") } rowsObj := shape.Series.Get(0) colsObj := shape.Series.Get(1) rowsInt, ok1 := rowsObj.(env.Integer) colsInt, ok2 := colsObj.(env.Integer) if !ok1 || !ok2 { return evaldo.MakeBuiltinError(ps, "Shape must contain integers", "matrix") } rows := int(rowsInt.Value) cols := int(colsInt.Value) switch data := arg1.(type) { case env.Block: if data.Series.Len() != rows*cols { return evaldo.MakeBuiltinError(ps, "Data length must match rows*cols", "matrix") } floats := make([]float64, rows*cols) for i := 0; i < data.Series.Len(); i++ { switch v := data.Series.Get(i).(type) { case env.Decimal: floats[i] = v.Value case env.Integer: floats[i] = float64(v.Value) default: return evaldo.MakeBuiltinError(ps, "Data must contain numbers", "matrix") } } return *env.NewMatrixWithData(rows, cols, floats) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "matrix") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "matrix") } }, }, "matrix\\randn": { Argsn: 2, Doc: "Creates a matrix with random normal values (mean 0, std 1).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch rows := arg0.(type) { case env.Integer: switch cols := arg1.(type) { case env.Integer: if rows.Value <= 0 || cols.Value <= 0 { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must be positive", "matrix\\randn") } r := int(rows.Value) c := int(cols.Value) data := make([]float64, r*c) for i := range data { data[i] = rand.NormFloat64() } return *env.NewMatrixWithData(r, c, data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "matrix\\randn") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "matrix\\randn") } }, }, "matrix\\ones": { Argsn: 2, Doc: "Creates a matrix filled with ones.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch rows := arg0.(type) { case env.Integer: switch cols := arg1.(type) { case env.Integer: if rows.Value <= 0 || cols.Value <= 0 { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must be positive", "matrix\\ones") } r := int(rows.Value) c := int(cols.Value) data := make([]float64, r*c) for i := range data { data[i] = 1.0 } return *env.NewMatrixWithData(r, c, data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "matrix\\ones") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "matrix\\ones") } }, }, "matrix\\eye": { Argsn: 1, Doc: "Creates an identity matrix of size n×n.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch n := arg0.(type) { case env.Integer: if n.Value <= 0 { return evaldo.MakeBuiltinError(ps, "Matrix size must be positive", "matrix\\eye") } size := int(n.Value) data := make([]float64, size*size) for i := 0; i < size; i++ { data[i*size+i] = 1.0 } return *env.NewMatrixWithData(size, size, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "matrix\\eye") } }, }, "shape?": { Argsn: 1, Doc: "Returns the shape of a matrix as { rows cols }.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: return *env.NewBlock(*env.NewTSeries([]env.Object{ *env.NewInteger(int64(m.Rows)), *env.NewInteger(int64(m.Cols)), })) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "shape?") } }, }, "rows?": { Argsn: 1, Doc: "Returns the number of rows in a matrix.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: return *env.NewInteger(int64(m.Rows)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "rows?") } }, }, "cols?": { Argsn: 1, Doc: "Returns the number of columns in a matrix.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: return *env.NewInteger(int64(m.Cols)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "cols?") } }, }, "mat-get": { Argsn: 3, Doc: "Gets the element at the specified row and column (0-indexed).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch row := arg1.(type) { case env.Integer: switch col := arg2.(type) { case env.Integer: r := int(row.Value) c := int(col.Value) if r < 0 || r >= m.Rows || c < 0 || c >= m.Cols { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Matrix indices out of bounds: row %d, col %d (matrix is %dx%d)", r, c, m.Rows, m.Cols), "mat-get") } return *env.NewDecimal(m.Get(r, c)) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType}, "mat-get") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mat-get") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-get") } }, }, "mat-set!": { Argsn: 4, Doc: "Sets the element at the specified row and column (0-indexed). Modifies matrix in place.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch row := arg1.(type) { case env.Integer: switch col := arg2.(type) { case env.Integer: r := int(row.Value) c := int(col.Value) if r < 0 || r >= m.Rows || c < 0 || c >= m.Cols { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Matrix indices out of bounds: row %d, col %d (matrix is %dx%d)", r, c, m.Rows, m.Cols), "mat-set!") } var val float64 switch v := arg3.(type) { case env.Decimal: val = v.Value case env.Integer: val = float64(v.Value) default: return evaldo.MakeArgError(ps, 4, []env.Type{env.DecimalType, env.IntegerType}, "mat-set!") } m.Set(r, c, val) return m default: return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType}, "mat-set!") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mat-set!") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-set!") } }, }, "mat-row": { Argsn: 2, Doc: "Returns a row of the matrix as a vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch row := arg1.(type) { case env.Integer: r := int(row.Value) if r < 0 || r >= m.Rows { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Row index %d out of bounds (matrix has %d rows)", r, m.Rows), "mat-row") } data := make(govector.Vector, m.Cols) for j := 0; j < m.Cols; j++ { data[j] = m.Get(r, j) } return *env.NewVector(data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mat-row") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-row") } }, }, "mat-col": { Argsn: 2, Doc: "Returns a column of the matrix as a vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch col := arg1.(type) { case env.Integer: c := int(col.Value) if c < 0 || c >= m.Cols { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Column index %d out of bounds (matrix has %d columns)", c, m.Cols), "mat-col") } data := make(govector.Vector, m.Rows) for i := 0; i < m.Rows; i++ { data[i] = m.Get(i, c) } return *env.NewVector(data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mat-col") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-col") } }, }, "mat-transpose": { Argsn: 1, Doc: "Returns the transpose of a matrix.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: data := make([]float64, m.Rows*m.Cols) for i := 0; i < m.Rows; i++ { for j := 0; j < m.Cols; j++ { data[j*m.Rows+i] = m.Get(i, j) } } return *env.NewMatrixWithData(m.Cols, m.Rows, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-transpose") } }, }, "mat-mul": { Argsn: 2, Doc: "Matrix multiplication. A (m×n) × B (n×p) = C (m×p).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch A := arg0.(type) { case env.Matrix: switch B := arg1.(type) { case env.Matrix: if A.Cols != B.Rows { return evaldo.MakeBuiltinError(ps, "Matrix dimensions incompatible for multiplication", "mat-mul") } m, n, p := A.Rows, A.Cols, B.Cols data := make([]float64, m*p) for i := 0; i < m; i++ { for j := 0; j < p; j++ { var sum float64 for k := 0; k < n; k++ { sum += A.Get(i, k) * B.Get(k, j) } data[i*p+j] = sum } } return *env.NewMatrixWithData(m, p, data) case env.Vector: if A.Cols != len(B.Value) { return evaldo.MakeBuiltinError(ps, "Matrix columns must match vector length", "mat-mul") } result := make(govector.Vector, A.Rows) for i := 0; i < A.Rows; i++ { var sum float64 for j := 0; j < A.Cols; j++ { sum += A.Get(i, j) * B.Value[j] } result[i] = sum } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.MatrixType, env.VectorType}, "mat-mul") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-mul") } }, }, "mat-hadamard": { Argsn: 2, Doc: "Element-wise (Hadamard) multiplication of two matrices. In the future, could have a dedicated .* operator.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch A := arg0.(type) { case env.Matrix: switch B := arg1.(type) { case env.Matrix: if A.Rows != B.Rows || A.Cols != B.Cols { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must match", "mat-hadamard") } data := make([]float64, len(A.Data)) for i := range A.Data { data[i] = A.Data[i] * B.Data[i] } return *env.NewMatrixWithData(A.Rows, A.Cols, data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.MatrixType}, "mat-hadamard") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-hadamard") } }, }, "mat-add": { Argsn: 2, Doc: "Element-wise addition of two matrices. In the future, could have a dedicated .+ operator.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch A := arg0.(type) { case env.Matrix: switch B := arg1.(type) { case env.Matrix: if A.Rows != B.Rows || A.Cols != B.Cols { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must match", "mat-add") } data := make([]float64, len(A.Data)) for i := range A.Data { data[i] = A.Data[i] + B.Data[i] } return *env.NewMatrixWithData(A.Rows, A.Cols, data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.MatrixType}, "mat-add") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-add") } }, }, "mat-sub": { Argsn: 2, Doc: "Element-wise subtraction of two matrices. In the future, could have a dedicated .- operator.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch A := arg0.(type) { case env.Matrix: switch B := arg1.(type) { case env.Matrix: if A.Rows != B.Rows || A.Cols != B.Cols { return evaldo.MakeBuiltinError(ps, "Matrix dimensions must match", "mat-sub") } data := make([]float64, len(A.Data)) for i := range A.Data { data[i] = A.Data[i] - B.Data[i] } return *env.NewMatrixWithData(A.Rows, A.Cols, data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.MatrixType}, "mat-sub") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-sub") } }, }, "mat-scale": { Argsn: 2, Doc: "Multiplies all elements of a matrix by a scalar.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: var scalar float64 switch s := arg1.(type) { case env.Decimal: scalar = s.Value case env.Integer: scalar = float64(s.Value) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.DecimalType, env.IntegerType}, "mat-scale") } data := make([]float64, len(m.Data)) for i := range m.Data { data[i] = m.Data[i] * scalar } return *env.NewMatrixWithData(m.Rows, m.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-scale") } }, }, "mat-sum-rows": { Argsn: 1, Doc: "Returns a vector containing the sum of each row.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: result := make(govector.Vector, m.Rows) for i := 0; i < m.Rows; i++ { var sum float64 for j := 0; j < m.Cols; j++ { sum += m.Get(i, j) } result[i] = sum } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-sum-rows") } }, }, "mat-sum-cols": { Argsn: 1, Doc: "Returns a vector containing the sum of each column.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: result := make(govector.Vector, m.Cols) for j := 0; j < m.Cols; j++ { var sum float64 for i := 0; i < m.Rows; i++ { sum += m.Get(i, j) } result[j] = sum } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-sum-cols") } }, }, "mat-max-rows": { Argsn: 1, Doc: "Returns a vector containing the maximum of each row.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: result := make(govector.Vector, m.Rows) for i := 0; i < m.Rows; i++ { maxVal := m.Get(i, 0) for j := 1; j < m.Cols; j++ { if v := m.Get(i, j); v > maxVal { maxVal = v } } result[i] = maxVal } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-max-rows") } }, }, "mat-max-cols": { Argsn: 1, Doc: "Returns a vector containing the maximum of each column.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: result := make(govector.Vector, m.Cols) for j := 0; j < m.Cols; j++ { maxVal := m.Get(0, j) for i := 1; i < m.Rows; i++ { if v := m.Get(i, j); v > maxVal { maxVal = v } } result[j] = maxVal } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-max-cols") } }, }, "mat-to-block": { Argsn: 1, Doc: "Converts a matrix to a block of blocks (each row is a block).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: rows := make([]env.Object, m.Rows) for i := 0; i < m.Rows; i++ { row := make([]env.Object, m.Cols) for j := 0; j < m.Cols; j++ { row[j] = *env.NewDecimal(m.Get(i, j)) } rows[i] = *env.NewBlock(*env.NewTSeries(row)) } return *env.NewBlock(*env.NewTSeries(rows)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-to-block") } }, }, "block-to-mat": { Argsn: 1, Doc: "Converts a block of blocks (rows) to a matrix.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch blk := arg0.(type) { case env.Block: if blk.Series.Len() == 0 { return evaldo.MakeBuiltinError(ps, "Block is empty", "block-to-mat") } firstRow, ok := blk.Series.Get(0).(env.Block) if !ok { return evaldo.MakeBuiltinError(ps, "Block must contain blocks (rows)", "block-to-mat") } rows := blk.Series.Len() cols := firstRow.Series.Len() data := make([]float64, rows*cols) for i := 0; i < rows; i++ { row, ok := blk.Series.Get(i).(env.Block) if !ok { return evaldo.MakeBuiltinError(ps, "Block must contain blocks (rows)", "block-to-mat") } if row.Series.Len() != cols { return evaldo.MakeBuiltinError(ps, "All rows must have the same length", "block-to-mat") } for j := 0; j < cols; j++ { switch v := row.Series.Get(j).(type) { case env.Decimal: data[i*cols+j] = v.Value case env.Integer: data[i*cols+j] = float64(v.Value) default: return evaldo.MakeBuiltinError(ps, "Rows must contain numbers", "block-to-mat") } } } return *env.NewMatrixWithData(rows, cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "block-to-mat") } }, }, "vector-to-mat": { Argsn: 2, Doc: "Converts a vector to a matrix. Use 'row for 1×n or 'col for n×1.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v := arg0.(type) { case env.Vector: switch orient := arg1.(type) { case env.Word: word := ps.Idx.GetWord(orient.Index) n := len(v.Value) data := make([]float64, n) copy(data, v.Value) if word == "row" { return *env.NewMatrixWithData(1, n, data) } else if word == "col" { return *env.NewMatrixWithData(n, 1, data) } return evaldo.MakeBuiltinError(ps, "Orientation must be 'row or 'col", "vector-to-mat") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.WordType}, "vector-to-mat") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "vector-to-mat") } }, }, "mat-slice": { Argsn: 3, Doc: "Extracts a sub-matrix. Row and column ranges are { start end } (inclusive, 0-indexed).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch rowRange := arg1.(type) { case env.Block: if rowRange.Series.Len() != 2 { return evaldo.MakeBuiltinError(ps, "Row range must be { start end }", "mat-slice") } switch colRange := arg2.(type) { case env.Block: if colRange.Series.Len() != 2 { return evaldo.MakeBuiltinError(ps, "Column range must be { start end }", "mat-slice") } r0, ok1 := rowRange.Series.Get(0).(env.Integer) r1, ok2 := rowRange.Series.Get(1).(env.Integer) c0, ok3 := colRange.Series.Get(0).(env.Integer) c1, ok4 := colRange.Series.Get(1).(env.Integer) if !ok1 || !ok2 || !ok3 || !ok4 { return evaldo.MakeBuiltinError(ps, "Ranges must contain integers", "mat-slice") } rowStart, rowEnd := int(r0.Value), int(r1.Value) colStart, colEnd := int(c0.Value), int(c1.Value) if rowStart < 0 || rowEnd >= m.Rows || rowStart > rowEnd { return evaldo.MakeBuiltinError(ps, "Invalid row range", "mat-slice") } if colStart < 0 || colEnd >= m.Cols || colStart > colEnd { return evaldo.MakeBuiltinError(ps, "Invalid column range", "mat-slice") } newRows := rowEnd - rowStart + 1 newCols := colEnd - colStart + 1 data := make([]float64, newRows*newCols) for i := 0; i < newRows; i++ { for j := 0; j < newCols; j++ { data[i*newCols+j] = m.Get(rowStart+i, colStart+j) } } return *env.NewMatrixWithData(newRows, newCols, data) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.BlockType}, "mat-slice") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "mat-slice") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-slice") } }, }, "mat-softmax": { Argsn: 1, Doc: "Applies softmax to each column of the matrix. Returns a new matrix.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: data := make([]float64, m.Rows*m.Cols) for j := 0; j < m.Cols; j++ { maxVal := m.Get(0, j) for i := 1; i < m.Rows; i++ { if v := m.Get(i, j); v > maxVal { maxVal = v } } sum := 0.0 for i := 0; i < m.Rows; i++ { exp := math.Exp(m.Get(i, j) - maxVal) data[i*m.Cols+j] = exp sum += exp } for i := 0; i < m.Rows; i++ { data[i*m.Cols+j] /= sum } } return *env.NewMatrixWithData(m.Rows, m.Cols, data) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-softmax") } }, }, "mat-set-col!": { Argsn: 3, Doc: "Sets a column of the matrix from a vector or block. Mutates in place.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch m := arg0.(type) { case env.Matrix: switch col := arg1.(type) { case env.Integer: c := int(col.Value) if c < 0 || c >= m.Cols { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Column index %d out of bounds (matrix has %d columns)", c, m.Cols), "mat-set-col!") } switch vals := arg2.(type) { case env.Vector: if len(vals.Value) != m.Rows { return evaldo.MakeBuiltinError(ps, "Vector length must match matrix rows", "mat-set-col!") } for i := 0; i < m.Rows; i++ { m.Set(i, c, vals.Value[i]) } return m case env.Block: if vals.Series.Len() != m.Rows { return evaldo.MakeBuiltinError(ps, "Block length must match matrix rows", "mat-set-col!") } for i := 0; i < m.Rows; i++ { switch v := vals.Series.Get(i).(type) { case env.Decimal: m.Set(i, c, v.Value) case env.Integer: m.Set(i, c, float64(v.Value)) default: return evaldo.MakeBuiltinError(ps, "Block must contain numbers", "mat-set-col!") } } return m default: return evaldo.MakeArgError(ps, 3, []env.Type{env.VectorType, env.BlockType}, "mat-set-col!") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mat-set-col!") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.MatrixType}, "mat-set-col!") } }, }, "vec-add": { Argsn: 2, Doc: "Adds two vectors element-wise. Returns a new vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: if len(v1.Value) != len(v2.Value) { return evaldo.MakeBuiltinError(ps, "Vectors must have same length", "vec-add") } data := make(govector.Vector, len(v1.Value)) for i := range v1.Value { data[i] = v1.Value[i] + v2.Value[i] } return *env.NewVector(data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "vec-add") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "vec-add") } }, }, "vec-sub": { Argsn: 2, Doc: "Subtracts two vectors element-wise (v1 - v2). Returns a new vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: if len(v1.Value) != len(v2.Value) { return evaldo.MakeBuiltinError(ps, "Vectors must have same length", "vec-sub") } data := make(govector.Vector, len(v1.Value)) for i := range v1.Value { data[i] = v1.Value[i] - v2.Value[i] } return *env.NewVector(data) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "vec-sub") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "vec-sub") } }, }, "vec-to-block": { Argsn: 1, Doc: "Converts a vector to a block of decimal values.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v := arg0.(type) { case env.Vector: items := make([]env.Object, len(v.Value)) for i, val := range v.Value { items[i] = *env.NewDecimal(val) } return *env.NewBlock(*env.NewTSeries(items)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "vec-to-block") } }, }, }
var Builtins_mcp = map[string]*env.Builtin{ "mcp-server//Create": { Argsn: 2, Doc: "Creates a new MCP server with the given name and version.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch name := arg0.(type) { case env.String: switch version := arg1.(type) { case env.String: mcpServerMutex.Lock() defer mcpServerMutex.Unlock() serverInfo := struct { Name string Version string }{ Name: name.Value, Version: version.Value, } return *env.NewNative(ps.Idx, serverInfo, "Rye-mcp-server") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mcp-server//create") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "mcp-server//create") } }, }, "mcp//Create-resource": { Argsn: 3, Doc: "Creates a new MCP resource with the given URI, name, and MIME type.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch uri := arg0.(type) { case env.String: switch name := arg1.(type) { case env.String: switch mimeType := arg2.(type) { case env.String: resourceInfo := struct { URI string Name string MIMEType string }{ URI: uri.Value, Name: name.Value, MIMEType: mimeType.Value, } return *env.NewNative(ps.Idx, resourceInfo, "Rye-mcp-resource") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "mcp-resource//create") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mcp-resource//create") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "mcp-resource//create") } }, }, "mcp//Create-tool": { Argsn: 2, Doc: "Creates a new MCP tool with the given name and description.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch name := arg0.(type) { case env.String: switch desc := arg1.(type) { case env.String: toolInfo := struct { Name string Description string }{ Name: name.Value, Description: desc.Value, } return *env.NewNative(ps.Idx, toolInfo, "Rye-mcp-tool") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mcp-tool//create") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "mcp-tool//create") } }, }, "mcp//Create-prompt": { Argsn: 2, Doc: "Creates a new MCP prompt with the given name and description.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch name := arg0.(type) { case env.String: switch desc := arg1.(type) { case env.String: promptInfo := struct { Name string Description string }{ Name: name.Value, Description: desc.Value, } return *env.NewNative(ps.Idx, promptInfo, "Rye-mcp-prompt") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mcp-prompt//create") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "mcp-prompt//create") } }, }, "mcp//Protocol-version": { Argsn: 0, Doc: "Returns the latest MCP protocol version.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return env.String{Value: "2024-11-05"} }, }, "Rye-mcp-server//Get-name": { Argsn: 1, Doc: "Gets the name of the MCP server.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch srv := arg0.(type) { case env.Native: if srv.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-server//get-name") } serverInfo, ok := srv.Value.(struct { Name string Version string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to server info", "Rye-mcp-server//get-name") } return env.String{Value: serverInfo.Name} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-server//get-name") } }, }, "Rye-mcp-server//Get-version": { Argsn: 1, Doc: "Gets the version of the MCP server.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch srv := arg0.(type) { case env.Native: if srv.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-server//get-version") } serverInfo, ok := srv.Value.(struct { Name string Version string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to server info", "Rye-mcp-server//get-version") } return env.String{Value: serverInfo.Version} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-server//get-version") } }, }, "Rye-mcp-resource//Get-uri": { Argsn: 1, Doc: "Gets the URI of the MCP resource.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch res := arg0.(type) { case env.Native: if res.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-resource//get-uri") } resourceInfo, ok := res.Value.(struct { URI string Name string MIMEType string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to resource info", "Rye-mcp-resource//get-uri") } return env.String{Value: resourceInfo.URI} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-resource//get-uri") } }, }, "Rye-mcp-resource//Get-name": { Argsn: 1, Doc: "Gets the name of the MCP resource.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch res := arg0.(type) { case env.Native: if res.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-resource//get-name") } resourceInfo, ok := res.Value.(struct { URI string Name string MIMEType string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to resource info", "Rye-mcp-resource//get-name") } return env.String{Value: resourceInfo.Name} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-resource//get-name") } }, }, "Rye-mcp-resource//Get-mime-type": { Argsn: 1, Doc: "Gets the MIME type of the MCP resource.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch res := arg0.(type) { case env.Native: if res.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-resource//get-mime-type") } resourceInfo, ok := res.Value.(struct { URI string Name string MIMEType string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to resource info", "Rye-mcp-resource//get-mime-type") } return env.String{Value: resourceInfo.MIMEType} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-resource//get-mime-type") } }, }, "Rye-mcp-tool//Get-name": { Argsn: 1, Doc: "Gets the name of the MCP tool.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch tool := arg0.(type) { case env.Native: if tool.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-tool//get-name") } toolInfo, ok := tool.Value.(struct { Name string Description string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to tool info", "Rye-mcp-tool//get-name") } return env.String{Value: toolInfo.Name} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-tool//get-name") } }, }, "Rye-mcp-tool//Get-description": { Argsn: 1, Doc: "Gets the description of the MCP tool.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch tool := arg0.(type) { case env.Native: if tool.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-tool//get-description") } toolInfo, ok := tool.Value.(struct { Name string Description string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to tool info", "Rye-mcp-tool//get-description") } return env.String{Value: toolInfo.Description} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-tool//get-description") } }, }, "Rye-mcp-prompt//Get-name": { Argsn: 1, Doc: "Gets the name of the MCP prompt.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch prompt := arg0.(type) { case env.Native: if prompt.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-prompt//get-name") } promptInfo, ok := prompt.Value.(struct { Name string Description string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to prompt info", "Rye-mcp-prompt//get-name") } return env.String{Value: promptInfo.Name} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-prompt//get-name") } }, }, "Rye-mcp-prompt//Get-description": { Argsn: 1, Doc: "Gets the description of the MCP prompt.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch prompt := arg0.(type) { case env.Native: if prompt.Type() != env.NativeType { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Expected native type", "Rye-mcp-prompt//get-description") } promptInfo, ok := prompt.Value.(struct { Name string Description string }) if !ok { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Failed to cast to prompt info", "Rye-mcp-prompt//get-description") } return env.String{Value: promptInfo.Description} default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mcp-prompt//get-description") } }, }, }
var Builtins_mqtt = map[string]*env.Builtin{ "mqtt-uri//Open": { Argsn: 1, Doc: "Opens a connection to an MQTT broker.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch uri := arg0.(type) { case env.Uri: scheme := ps.Idx.GetWord(uri.Scheme.Index) opts, err := mqttURIOptions(scheme, uri.Path) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "mqtt-uri//Open") } client := mqtt.NewClient(opts) if token := client.Connect(); token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to connect to MQTT broker: %v", token.Error()), "mqtt-uri//Open") } return *env.NewNative(ps.Idx, client, "mqtt-client") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "mqtt-uri//Open") } }, }, "mqtt-client//Disconnect": { Argsn: 1, Doc: "Disconnects from the MQTT broker.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: mqttClient := client.Value.(mqtt.Client) mqttClient.Disconnect(250) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Disconnect") } }, }, "mqtt-client//Close": { Argsn: 1, Doc: "Closes the MQTT client connection (alias for Disconnect).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: if ps.Idx.GetWord(client.Kind.Index) != "mqtt-client" { return evaldo.MakeBuiltinError(ps, "Expected MQTT client connection.", "mqtt-client//Close") } mqttClient := client.Value.(mqtt.Client) mqttClient.Disconnect(250) return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Close") } }, }, "mqtt-client//Publish": { Argsn: 5, Doc: "Publishes a message to an MQTT topic with specified QoS and retain flag.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: switch payload := arg2.(type) { case env.String: switch qos := arg3.(type) { case env.Integer: switch retain := arg4.(type) { case env.Integer: mqttClient := client.Value.(mqtt.Client) retainBool := retain.Value != 0 if qos.Value < 0 || qos.Value > 2 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "QoS must be 0, 1, or 2", "mqtt-client//Publish") } token := mqttClient.Publish(topic.Value, byte(qos.Value), retainBool, payload.Value) if token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to publish message: %v", token.Error()), "mqtt-client//Publish") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 5, []env.Type{env.IntegerType}, "mqtt-client//Publish") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 4, []env.Type{env.IntegerType}, "mqtt-client//Publish") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "mqtt-client//Publish") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-client//Publish") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Publish") } }, }, "mqtt-client//Publish-simple": { Argsn: 3, Doc: "Publishes a message to an MQTT topic with default settings (QoS 0, no retain).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: switch payload := arg2.(type) { case env.String: mqttClient := client.Value.(mqtt.Client) token := mqttClient.Publish(topic.Value, 0, false, payload.Value) if token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to publish message: %v", token.Error()), "mqtt-client//Publish-simple") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "mqtt-client//Publish-simple") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-client//Publish-simple") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Publish-simple") } }, }, "mqtt-client//Subscribe": { Argsn: 4, Doc: "Subscribes to an MQTT topic with a message handler function.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: switch qos := arg2.(type) { case env.Integer: switch handler := arg3.(type) { case env.Function: mqttClient := client.Value.(mqtt.Client) if qos.Value < 0 || qos.Value > 2 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "QoS must be 0, 1, or 2", "mqtt-client//Subscribe") } callback := mqttMessageHandler(ps, handler) token := mqttClient.Subscribe(topic.Value, byte(qos.Value), callback) if token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to subscribe: %v", token.Error()), "mqtt-client//Subscribe") } return *env.NewInteger(1) default: fmt.Println(arg3.Inspect(*ps.Idx)) ps.FailureFlag = true return evaldo.MakeArgError(ps, 4, []env.Type{env.FunctionType}, "mqtt-client//Subscribe") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.IntegerType}, "mqtt-client//Subscribe") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-client//Subscribe") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Subscribe") } }, }, "mqtt-client//Subscribe-simple": { Argsn: 3, Doc: "Subscribes with QoS 0; the handler receives a payload string and metadata dict, just like Subscribe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: switch handler := arg2.(type) { case env.Function: mqttClient := client.Value.(mqtt.Client) callback := mqttMessageHandler(ps, handler) token := mqttClient.Subscribe(topic.Value, 0, callback) if token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to subscribe: %v", token.Error()), "mqtt-client//Subscribe-simple") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.FunctionType}, "mqtt-client//Subscribe-simple") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-client//Subscribe-simple") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Subscribe-simple") } }, }, "mqtt-client//Unsubscribe": { Argsn: 2, Doc: "Unsubscribes from an MQTT topic.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: mqttClient := client.Value.(mqtt.Client) token := mqttClient.Unsubscribe(topic.Value) if token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to unsubscribe: %v", token.Error()), "mqtt-client//Unsubscribe") } return *env.NewInteger(1) default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-client//Unsubscribe") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Unsubscribe") } }, }, "mqtt-client//Is-connected": { Argsn: 1, Doc: "Checks if the MQTT client is currently connected to the broker.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch client := arg0.(type) { case env.Native: mqttClient := client.Value.(mqtt.Client) if mqttClient.IsConnected() { return *env.NewInteger(1) } else { return *env.NewInteger(0) } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-client//Connected?") } }, }, "mqtt-options": { Argsn: 0, Doc: "Creates a new MQTT client options object for advanced configuration.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { opts := mqtt.NewClientOptions() return *env.NewNative(ps.Idx, opts, "mqtt-options") }, }, "mqtt-options//Set-broker": { Argsn: 2, Doc: "Sets the MQTT broker address in the options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch broker := arg1.(type) { case env.String: options := opts.Value.(*mqtt.ClientOptions) options.AddBroker(broker.Value) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-options//Set-broker") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-broker") } }, }, "mqtt-options//Set-client-id": { Argsn: 2, Doc: "Sets the client ID in the MQTT options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch clientID := arg1.(type) { case env.String: options := opts.Value.(*mqtt.ClientOptions) options.SetClientID(clientID.Value) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-options//Set-client-id") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-client-id") } }, }, "mqtt-options//Set-keep-alive": { Argsn: 2, Doc: "Sets the keep alive interval in seconds.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch keepAlive := arg1.(type) { case env.Integer: options := opts.Value.(*mqtt.ClientOptions) options.SetKeepAlive(time.Duration(keepAlive.Value) * time.Second) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "mqtt-options//Set-keep-alive") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-keep-alive") } }, }, "mqtt-options//Set-username": { Argsn: 2, Doc: "Sets the username for MQTT authentication.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch username := arg1.(type) { case env.String: options := opts.Value.(*mqtt.ClientOptions) options.SetUsername(username.Value) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-options//Set-username") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-username") } }, }, "mqtt-options//Set-password": { Argsn: 2, Doc: "Sets the password for MQTT authentication.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch password := arg1.(type) { case env.String: options := opts.Value.(*mqtt.ClientOptions) options.SetPassword(password.Value) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-options//Set-password") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-password") } }, }, "mqtt-options//Set-will": { Argsn: 5, Doc: "Sets the Last Will and Testament message with QoS and retain flag.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: switch topic := arg1.(type) { case env.String: switch payload := arg2.(type) { case env.String: switch qos := arg3.(type) { case env.Integer: switch retain := arg4.(type) { case env.Integer: if qos.Value < 0 || qos.Value > 2 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "QoS must be 0, 1, or 2", "mqtt-options//Set-will") } options := opts.Value.(*mqtt.ClientOptions) retainBool := retain.Value != 0 options.SetWill(topic.Value, payload.Value, byte(qos.Value), retainBool) return arg0 default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 5, []env.Type{env.IntegerType}, "mqtt-options//Set-will") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 4, []env.Type{env.IntegerType}, "mqtt-options//Set-will") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "mqtt-options//Set-will") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mqtt-options//Set-will") } default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Set-will") } }, }, "mqtt-options//Connect-with-options": { Argsn: 1, Doc: "Creates and connects an MQTT client using the configured options.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch opts := arg0.(type) { case env.Native: options := opts.Value.(*mqtt.ClientOptions) client := mqtt.NewClient(options) if token := client.Connect(); token.Wait() && token.Error() != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Failed to connect to MQTT broker: %v", token.Error()), "mqtt-options//Connect-with-options") } return *env.NewNative(ps.Idx, client, "mqtt-client") default: ps.FailureFlag = true return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "mqtt-options//Connect-with-options") } }, }, }
var Builtins_msgdispatcher = map[string]*env.Builtin{ "msg-dispatcher": { Argsn: 2, Doc: "Creates a new message dispatcher with specified buffer size and initial state.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bufSize := arg0.(type) { case env.Integer: switch initialState := arg1.(type) { case env.Dict: dispatcher := NewMessageDispatcher(int(bufSize.Value), initialState) return *env.NewNative(ps.Idx, dispatcher, "msg-dispatcher") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.DictType}, "msg-dispatcher") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "msg-dispatcher") } }, }, "msg-dispatcher//Register": { Argsn: 3, Doc: "Registers a message handler function for a specific message type.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Register") } switch msgType := arg1.(type) { case env.String: switch handler := arg2.(type) { case env.Function: if handler.Argsn != 2 { return evaldo.MakeBuiltinError(ps, "Handler must accept 2 arguments (message, state)", "Rye-msg-dispatcher//Register") } dispatcher.RegisterHandler(msgType.Value, handler) return arg0 default: return evaldo.MakeArgError(ps, 3, []env.Type{env.FunctionType}, "Rye-msg-dispatcher//Register") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Rye-msg-dispatcher//Register") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Register") } }, }, "msg-dispatcher//Unregister": { Argsn: 2, Doc: "Unregisters a message handler for a specific message type.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Unregister") } switch msgType := arg1.(type) { case env.String: dispatcher.UnregisterHandler(msgType.Value) return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "Rye-msg-dispatcher//Unregister") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Unregister") } }, }, "msg-dispatcher//Send": { Argsn: 2, Doc: "Sends a message to the dispatcher for processing.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Send") } err := dispatcher.Send(arg1) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Send failed: %v", err), "Rye-msg-dispatcher//Send") } return arg0 default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Send") } }, }, "msg-dispatcher//State": { Argsn: 1, Doc: "Gets the current state from the dispatcher.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//State") } return dispatcher.GetState() default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//State") } }, }, "msg-dispatcher//Set-state": { Argsn: 2, Doc: "Sets the current state in the dispatcher.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Set-state") } switch newState := arg1.(type) { case env.Dict: dispatcher.SetState(newState) return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.DictType}, "Rye-msg-dispatcher//Set-state") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Set-state") } }, }, "msg-dispatcher//Start": { Argsn: 2, Doc: "Starts the message dispatcher loop in a goroutine. Optionally takes an update callback function.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Start") } var updateCallback env.Function switch cb := arg1.(type) { case env.Function: if cb.Argsn != 1 { return evaldo.MakeBuiltinError(ps, "Update callback must accept 1 argument (state)", "Rye-msg-dispatcher//Start") } updateCallback = cb case env.Void: updateCallback = env.Function{Argsn: -1} default: return evaldo.MakeArgError(ps, 2, []env.Type{env.FunctionType, env.VoidType}, "Rye-msg-dispatcher//Start") } dispatcher.Start(ps, updateCallback) return arg0 default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Start") } }, }, "msg-dispatcher//Stop": { Argsn: 1, Doc: "Stops the message dispatcher loop and waits for it to finish.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: dispatcher, ok := native.Value.(*MessageDispatcher) if !ok { return evaldo.MakeBuiltinError(ps, "Expected MessageDispatcher", "Rye-msg-dispatcher//Stop") } dispatcher.Stop() return arg0 default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-msg-dispatcher//Stop") } }, }, }
Builtins for message dispatcher
var Builtins_mysql = map[string]*env.Builtin{ "mysql-uri//Open": { Argsn: 1, Doc: "Opens a connection to a MySQL database.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.Uri: db, err := sql.Open("mysql", str.Path) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error opening MySQL: %v", err.Error()), "mysql-uri//Open") } if err := db.Ping(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error connecting to MySQL: %v", err.Error()), "mysql-uri//Open") } return *env.NewNative(ps.Idx, db, "Rye-mysql") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "mysql-uri//Open") } }, }, "mysql-uri//Open\\pwd": { Argsn: 2, Doc: "Opens a connection to a MySQL database with separate password parameter.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.Uri: switch pwd := arg1.(type) { case env.String: path := strings.Replace(str.Path, "@", ":"+pwd.Value+"@", 1) db, err := sql.Open("mysql", path) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error opening MySQL: %v", err.Error()), "mysql-uri//Open\\pwd") } if err := db.Ping(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error connecting to MySQL: %v", err.Error()), "mysql-uri//Open\\pwd") } return *env.NewNative(ps.Idx, db, "Rye-mysql") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "mysql-uri//Open\\pwd") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "mysql-uri//Open\\pwd") } }, }, "Rye-mysql//Exec": { Argsn: 2, Doc: "Executes a SQL statement that modifies data (INSERT, UPDATE, DELETE).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0, 2) _, vals = SQL_EvalBlock(ps, MODE_SQLITE, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: ps.ErrorFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-mysql//Exec") } if sqlstr != "" { db2 := db1.Value.(*sql.DB) res, err := db2.Exec(sqlstr, vals...) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-mysql//Exec") } else { num, _ := res.RowsAffected() if num > 0 { return env.NewInteger(1) } else { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "No rows affected.", "Rye-mysql//Exec") } } } else { return evaldo.MakeBuiltinError(ps, "SQL string is blank.", "Rye-mysql//Exec") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mysql//Exec") } }, }, "Rye-mysql//Query": { Argsn: 2, Doc: "Executes a SQL query and returns results as a table.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0, 2) _, vals = SQL_EvalBlock(ps, MODE_SQLITE, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: ps.ErrorFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-mysql//Query") } if sqlstr != "" { rows, err := db1.Value.(*sql.DB).Query(sqlstr, vals...) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-mysql//Query") } else { cols, _ := rows.Columns() spr := env.NewTable(cols) i := 0 for rows.Next() { var sr env.TableRow columns := make([]any, len(cols)) columnPointers := make([]any, len(cols)) for i := range columns { columnPointers[i] = &columns[i] } if err := rows.Scan(columnPointers...); err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-mysql//Query") } m := make(map[string]any) for i, colName := range cols { val := *columnPointers[i].(*any) switch vval := val.(type) { case []uint8: m[colName] = env.ToRyeValue(string(vval)) sr.Values = append(sr.Values, env.ToRyeValue(string(vval))) default: m[colName] = env.ToRyeValue(vval) sr.Values = append(sr.Values, env.ToRyeValue(vval)) } } spr.AddRow(sr) i++ } rows.Close() if i == 0 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "No data.", "Rye-mysql//Query") } return *spr } } else { return evaldo.MakeBuiltinError(ps, "Empty SQL.", "Rye-mysql//Query") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mysql//Query") } }, }, "Rye-mysql//Close": { Argsn: 1, Doc: "Closes the MySQL database connection.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch db := arg0.(type) { case env.Native: mysqlKind, _ := ps.Idx.GetIndex("Rye-mysql") if db.Kind.Index != mysqlKind { return evaldo.MakeBuiltinError(ps, "Expected MySQL database connection.", "Rye-mysql//Close") } sqlDB, ok := db.Value.(*sql.DB) if !ok { return evaldo.MakeBuiltinError(ps, "Invalid database connection.", "Rye-mysql//Close") } err := sqlDB.Close() if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error closing database: %v", err.Error()), "Rye-mysql//Close") } return *env.NewInteger(1) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-mysql//Close") } }, }, }
var Builtins_pipes = map[string]*env.Builtin{ "cat": { Argsn: 1, Doc: "Creates a new pipe object from a file.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch path := arg0.(type) { case env.Uri: p := script.File(path.GetPath()) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "p-new-file") } }, }, "find": { Argsn: 1, Doc: "Creates a pipe object listing all the files in the directory and its subdirectories recursively, one per line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch path := arg0.(type) { case env.Uri: p := script.FindFiles(path.GetPath()) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "p-new-find-files") } }, }, "list": { Argsn: 1, Doc: "Creates a pipe object listing all the files in the directory, one per line. Accepts and URI or glob pattern.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch path := arg0.(type) { case env.Uri: p := script.ListFiles(path.GetPath()) return *env.NewNative(ps.Idx, p, "script-pipe") case env.String: p := script.ListFiles(path.Value) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "p-new-list-files") } }, }, "from-block": { Argsn: 1, Doc: "Creates a pipe object from a block of strings, one per line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch block := arg0.(type) { case env.Block: strs := make([]string, len(block.Series.S)) for i, item := range block.Series.S { switch s := item.(type) { case env.String: strs[i] = s.Value default: return evaldo.MakeBuiltinError(ps, "Block must contain only strings", "p-new-block") } } p := script.Slice(strs) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "p-new-block") } }, }, "echo": { Argsn: 1, Doc: "Creates a pipe object from a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s := arg0.(type) { case env.String: p := script.Echo(s.Value) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "p-new-echo") } }, }, "cat\\opt": { Argsn: 1, Doc: "Creates a pipe object from a file if it exists, otherwise returns an empty pipe object.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch path := arg0.(type) { case env.Uri: p := script.IfExists(path.GetPath()) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "p-new-if-exists") } }, }, "exec": { Argsn: 1, Doc: "Creates a pipe object from a command that is executed.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cmd := arg0.(type) { case env.String: p := script.Exec(cmd.Value) return *env.NewNative(ps.Idx, p, "script-pipe") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "p-new-exec") } }, }, "exec\\in": { Argsn: 2, Doc: "Executes a command by sending it the contents of the pipe as input and returns a pipe object.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch cmd := arg1.(type) { case env.String: newPipe := pipe.Exec(cmd.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-exec") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-exec") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-exec") } }, }, "exec\\each": { Argsn: 2, Doc: "Executes a command from a Go template for each line in the pipe and returns a pipe object with the output of each command.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch cmd := arg1.(type) { case env.String: newPipe := pipe.ExecForEach(cmd.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-exec-for-each") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-exec-for-each") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-exec-for-each") } }, }, "into-string": { Argsn: 1, Doc: "Returns pipe contents as a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: str, err := pipe.String() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "p-string") } return *env.NewString(str) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-string") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-string") } }, }, "into-file": { Argsn: 2, Doc: "Writes pipe contents to a file and returns the number of bytes written.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch path := arg1.(type) { case env.Uri: i, err := pipe.WriteFile(path.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "p-write-file") } return *env.NewInteger(i) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.UriType}, "p-write-file") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-write-file") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-write-file") } }, }, "out": { Argsn: 1, Doc: "Prints pipe contents to stdout and returns the number of bytes written.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: i, err := pipe.Stdout() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "p-stdout") } return *env.NewInteger(int64(i)) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-stdout") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-stdout") } }, }, "head": { Argsn: 2, Doc: "Returns a pipe with the first n lines from the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch n := arg1.(type) { case env.Integer: newPipe := pipe.First(int(n.Value)) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "p-first-n") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-first-n") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-first-n") } }, }, "tail": { Argsn: 2, Doc: "Returns a pipe with the last n lines from the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch n := arg1.(type) { case env.Integer: newPipe := pipe.Last(int(n.Value)) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "p-last-n") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-last-n") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-last-n") } }, }, "dirname": { Argsn: 1, Doc: "Reads paths from the pipe, one per line, and returns the directory component of each.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Dirname() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-dirname") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-dirname") } }, }, "basename": { Argsn: 1, Doc: "Reads paths from the pipe, one per line, and removes any leading directory components from each.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Basename() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-basename") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-basename") } }, }, "wc\\l": { Argsn: 1, Doc: "Returns the number of lines in a pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: n, err := pipe.CountLines() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "p-count-lines") } return *env.NewInteger(int64(n)) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-count-lines") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-count-lines") } }, }, "freq": { Argsn: 1, Doc: "Returns a pipe object with the frequency of each line in a pipe in descending order.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Freq() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-freq") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-freq") } }, }, "column": { Argsn: 2, Doc: "Returns a pipe object with the column of each line of input, where the first column is column 1, and columns are delimited by Unicode whitespace.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch n := arg1.(type) { case env.Integer: newPipe := pipe.Column(int(n.Value)) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "p-column") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-column") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-column") } }, }, "jq": { Argsn: 2, Doc: "Executes the jq command on the pipe whose contents are presumed to be JSON and returns a new pipe object with the output.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch jq := arg1.(type) { case env.String: newPipe := pipe.JQ(jq.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-jq") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-jq") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-jq") } }, }, "match": { Argsn: 2, Doc: "Returns a pipe object with lines that match the string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: newPipe := pipe.Match(s.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-match") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-match") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-match") } }, }, "match\\regex": { Argsn: 2, Doc: "Returns a pipe object with lines that match the regular expression.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch r := arg1.(type) { case env.Native: switch regxp := r.Value.(type) { case *regexp.Regexp: newPipe := pipe.MatchRegexp(regxp) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 2, []string{"regex"}, "p-match-regex") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "p-match-regex") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-match-regex") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-match-regex") } }, }, "not-match": { Argsn: 2, Doc: "Returns a pipe object with lines that do not match the string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: newPipe := pipe.Reject(s.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-not-match") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-not-match") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-not-match") } }, }, "not-match\\regex": { Argsn: 2, Doc: "Returns a pipe object with lines that do not match the regular expression.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch r := arg1.(type) { case env.Native: switch regxp := r.Value.(type) { case *regexp.Regexp: newPipe := pipe.RejectRegexp(regxp) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 2, []string{"regex"}, "p-not-match-regex") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "p-not-match-regex") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-not-match-regex") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-not-match-regex") } }, }, "replace": { Argsn: 3, Doc: "Replaces all occurrences of a string with another string in the pipe and returns a new pipe object.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch search := arg1.(type) { case env.String: switch replace := arg2.(type) { case env.String: newPipe := pipe.Replace(search.Value, replace.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "p-replace") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-replace") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-replace") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-replace") } }, }, "replace\\regex": { Argsn: 3, Doc: "Replaces all occurrences of strings that match the regex pattern with a string in the pipe and returns a new pipe object.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch searchR := arg1.(type) { case env.Native: switch searchRegexp := searchR.Value.(type) { case *regexp.Regexp: switch replace := arg2.(type) { case env.String: newPipe := pipe.ReplaceRegexp(searchRegexp, replace.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "p-replace-regex") } default: return evaldo.MakeNativeArgError(ps, 2, []string{"regex"}, "p-replace-regex") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "p-replace-regex") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-replace-regex") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-replace-regex") } }, }, "into-block": { Argsn: 1, Doc: "Returns a block of strings with the contents of the pipe, one per line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: lines, err := pipe.Slice() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "p-block") } items := make([]env.Object, len(lines)) for i, line := range lines { items[i] = *env.NewString(line) } return *env.NewBlock(*env.NewTSeries(items)) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-block") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-block") } }, }, "error\\opt": { Argsn: 1, Doc: "Returns the error from the pipe, if any.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: err := pipe.Error() if err != nil { return *env.NewError(err.Error()) } return env.Void{} default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-error") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-error") } }, }, "sha256sum": { Argsn: 1, Doc: "Returns the hex-encoded SHA-256 hash of the entire contents of the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: sha256, err := pipe.SHA256Sum() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "pipes/sha256sum") } return *env.NewString(sha256) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "pipes/sha256sum") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "pipes/sha256sum") } }, }, "sha256sums": { Argsn: 1, Doc: "Reads paths from the pipe, one per line, and produces the hex-encoded SHA-256 hash of each corresponding file, one per line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.SHA256Sums() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "pipes/sha256sums") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "pipes/sha256sums") } }, }, "decodeBase64": { Argsn: 1, Doc: "decodeBase64 produces the string represented by the base64 encoded input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.DecodeBase64() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "decodeBase64") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "decodeBase64") } }, }, "encodeBase64": { Argsn: 1, Doc: "encodeBase64 produces the base64 encoding of the input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.EncodeBase64() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "encodeBase64") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "encodeBase64") } }, }, "join": { Argsn: 1, Doc: "joins all the lines in the pipe's contents into a single space-separated string, which will always end with a newline.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Join() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-join") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-join") } }, }, "exit-status": { Argsn: 1, Doc: "Returns the integer exit status of a previous command. This will be zero unless the pipe's error status is set and the error matches the pattern.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: status := pipe.ExitStatus() return *env.NewInteger(int64(status)) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-exit-status") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-exit-status") } }, }, "args": { Argsn: 0, Doc: "Creates a pipe containing the program's command-line arguments from os.Args, excluding the program name, one per line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { newPipe := script.Args() return *env.NewNative(ps.Idx, newPipe, "script-pipe") }, }, "concat": { Argsn: 1, Doc: "concat reads paths from the pipe, one per line, and produces the contents of all the corresponding files in sequence. If there are any errors (for example, non-existent files), these will be ignored, execution will continue, and the pipe's error status will not be set.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Concat() return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-concat") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-concat") } }, }, "close": { Argsn: 1, Doc: "Closes the pipe's associated reader.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: closeErr := pipe.Close() if closeErr != nil { return *env.NewError("Error closing pipe") } return *env.NewInteger(0) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-close") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-close") } }, }, "get": { Argsn: 2, Doc: "Get makes an HTTP GET request to url, sending the contents of the pipe as the request body, and produces the server's response.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: newPipe := pipe.Get(s.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-get") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-get") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-get") } }, }, "post": { Argsn: 2, Doc: "Post makes an HTTP POST request to url, using the contents of the pipe as the request body, and produces the server's response.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: newPipe := pipe.Post(s.Value) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-post") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-post") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-post") } }, }, "new": { Argsn: 0, Doc: "new creates a new pipe with an empty reader.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { newPipe := script.NewPipe() return *env.NewNative(ps.Idx, newPipe, "script-pipe") }, }, "wait": { Argsn: 1, Doc: "Wait reads the pipe to completion and returns any error present on the pipe, or 0 otherwise..", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: waitErr := pipe.Wait() if waitErr != nil { return *env.NewError("Error in pipe during waiting") } return *env.NewInteger(0) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-wait") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-wait") } }, }, "append-to-file": { Argsn: 2, Doc: "append-to-file appends the contents of the pipe to the file path, creating it if necessary, and returns the number of bytes successfully written, or an error.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: writtenBytes, err := pipe.AppendFile(s.Value) if err != nil { return *env.NewError("Error while appending data to files.") } return *env.NewInteger(writtenBytes) case env.Uri: writtenBytes, err := pipe.AppendFile(s.Path) if err != nil { return *env.NewError("Error while appending data to rey-file.") } return *env.NewInteger(writtenBytes) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType, env.UriType}, "p-append-to-file") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-append-to-file") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-append-to-file") } }, }, "stdin": { Argsn: 0, Doc: "Stdin creates a pipe that reads from os.Stdin.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { newPipe := script.Stdin() return *env.NewNative(ps.Idx, newPipe, "script-pipe") }, }, "error": { Argsn: 1, Doc: "error - returns any error present on the pipe, or 0 otherwise.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: waitErr := pipe.Error() if waitErr != nil { return *env.NewError("Error in pipe: " + waitErr.Error()) } return *env.NewInteger(0) default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-error") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-error") } }, }, "set-error": { Argsn: 2, Doc: "set-error sets the error err on the pipe and return it.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch errStr := arg1.(type) { case env.String: err := errors.New(errStr.Value) pipe.SetError(err) return *env.NewNative(ps.Idx, pipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "p-set-error") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "p-set-error") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "p-set-error") } }, }, "extract\\regex": { Argsn: 2, Doc: "For each line in the pipe, extracts all regex matches (capture group 1 if present, otherwise the whole match) and outputs each match on a separate line. Equivalent to grep -oP with a capture group.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch r := arg1.(type) { case env.Native: switch rx := r.Value.(type) { case *regexp.Regexp: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) for scanner.Scan() { line := scanner.Text() matches := rx.FindAllStringSubmatch(line, -1) for _, match := range matches { if len(match) > 1 { fmt.Fprintln(w, match[1]) } else { fmt.Fprintln(w, match[0]) } } } return scanner.Err() }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 2, []string{"regex"}, "extract\\regex") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "extract\\regex") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "extract\\regex") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "extract\\regex") } }, }, "sort": { Argsn: 1, Doc: "Sorts the lines of the pipe alphabetically in ascending order.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) var lines []string for scanner.Scan() { lines = append(lines, scanner.Text()) } if err := scanner.Err(); err != nil { return err } sort.Strings(lines) for _, line := range lines { fmt.Fprintln(w, line) } return nil }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "sort") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "sort") } }, }, "sort\\reverse": { Argsn: 1, Doc: "Sorts the lines of the pipe alphabetically in descending (reverse) order.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) var lines []string for scanner.Scan() { lines = append(lines, scanner.Text()) } if err := scanner.Err(); err != nil { return err } sort.Sort(sort.Reverse(sort.StringSlice(lines))) for _, line := range lines { fmt.Fprintln(w, line) } return nil }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "sort\\reverse") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "sort\\reverse") } }, }, "uniq": { Argsn: 1, Doc: "Removes consecutive duplicate lines from the pipe, like the Unix uniq command. Combine with sort to remove all duplicates.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) last := "" first := true for scanner.Scan() { line := scanner.Text() if first || line != last { fmt.Fprintln(w, line) last = line first = false } } return scanner.Err() }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "uniq") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "uniq") } }, }, "trim-lines": { Argsn: 1, Doc: "Trims leading and trailing whitespace from each line in the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.FilterLine(func(line string) string { return strings.TrimSpace(line) }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "trim-lines") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "trim-lines") } }, }, "prefix-lines": { Argsn: 2, Doc: "Prepends a string to the beginning of each line in the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch prefix := arg1.(type) { case env.String: newPipe := pipe.FilterLine(func(line string) string { return prefix.Value + line }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "prefix-lines") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "prefix-lines") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "prefix-lines") } }, }, "skip": { Argsn: 2, Doc: "Skips the first n lines from the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch n := arg1.(type) { case env.Integer: skipCount := int(n.Value) newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) lineNum := 0 for scanner.Scan() { lineNum++ if lineNum > skipCount { fmt.Fprintln(w, scanner.Text()) } } return scanner.Err() }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "skip") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "skip") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "skip") } }, }, "number-lines": { Argsn: 1, Doc: "Prefixes each line with its line number (1-indexed).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) lineNum := 0 for scanner.Scan() { lineNum++ fmt.Fprintf(w, "%d: %s\n", lineNum, scanner.Text()) } return scanner.Err() }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "number-lines") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "number-lines") } }, }, "count-matches": { Argsn: 2, Doc: "Counts the number of lines containing the given string. This is a sink operation that consumes the pipe.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch s := arg1.(type) { case env.String: lines, err := pipe.Slice() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "count-matches") } count := 0 for _, line := range lines { if strings.Contains(line, s.Value) { count++ } } return *env.NewInteger(int64(count)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "count-matches") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "count-matches") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "count-matches") } }, }, "between": { Argsn: 3, Doc: "Returns lines between start and end marker lines (exclusive). Can handle multiple ranges.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch startStr := arg1.(type) { case env.String: switch endStr := arg2.(type) { case env.String: newPipe := pipe.Filter(func(r io.Reader, w io.Writer) error { scanner := bufio.NewScanner(r) inside := false for scanner.Scan() { line := scanner.Text() if strings.Contains(line, endStr.Value) { inside = false continue } if inside { fmt.Fprintln(w, line) } if strings.Contains(line, startStr.Value) { inside = true } } return scanner.Err() }) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "between") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "between") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "between") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "between") } }, }, "tee\\file": { Argsn: 2, Doc: "Writes the pipe contents to a file while also passing them through. Like the Unix tee command.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch path := arg1.(type) { case env.Uri: file, err := os.Create(path.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "tee\\file") } newPipe := pipe.Tee(file) return *env.NewNative(ps.Idx, newPipe, "script-pipe") case env.String: file, err := os.Create(path.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "tee\\file") } newPipe := pipe.Tee(file) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.UriType, env.StringType}, "tee\\file") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "tee\\file") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tee\\file") } }, }, "map-each": { Argsn: 2, Doc: "Transforms each line by evaluating a Rye block with the line injected. The block should return a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch block := arg1.(type) { case env.Block: lines, err := pipe.Slice() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "map-each") } result := make([]string, 0, len(lines)) ser := ps.Ser for _, line := range lines { ps.Ser = block.Series ps.Ser.SetPos(0) evaldo.EvalBlockInj(ps, *env.NewString(line), true) if ps.ErrorFlag { ps.Ser = ser return evaldo.MakeBuiltinError(ps, "Error during evaluation of block", "map-each") } if ps.FailureFlag { ps.Ser = ser return ps.Res } switch res := ps.Res.(type) { case env.String: result = append(result, res.Value) default: result = append(result, ps.Res.Print(*ps.Idx)) } } ps.Ser = ser newPipe := script.Slice(result) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "map-each") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "map-each") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "map-each") } }, }, "filter-each": { Argsn: 2, Doc: "Filters lines by evaluating a Rye block with each line injected. Only lines for which the block returns truthy are kept.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: switch pipe := p.Value.(type) { case *script.Pipe: switch block := arg1.(type) { case env.Block: lines, err := pipe.Slice() if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "filter-each") } result := make([]string, 0) ser := ps.Ser for _, line := range lines { ps.Ser = block.Series ps.Ser.SetPos(0) evaldo.EvalBlockInj(ps, *env.NewString(line), true) if ps.ErrorFlag { ps.Ser = ser return evaldo.MakeBuiltinError(ps, "Error during evaluation of block", "filter-each") } if ps.FailureFlag { ps.Ser = ser return ps.Res } if util.IsTruthy(ps.Res) { result = append(result, line) } } ps.Ser = ser newPipe := script.Slice(result) return *env.NewNative(ps.Idx, newPipe, "script-pipe") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "filter-each") } default: return evaldo.MakeNativeArgError(ps, 1, []string{"script-pipe"}, "filter-each") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "filter-each") } }, }, }
var Builtins_prometheus = map[string]*env.Builtin{
"new-counter": {
Argsn: 3,
Doc: "Creates a new Prometheus counter with the given name, help text, and optional labels.",
Fn: __prometheus_new_counter,
},
"prometheus-counter//Inc": {
Argsn: 1,
Doc: "Increments a Prometheus counter by 1.",
Fn: __prometheus_counter_inc,
},
"prometheus-counter//Add": {
Argsn: 2,
Doc: "Adds the given value to a Prometheus counter.",
Fn: __prometheus_counter_add,
},
"new-gauge": {
Argsn: 3,
Doc: "Creates a new Prometheus gauge with the given name, help text, and optional labels.",
Fn: __prometheus_new_gauge,
},
"prometheus-gauge//Set": {
Argsn: 2,
Doc: "Sets a Prometheus gauge to the given value.",
Fn: __prometheus_gauge_set,
},
"prometheus-gauge//Inc": {
Argsn: 1,
Doc: "Increments a Prometheus gauge by 1.",
Fn: __prometheus_gauge_inc,
},
"prometheus-gauge//Dec": {
Argsn: 1,
Doc: "Decrements a Prometheus gauge by 1.",
Fn: __prometheus_gauge_dec,
},
"prometheus-gauge//Add": {
Argsn: 2,
Doc: "Adds the given value to a Prometheus gauge.",
Fn: __prometheus_gauge_add,
},
"prometheus-gauge//Sub": {
Argsn: 2,
Doc: "Subtracts the given value from a Prometheus gauge.",
Fn: __prometheus_gauge_sub,
},
"new-histogram": {
Argsn: 4,
Doc: "Creates a new Prometheus histogram with the given name, help text, optional buckets, and optional labels.",
Fn: __prometheus_new_histogram,
},
"prometheus-histogram//Observe": {
Argsn: 2,
Doc: "Observes the given value in a Prometheus histogram.",
Fn: __prometheus_histogram_observe,
},
"new-summary": {
Argsn: 4,
Doc: "Creates a new Prometheus summary with the given name, help text, optional objectives, and optional labels.",
Fn: __prometheus_new_summary,
},
"prometheus-summary//Observe": {
Argsn: 2,
Doc: "Observes the given value in a Prometheus summary.",
Fn: __prometheus_summary_observe,
},
"start-http-server": {
Argsn: 1,
Doc: "Starts a Prometheus HTTP server on the given address (e.g., ':8080').",
Fn: __prometheus_start_http_server,
},
"new-mutex": {
Argsn: 0,
Doc: "Creates a new mutex for protecting metrics from concurrent access.",
Fn: __prometheus_new_mutex,
},
"prometheus-mutex//Lock": {
Argsn: 1,
Doc: "Locks a mutex.",
Fn: __prometheus_mutex_lock,
},
"prometheus-mutex//Unlock": {
Argsn: 1,
Doc: "Unlocks a mutex.",
Fn: __prometheus_mutex_unlock,
},
"must-register": {
Argsn: 1,
Doc: "Registers a Prometheus collector using MustRegister. Will panic if registration fails.",
Fn: __prometheus_must_register,
},
"handler": {
Argsn: 0,
Doc: "Returns a Prometheus HTTP handler for custom HTTP server setups.",
Fn: __prometheus_handler,
},
}
Map of Prometheus builtins
var Builtins_psql = map[string]*env.Builtin{ "postgres-uri//Open": { Argsn: 1, Doc: "Opens a connection to a PostgreSQL database.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.Uri: db, err := sql.Open("postgres", "postgresql://"+str.Path) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error opening PostgreSQL: %v", err.Error()), "postgres-uri//Open") } if err := db.Ping(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error connecting to PostgreSQL: %v", err.Error()), "postgres-uri//Open") } return *env.NewNative(ps.Idx, db, "Rye-psql") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "postgres-uri//Open") } }, }, "Rye-psql//Exec": { Argsn: 2, Doc: "Executes a SQL statement that modifies data (INSERT, UPDATE, DELETE).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0, 2) _, vals = SQL_EvalBlock(ps, MODE_PSQL, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: ps.ErrorFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-psql//Exec") } if sqlstr != "" { db2 := db1.Value.(*sql.DB) res, err := db2.Exec(sqlstr, vals...) if err != nil { ps.FailureFlag = true return env.NewError("Error" + err.Error()) } else { num, _ := res.RowsAffected() return *env.NewInteger(num) } } else { return evaldo.MakeBuiltinError(ps, "Sql string is empty.", "Rye-psql//Exec") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-psql//Exec") } }, }, "Rye-psql//Query": { Argsn: 2, Doc: "Executes a SQL query and returns results as a table.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0, 2) _, vals = SQL_EvalBlock(ps, MODE_PSQL, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: ps.ErrorFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-psql//Query") } if sqlstr != "" { rows, err := db1.Value.(*sql.DB).Query(sqlstr, vals...) if err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-psql//Query") } else { cols, _ := rows.Columns() spr := env.NewTable(cols) i := 0 for rows.Next() { var sr env.TableRow columns := make([]any, len(cols)) columnPointers := make([]any, len(cols)) for i := range columns { columnPointers[i] = &columns[i] } if err := rows.Scan(columnPointers...); err != nil { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "Error scanning row: "+err.Error(), "Rye-psql//Query") } m := make(map[string]any) for i, colName := range cols { val := columnPointers[i].(*any) // Convert nil (SQL NULL) values to Void{} for proper Rye handling var ryeVal env.Object if *val == nil { ryeVal = env.Void{} } else { ryeVal = env.ToRyeValue(*val) } m[colName] = ryeVal sr.Values = append(sr.Values, ryeVal) } spr.AddRow(sr) i++ } rows.Close() if i == 0 { ps.FailureFlag = true return evaldo.MakeBuiltinError(ps, "No data.", "Rye-psql//Query") } return *spr } } else { return evaldo.MakeBuiltinError(ps, "Empty SQL.", "Rye-psql//Query") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-psql//Query") } }, }, "Rye-psql//Show-SQL": { Argsn: 2, Doc: "Generates and returns the SQL string without executing it.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0, 2) _, vals = SQL_EvalBlock(ps, MODE_PSQL, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: ps.ErrorFlag = true return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-psql//Show-SQL") } if sqlstr != "" { if len(vals) > 0 { result := sqlstr + "\n-- Parameters: " for i, val := range vals { if i > 0 { result += ", " } result += fmt.Sprintf("$%d = %v", i+1, val) } return *env.NewString(result) } return *env.NewString(sqlstr) } else { return evaldo.MakeBuiltinError(ps, "Empty SQL.", "Rye-psql//Show-SQL") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-psql//Show-SQL") } }, }, "Rye-psql//Close": { Argsn: 1, Doc: "Closes the PostgreSQL database connection.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch db := arg0.(type) { case env.Native: psqlKind, _ := ps.Idx.GetIndex("Rye-psql") if db.Kind.Index != psqlKind { return evaldo.MakeBuiltinError(ps, "Expected PostgreSQL database connection.", "Rye-psql//Close") } sqlDB, ok := db.Value.(*sql.DB) if !ok { return evaldo.MakeBuiltinError(ps, "Invalid database connection.", "Rye-psql//Close") } err := sqlDB.Close() if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error closing database: %v", err.Error()), "Rye-psql//Close") } return *env.NewInteger(1) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-psql//Close") } }, }, }
var Builtins_regex = map[string]*env.Builtin{ "regex": { Argsn: 1, Doc: "Creates a compiled regular expression object from a pattern string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s := arg0.(type) { case env.String: val, err := regexp.Compile(s.Value) if err != nil { return evaldo.MakeError(ps, err.Error()) } return *env.NewNative(ps.Idx, val, "regex") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "regex") } }, }, "re": { Argsn: 1, Doc: "Creates a compiled regular expression object from a pattern string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s := arg0.(type) { case env.String: val, err := regexp.Compile(s.Value) if err != nil { return evaldo.MakeError(ps, err.Error()) } return *env.NewNative(ps.Idx, val, "regex") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "regex") } }, }, "regex//Is-match": { Argsn: 2, Doc: "Tests if a string matches the regular expression pattern.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).MatchString(val.Value) if res { return *env.NewBoolean(true) } else { return *env.NewBoolean(false) } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "regex//Is-match") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "regex//Is-match") } }, }, "regex//Submatch?": { Argsn: 2, Doc: "Extracts the first captured group from a string using the regular expression.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).FindStringSubmatch(val.Value) if len(res) > 1 { return *env.NewString(res[1]) } else { return evaldo.MakeBuiltinError(ps, "No submatch.", "regex//Submatch?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "regex//Submatch?") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "regex//Submatch?") } }, }, "regex//Submatches?": { Argsn: 2, Doc: "Extracts all captured groups from the first match as a block of strings.", Fn: func(env1 *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).FindStringSubmatch(val.Value) if len(res) > 0 { col1 := make([]env.Object, len(res)-1) for i, row := range res { if i > 0 { col1[i-1] = *env.NewString(row) } } return *env.NewBlock(*env.NewTSeries(col1)) } return evaldo.MakeBuiltinError(env1, "No results", "Submatches?") default: return evaldo.MakeError(env1, "Arg2 not Native") } default: return evaldo.MakeError(env1, "Arg1 not String") } }, }, "regex//Submatches\\all?": { Argsn: 2, Doc: "Extracts all captured groups from all matches as a nested block structure.", Fn: func(env1 *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).FindAllStringSubmatch(val.Value, -1) if len(res) > 0 { blks := make([]env.Object, len(res)) for i, mtch := range res { strs := make([]env.Object, len(mtch)-1) for j, row := range mtch { if j > 0 { strs[j-1] = *env.NewString(row) } } blks[i] = *env.NewBlock(*env.NewTSeries(strs)) } return *env.NewBlock(*env.NewTSeries(blks)) } return evaldo.MakeBuiltinError(env1, "No results", "Submatches?") default: return evaldo.MakeError(env1, "Arg2 not Native") } default: return evaldo.MakeError(env1, "Arg1 not String") } }, }, "regex//Find-all": { Argsn: 2, Doc: "Finds all substrings matching the regular expression and returns them as a block.", Fn: func(env1 *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).FindAllString(val.Value, -1) if len(res) > 0 { col1 := make([]env.Object, len(res)) for i, row := range res { col1[i] = *env.NewString(row) } return *env.NewBlock(*env.NewTSeries(col1)) } return evaldo.MakeBuiltinError(env1, "No results", "Find-all") default: return evaldo.MakeError(env1, "Arg2 not Native") } default: return evaldo.MakeError(env1, "Arg1 not String") } }, }, "regex//Match?": { Argsn: 2, Doc: "Finds the first substring matching the regular expression.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg1.(type) { case env.String: switch s := arg0.(type) { case env.Native: res := s.Value.(*regexp.Regexp).FindString(val.Value) if len(res) > 0 { return *env.NewString(res) } return evaldo.MakeBuiltinError(ps, "No result", "Match?") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "regex//Match?") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "regex//Match?") } }, }, "regex//Replace-all": { Argsn: 3, Doc: "Replaces all occurrences of the regular expression pattern with the specified replacement string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch re := arg0.(type) { case env.Native: switch val := arg1.(type) { case env.String: switch replac := arg2.(type) { case env.String: res := re.Value.(*regexp.Regexp).ReplaceAllString(val.Value, replac.Value) return *env.NewString(res) default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "regex//Replace-all") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "regex//Replace-all") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "regex//Replace-all") } }, }, }
var Builtins_smtpd = map[string]*env.Builtin{ "smtp-server": { Argsn: 1, Doc: "Creates a new SMTP server that can receive incoming email messages on the specified address.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewNative(ps.Idx, arg0, "smtpd") }, }, "smtpd//Serve": { Argsn: 4, Doc: "Starts the SMTP server listening for incoming emails and calls the handler function for each received message.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch server := arg0.(type) { case env.Native: switch handler := arg1.(type) { case env.Function: switch name := arg2.(type) { case env.String: err := smtpd.ListenAndServe(server.Value.(env.String).Value, func(origin net.Addr, from string, to []string, data []byte) error { ps.FailureFlag = false ps.ErrorFlag = false ps.ReturnFlag = false psTemp := env.ProgramState{} err := copier.Copy(&psTemp, &ps) if err != nil { fmt.Println(err.Error()) } lstTo := make([]any, len(to)) for i, v := range to { lstTo[i] = v } evaldo.CallFunctionArgs4(handler, ps, *env.NewNative(ps.Idx, bytes.NewReader(data), "reader"), env.NewString(from), *env.NewList(lstTo), *env.NewNative(ps.Idx, origin, "new-addr"), nil) return nil }, name.Value, "") if err != nil { return evaldo.MakeError(ps, err.Error()) } return arg0 default: return evaldo.MakeArgError(ps, 3, []env.Type{env.StringType}, "smtpd//serve") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.FunctionType}, "smtpd//serve") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "smtpd//serve") } }, }, }
var Builtins_sqlite = map[string]*env.Builtin{ "sqlite-uri//Open": { Argsn: 1, Doc: "Opens a connection to a SQLite database file.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.Uri: db, err := sql.Open("sqlite", str.GetPath()) if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error opening SQLite: %v", err.Error()), "sqlite-uri//Open") } if err := db.Ping(); err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error connecting to SQLite: %v", err.Error()), "sqlite-uri//Open") } return *env.NewNative(ps.Idx, db, "Rye-sqlite") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.UriType}, "sqlite-uri//Open") } }, }, "htmlize": { Argsn: 1, Doc: "Converts a table to HTML format.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch str := arg0.(type) { case env.Table: return *env.NewString(str.ToHtml()) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.TableType}, "htmlize") } }, }, "Rye-sqlite//Exec": { Argsn: 2, Doc: "Executes a SQL statement that doesn't return rows.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0) _, vals = SQL_EvalBlock(ps, MODE_SQLITE, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-sqlite//Exec") } if sqlstr != "" { db2 := db1.Value.(*sql.DB) _, err := db2.Exec(sqlstr, vals...) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-sqlite//Exec") } return arg0 } else { return evaldo.MakeBuiltinError(ps, "sql string not found.", "Rye-sqlite//Exec") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-sqlite//Exec") } }, }, "Rye-sqlite//Query": { Argsn: 2, Doc: "Executes a SQL query and returns results as a table.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any paramToAny := func(o env.Object) any { switch v := o.(type) { case env.Getword: val, _ := ps.Ctx.Get(v.Index) return sqlResultToJS(val) case env.Word: val, _ := ps.Ctx.Get(v.Index) return sqlResultToJS(val) case env.String: return v.Value case *env.String: return v.Value case env.Integer: return v.Value case *env.Integer: return v.Value case env.Decimal: return v.Value case *env.Decimal: return v.Value case env.Boolean: return v.Value case *env.Boolean: return v.Value case env.Void: return nil default: return sqlResultToJS(o) } } switch db1 := arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: if str.Series.Len() > 0 { first := str.Series.Get(0) if s, ok := first.(env.String); ok { sqlstr = s.Value for i := 1; i < str.Series.Len(); i++ { p := str.Series.Get(i) if _, isComma := p.(env.Comma); isComma { continue } vals = append(vals, paramToAny(p)) } } else { ser := ps.Ser ps.Ser = str.Series values := make([]any, 0) _, vals = SQL_EvalBlock(ps, MODE_SQLITE, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser } } else { return evaldo.MakeBuiltinError(ps, "Sql block is empty.", "Rye-sqlite//Query") } case env.String: sqlstr = str.Value default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-sqlite//Query") } if sqlstr != "" { rows, err := db1.Value.(*sql.DB).Query(sqlstr, vals...) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Rye-sqlite//Query") } columns, _ := rows.Columns() spr := env.NewTable(columns) if err != nil { fmt.Println(err.Error()) } else { cols, _ := rows.Columns() for rows.Next() { var sr env.TableRow columns := make([]any, len(cols)) columnPointers := make([]any, len(cols)) for i := range columns { columnPointers[i] = &columns[i] } if err := rows.Scan(columnPointers...); err != nil { return env.NewError(err.Error()) } m := make(map[string]any) for i, colName := range cols { val := columnPointers[i].(*any) // Convert nil (SQL NULL) values to Void{} for proper Rye handling var ryeVal env.Object if *val == nil { ryeVal = env.Void{} } else { ryeVal = env.ToRyeValue(*val) } m[colName] = ryeVal sr.Values = append(sr.Values, ryeVal) sr.Uplink = spr } spr.AddRow(sr) } rows.Close() return *spr } return evaldo.MakeBuiltinError(ps, "Empty SQL.", "Rye-sqlite//Query") } else { return evaldo.MakeBuiltinError(ps, "Sql string not found.", "Rye-sqlite//Query") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-sqlite//Query") } }, }, "Rye-sqlite//Show-SQL": { Argsn: 2, Doc: "Generates and returns the SQL string without executing it.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var sqlstr string var vals []any switch arg0.(type) { case env.Native: switch str := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = str.Series values := make([]any, 0) _, vals = SQL_EvalBlock(ps, MODE_SQLITE, values) sqlstr = ps.Res.(env.String).Value ps.Ser = ser case env.String: sqlstr = str.Value default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType, env.StringType}, "Rye-sqlite//Show-SQL") } if sqlstr != "" { if len(vals) > 0 { result := sqlstr + "\n-- Parameters: " for i, val := range vals { if i > 0 { result += ", " } result += fmt.Sprintf("? = %v", val) } return *env.NewString(result) } return *env.NewString(sqlstr) } else { return evaldo.MakeBuiltinError(ps, "Empty SQL.", "Rye-sqlite//Show-SQL") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-sqlite//Show-SQL") } }, }, "Rye-sqlite//Close": { Argsn: 1, Doc: "Closes the SQLite database connection.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch db := arg0.(type) { case env.Native: sqliteKind, _ := ps.Idx.GetIndex("Rye-sqlite") if db.Kind.Index != sqliteKind { return evaldo.MakeBuiltinError(ps, "Expected SQLite database connection.", "Rye-sqlite//Close") } sqlDB, ok := db.Value.(*sql.DB) if !ok { return evaldo.MakeBuiltinError(ps, "Invalid database connection.", "Rye-sqlite//Close") } err := sqlDB.Close() if err != nil { return evaldo.MakeBuiltinError(ps, fmt.Sprintf("Error closing database: %v", err.Error()), "Rye-sqlite//Close") } return *env.NewInteger(1) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "Rye-sqlite//Close") } }, }, }
var Builtins_ssh = map[string]*env.Builtin{}
var Builtins_stackless = map[string]*env.Builtin{ "ry0": { Argsn: 1, Doc: "TODODOC", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg0.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series Stck_EvalBlock(ps) ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "ry0") } }, }, "ry0-loop": { Argsn: 2, Doc: "TODODOC", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cond := arg0.(type) { case env.Integer: switch bloc := arg1.(type) { case env.Block: ser := ps.Ser ps.Ser = bloc.Series for i := 0; int64(i) < cond.Value; i++ { ps = Stck_EvalBlock(ps) ps.Ser.Reset() } ps.Ser = ser return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "ry0-loop") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "ry0-loop") } }, }, }
var Builtins_structures = map[string]*env.Builtin{ "dict->struct": { Argsn: 2, Doc: "Converts a Rye Dict to a Go struct using reflection. Takes a Dict and a Native containing a pointer to a struct.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch dict := arg0.(type) { case env.Dict: switch native := arg1.(type) { case env.Native: return dictToStruct(ps, dict, native.Value) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "dict->struct") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.DictType}, "dict->struct") } }, }, "dict->new-struct": { Argsn: 2, Doc: "Creates a new Go struct type at runtime based on a Rye Dict and populates it with values. Takes a Dict and a string for the struct name.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch dict := arg0.(type) { case env.Dict: switch nameObj := arg1.(type) { case env.String: structPtr, err := dictToNewStruct(ps, dict, nameObj.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "dict->new-struct") } return *env.NewNative(ps.Idx, structPtr, nameObj.Value) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "dict->new-struct") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.DictType}, "dict->new-struct") } }, }, "struct->dict": { Argsn: 1, Doc: "Converts a Go struct to a Rye Dict using reflection. Takes a Native containing a struct or pointer to a struct.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch native := arg0.(type) { case env.Native: return structToDict(ps, native.Value) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "struct->dict") } }, }, "process": { Argsn: 2, Doc: "TODODOC", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { rm, err := load_structures_Dict(ps, arg1.(env.Block)) if err != nil { ps.FailureFlag = true return err } switch data := arg0.(type) { case env.Dict: return do_structures(ps, data, rm) } return nil }, }, }
var Builtins_sxml = map[string]*env.Builtin{ "reader//Do-sxml": { Argsn: 2, Doc: "Processes XML with streaming tag handlers. [ ] runs code, { } nests rules, and ( 'command , ... ) projects values with put, put-key, append-key, merge-key, sub-block, attach, append, and merge.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { reader, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "reader//Do-sxml") } ioReader, ok := reader.Value.(io.Reader) if !ok { return evaldo.MakeBuiltinError(ps, "reader native does not implement io.Reader", "reader//Do-sxml") } block, ok := arg1.(env.Block) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "reader//Do-sxml") } rm, err := load_saxml_Dict(ps, block) if err != nil { ps.FailureFlag = true return err } return do_sxml(ps, ioReader, rm) }, }, "rye-sxml-start//Attr?": { Argsn: 2, Doc: "Retrieves an attribute by index or name from an XML start element.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch obj := arg0.(type) { case env.Native: switch obj1 := obj.Value.(type) { case xml.StartElement: switch n := arg1.(type) { case env.Integer: if n.Value >= 0 && int(n.Value) < len(obj1.Attr) { attr := obj1.Attr[int(n.Value)] return *env.NewList([]any{ *env.NewString(attr.Name.Space), *env.NewString(attr.Name.Local), *env.NewString(attr.Value), }) } else { return evaldo.MakeBuiltinError(ps, "Attribute index out of bounds.", "rye-sxml-start//Attr?") } case env.Word: attrName := ps.Idx.GetWord(n.Index) for _, attr := range obj1.Attr { if attr.Name.Local == attrName { return *env.NewString(attr.Value) } } return evaldo.MakeBuiltinError(ps, "Attribute '"+attrName+"' not found.", "rye-sxml-start//Attr?") case env.String: attrName := n.Value namespaceAndName := strings.Split(attrName, ":") if len(namespaceAndName) == 2 { targetNS := namespaceAndName[0] targetLocal := namespaceAndName[1] for _, attr := range obj1.Attr { if attr.Name.Space == targetNS && attr.Name.Local == targetLocal { return *env.NewString(attr.Value) } } } else { for _, attr := range obj1.Attr { if attr.Name.Local == attrName { return *env.NewString(attr.Value) } } } return evaldo.MakeBuiltinError(ps, "Attribute '"+attrName+"' not found.", "rye-sxml-start//Attr?") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType, env.WordType, env.StringType}, "rye-sxml-start//Attr?") } default: return evaldo.MakeBuiltinError(ps, "Not xml-start element.", "rye-sxml-start//Attr?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "rye-sxml-start//Attr?") } }, }, "rye-sxml-start//Attrs?": { Argsn: 1, Doc: "Returns a dict of all attributes from an XML start element.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch obj := arg0.(type) { case env.Native: switch obj1 := obj.Value.(type) { case xml.StartElement: data := make(map[string]any) for _, attr := range obj1.Attr { var key string if attr.Name.Space != "" { key = attr.Name.Space + ":" + attr.Name.Local } else { key = attr.Name.Local } data[key] = *env.NewString(attr.Value) } return *env.NewDict(data) default: return evaldo.MakeBuiltinError(ps, "Not xml-start element.", "rye-sxml-start//Attrs?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "rye-sxml-start//Attrs?") } }, }, "rye-sxml-start//Name?": { Argsn: 1, Doc: "Returns the local name of an XML start or end element.", Fn: sxmlElementName, }, "rye-sxml-end//Name?": { Argsn: 1, Doc: "Returns the local name of an XML end element.", Fn: sxmlElementName, }, }
var Builtins_telegrambot = map[string]*env.Builtin{ "bot": { Argsn: 1, Doc: "Create new telegram bot using API value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch arg := arg0.(type) { case env.String: bot, err := tgm.NewBotAPI(arg.Value) if err != nil { return evaldo.MakeBuiltinError(ps, "Error in NewBotAPI function.", "new-telegram-bot") } return *env.NewNative(ps.Idx, bot, "telegram-bot") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "new-telegram-bot") } }, }, "telegram-bot//on-update": { Argsn: 2, Doc: "Get telegram update and add to Rye dictionary", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bot := arg0.(type) { case env.Native: switch code := arg1.(type) { case env.Block: u := tgm.NewUpdate(0) u.Timeout = 60 updates, _ := bot.Value.(*tgm.BotAPI).GetUpdatesChan(u) ser := ps.Ser ps.Ser = code.Series for update := range updates { dict := TelegramUpdateToRyeDict(update) evaldo.EvalBlockInj(ps, dict, true) if ps.ErrorFlag { ps.Ser = ser return ps.Res } ps.Ser.Reset() } ps.Ser = ser return env.NewInteger(1) case env.Function: u := tgm.NewUpdate(0) u.Timeout = 60 updates, _ := bot.Value.(*tgm.BotAPI).GetUpdatesChan(u) for update := range updates { dict := TelegramUpdateToRyeDict(update) ps.FailureFlag = false ps.ErrorFlag = false ps.ReturnFlag = false psTemp := env.ProgramState{} err := copier.Copy(&psTemp, &ps) if err != nil { fmt.Println(err.Error()) } evaldo.CallFunctionArgsN(code, ps, nil, dict) } return env.NewInteger(1) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "telegram-bot//on-update") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "telegram-bot//on-update") } }, }, "telegram-message//send": { Argsn: 2, Doc: "Send message in telegram bot.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch msg := arg0.(type) { case env.Native: switch bot := arg1.(type) { case env.Native: _, err := bot.Value.(*tgm.BotAPI).Send(msg.Value.(*tgm.MessageConfig)) if err != nil { return evaldo.MakeError(ps, err.Error()) } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "telegram-message//send") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "telegram-message//send") } }, }, "telegram-message//parse-mode!": { Argsn: 2, Doc: "Set the parse mode of the message", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch msg := arg0.(type) { case env.Native: switch mode := arg1.(type) { case env.String: message, _ := msg.Value.(tgm.MessageConfig) message.ParseMode = mode.Value return msg default: return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "telegram-message//send") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "telegram-message//send") } }, }, "message": { Argsn: 2, Doc: "Create new telegram bot message.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch cid := arg0.(type) { case env.Integer: switch txt := arg1.(type) { case env.String: msg := tgm.NewMessage(cid.Value, txt.Value) msg.ParseMode = "HTML" return *env.NewNative(ps.Idx, &msg, "telegram-message") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "new-telegram-message") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "new-telegram-message") } }, }, }
var Builtins_term = map[string]*env.Builtin{ "clear-line": { Argsn: 0, Doc: "Clears the current terminal line.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ClearLine() return *env.NewInteger(1) }, }, "cursor-up": { Argsn: 1, Doc: "Moves the cursor up by the specified number of lines.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch lines := arg0.(type) { case env.Integer: if lines.Value > 0 { fmt.Printf("\033[%dA", lines.Value) } return *env.NewInteger(1) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "cursor-up") } }, }, "cursor-down": { Argsn: 1, Doc: "Moves the cursor down by the specified number of lines.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch lines := arg0.(type) { case env.Integer: if lines.Value > 0 { fmt.Printf("\033[%dB", lines.Value) } return *env.NewInteger(1) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "cursor-down") } }, }, "clear-down": { Argsn: 0, Doc: "Clears from the cursor position to the bottom of the screen.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fmt.Print("\033[J") return *env.NewInteger(1) }, }, "clear-screen": { Argsn: 0, Doc: "Clears the entire screen.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fmt.Print("\033[2J\033[H") return *env.NewInteger(1) }, }, "hide-cursor": { Argsn: 0, Doc: "Hides the terminal cursor.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fmt.Print("\033[?25l") return *env.NewInteger(1) }, }, "show-cursor": { Argsn: 0, Doc: "Shows the terminal cursor.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fmt.Print("\033[?25h") return *env.NewInteger(1) }, }, "wrap": { Argsn: 2, Doc: "Wraps a string to a specified width by inserting newlines.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "wrap") } wdth, ok := arg1.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "wrap") } mkd := wrap.String(text.Value, int(wdth.Value)) return *env.NewString(mkd) }, }, "wrap\\words": { Argsn: 2, Doc: "Wraps a string to a specified width, preserving word boundaries.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "wrap\\words") } wdth, ok := arg1.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "wrap\\words") } mkd := wordwrap.String(text.Value, int(wdth.Value)) return *env.NewString(mkd) }, }, "indent": { Argsn: 2, Doc: "Indents each line of a string by a specified number of spaces.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { text, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "indent") } wdth, ok := arg1.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "indent") } mkd := indent.String(text.Value, uint(wdth.Value)) return *env.NewString(mkd) }, }, "width?": { Argsn: 0, Doc: "Returns the current width of the terminal in characters.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { fd := int(os.Stdout.Fd()) width, _, err := goterm.GetSize(fd) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "width?") } return env.NewInteger(int64(width)) }, }, "black": { Argsn: 0, Doc: "Sets terminal text color to black.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBlack() return env.NewInteger(1) }, }, "red": { Argsn: 0, Doc: "Sets terminal text color to red.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorRed() return env.NewInteger(1) }, }, "blue": { Argsn: 0, Doc: "Sets terminal text color to blue.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBlue() return env.NewInteger(1) }, }, "green": { Argsn: 0, Doc: "Sets terminal text color to green.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorGreen() return env.NewInteger(1) }, }, "yellow": { Argsn: 0, Doc: "Sets terminal text color to yellow.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorYellow() return env.NewInteger(1) }, }, "magenta": { Argsn: 0, Doc: "Sets terminal text color to magenta.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorMagenta() return env.NewInteger(1) }, }, "cyan": { Argsn: 0, Doc: "Sets terminal text color to cyan.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBlue() return env.NewInteger(1) }, }, "white": { Argsn: 0, Doc: "Sets terminal text color to white.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorWhite() return env.NewInteger(1) }, }, "str\\black": { Argsn: 0, Doc: "Returns ANSI escape code string for black text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBlack()) }, }, "str\\red": { Argsn: 0, Doc: "Returns ANSI escape code string for red text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorRed()) }, }, "str\\blue": { Argsn: 0, Doc: "Returns ANSI escape code string for blue text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBlue()) }, }, "str\\green": { Argsn: 0, Doc: "Returns ANSI escape code string for green text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorGreen()) }, }, "str\\yellow": { Argsn: 0, Doc: "Returns ANSI escape code string for yellow text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorYellow()) }, }, "str\\magenta": { Argsn: 0, Doc: "Returns ANSI escape code string for magenta text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorMagenta()) }, }, "str\\cyan": { Argsn: 0, Doc: "Returns ANSI escape code string for cyan text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorCyan()) }, }, "str\\white": { Argsn: 0, Doc: "Returns ANSI escape code string for white text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorWhite()) }, }, "br-black": { Argsn: 0, Doc: "Sets terminal text color to bright black (gray).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrBlack() return env.NewInteger(1) }, }, "str\\br-black": { Argsn: 0, Doc: "Returns ANSI escape code string for bright black (gray) text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrBlack()) }, }, "br-red": { Argsn: 0, Doc: "Sets terminal text color to bright red.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrRed() return env.NewInteger(1) }, }, "br-blue": { Argsn: 0, Doc: "Sets terminal text color to bright blue.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrBlue() return env.NewInteger(1) }, }, "br-green": { Argsn: 0, Doc: "Sets terminal text color to bright green.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrGreen() return env.NewInteger(1) }, }, "br-yellow": { Argsn: 0, Doc: "Sets terminal text color to bright yellow.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrYellow() return env.NewInteger(1) }, }, "br-magenta": { Argsn: 0, Doc: "Sets terminal text color to bright magenta.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrMagenta() return env.NewInteger(1) }, }, "br-cyan": { Argsn: 0, Doc: "Sets terminal text color to bright cyan.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrBlue() return env.NewInteger(1) }, }, "br-white": { Argsn: 0, Doc: "Sets terminal text color to bright white.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBrWhite() return env.NewInteger(1) }, }, "bg-black": { Argsn: 0, Doc: "Sets terminal background color to black.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgBlack() return env.NewInteger(1) }, }, "bg-red": { Argsn: 0, Doc: "Sets terminal background color to red.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgRed() return env.NewInteger(1) }, }, "bg-blue": { Argsn: 0, Doc: "Sets terminal background color to blue.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgBlue() return env.NewInteger(1) }, }, "bg-green": { Argsn: 0, Doc: "Sets terminal background color to green.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgGreen() return env.NewInteger(1) }, }, "bg-yellow": { Argsn: 0, Doc: "Sets terminal background color to yellow.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgYellow() return env.NewInteger(1) }, }, "bg-magenta": { Argsn: 0, Doc: "Sets terminal background color to magenta.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgMagenta() return env.NewInteger(1) }, }, "bg-cyan": { Argsn: 0, Doc: "Sets terminal background color to cyan.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgBlue() return env.NewInteger(1) }, }, "bg-white": { Argsn: 0, Doc: "Sets terminal background color to white.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ColorBgWhite() return env.NewInteger(1) }, }, "bold": { Argsn: 0, Doc: "Sets terminal text style to bold.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.Bold() return env.NewInteger(1) }, }, "underline": { Argsn: 0, Doc: "Sets terminal text style to underlined.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.Underline() return env.NewInteger(1) }, }, "reset\\bold": { Argsn: 0, Doc: "Resets terminal text bold style.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.ResetBold() return env.NewInteger(1) }, }, "reset": { Argsn: 0, Doc: "Resets all terminal text styles and colors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { term.CloseProps() return env.NewInteger(1) }, }, "str\\reset": { Argsn: 0, Doc: "Returns ANSI escape code string to reset all terminal text styles and colors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrCloseProps()) }, }, "spin-it": { Argsn: 2, Doc: "Takes a block of code and a message string, shows a spinner with the message while evaluating", Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch bloc := arg1.(type) { case env.Block: switch msg := arg0.(type) { case env.String: done := make(chan bool) spinnerDone := make(chan bool) go func() { ser := ps.Ser ps.Ser = bloc.Series ps.BlockFile = bloc.FileName ps.BlockLine = bloc.Line evaldo.Eval(ps) evaldo.MaybeDisplayFailureOrError(ps, ps.Idx, "spin-it") ps.Ser = ser done <- true }() spinner := []rune{'|', '/', '-', '\\'} i := 0 go func() { for { select { case <-done: fmt.Printf("\r") spinnerDone <- true return default: fmt.Printf("\r%s %c", msg.Value, spinner[i%len(spinner)]) i++ time.Sleep(120 * time.Millisecond) } } }() <-spinnerDone fmt.Println("") return ps.Res default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "spin-it") } default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "spin-it") } }, }, "pane": { Argsn: 2, Doc: "Displays content in a bordered pane with a title header.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { title, ok1 := arg0.(env.String) if !ok1 { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "pane") } content, ok2 := arg1.(env.String) if !ok2 { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "pane") } lines := strings.Split(content.Value, "\n") maxContentWidth := 0 for _, line := range lines { if len(line) > maxContentWidth { maxContentWidth = len(line) } } titleWidth := len(title.Value) + 4 paneWidth := maxContentWidth + 2 if titleWidth > paneWidth { paneWidth = titleWidth } if paneWidth < 10 { paneWidth = 10 } titlePadding := paneWidth - len(title.Value) - 4 leftPadding := titlePadding / 2 rightPadding := titlePadding - leftPadding topBorder := "╭" + strings.Repeat("─", leftPadding) + "─ " + title.Value + " ─" + strings.Repeat("─", rightPadding) + "╮" fmt.Println(topBorder) for _, line := range lines { contentPadding := paneWidth - len(line) rightContentPadding := contentPadding fmt.Printf("│%s%s│\n", line, strings.Repeat(" ", rightContentPadding)) } bottomBorder := "╰" + strings.Repeat("─", paneWidth) + "╯" fmt.Println(bottomBorder) return *env.NewInteger(1) }, }, }
var Builtins_termstr = map[string]*env.Builtin{ "black": { Argsn: 0, Doc: "Returns ANSI escape code string for black text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBlack()) }, }, "red": { Argsn: 0, Doc: "Returns ANSI escape code string for red text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorRed()) }, }, "blue": { Argsn: 0, Doc: "Returns ANSI escape code string for blue text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBlue()) }, }, "green": { Argsn: 0, Doc: "Returns ANSI escape code string for green text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorGreen()) }, }, "yellow": { Argsn: 0, Doc: "Returns ANSI escape code string for yellow text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorYellow()) }, }, "magenta": { Argsn: 0, Doc: "Returns ANSI escape code string for magenta text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorMagenta()) }, }, "cyan": { Argsn: 0, Doc: "Returns ANSI escape code string for cyan text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorCyan()) }, }, "white": { Argsn: 0, Doc: "Returns ANSI escape code string for white text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorWhite()) }, }, "br-black": { Argsn: 0, Doc: "Returns ANSI escape code string for bright black (gray) text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrBlack()) }, }, "br-red": { Argsn: 0, Doc: "Returns ANSI escape code string for bright red text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrRed()) }, }, "br-blue": { Argsn: 0, Doc: "Returns ANSI escape code string for bright blue text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrBlue()) }, }, "br-green": { Argsn: 0, Doc: "Returns ANSI escape code string for bright green text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrGreen()) }, }, "br-yellow": { Argsn: 0, Doc: "Returns ANSI escape code string for bright yellow text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrYellow()) }, }, "br-magenta": { Argsn: 0, Doc: "Returns ANSI escape code string for bright magenta text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrMagenta()) }, }, "br-cyan": { Argsn: 0, Doc: "Returns ANSI escape code string for bright cyan text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrCyan()) }, }, "br-white": { Argsn: 0, Doc: "Returns ANSI escape code string for bright white text color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBrWhite()) }, }, "bg-black": { Argsn: 0, Doc: "Returns ANSI escape code string for black background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgBlack()) }, }, "bg-red": { Argsn: 0, Doc: "Returns ANSI escape code string for red background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgRed()) }, }, "bg-blue": { Argsn: 0, Doc: "Returns ANSI escape code string for blue background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgBlue()) }, }, "bg-green": { Argsn: 0, Doc: "Returns ANSI escape code string for green background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgGreen()) }, }, "bg-yellow": { Argsn: 0, Doc: "Returns ANSI escape code string for yellow background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgYellow()) }, }, "bg-magenta": { Argsn: 0, Doc: "Returns ANSI escape code string for magenta background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgMagenta()) }, }, "bg-cyan": { Argsn: 0, Doc: "Returns ANSI escape code string for cyan background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgCyan()) }, }, "bg-white": { Argsn: 0, Doc: "Returns ANSI escape code string for white background color.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrColorBgWhite()) }, }, "bold": { Argsn: 0, Doc: "Returns ANSI escape code string for bold text style.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrBold()) }, }, "underline": { Argsn: 0, Doc: "Returns ANSI escape code string for underlined text style.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrUnderline()) }, }, "reset\\bold": { Argsn: 0, Doc: "Returns ANSI escape code string to reset bold text style.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrResetBold()) }, }, "reset": { Argsn: 0, Doc: "Returns ANSI escape code string to reset all terminal text styles and colors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return *env.NewString(term.StrCloseProps()) }, }, }
var Builtins_tmux = map[string]*env.Builtin{ "is-available": { Argsn: 0, Doc: "Checks if tmux is available on the system.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { _, err := exec.LookPath("tmux") return *env.NewBoolean(err == nil) }, }, "session": { Argsn: 1, Doc: "Creates a new tmux session with the given name using gotmux library.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { tmux, err := gotmux.DefaultTmux() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to connect to tmux: "+err.Error(), "tmux-new-session") } switch name := arg0.(type) { case env.String: session, err := tmux.NewSession(&gotmux.SessionOptions{Name: name.Value}) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to create session: "+err.Error(), "tmux-new-session") } return *env.NewNative(ps.Idx, session, "tmux-session") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "tmux-new-session") } }, }, "sessions?": { Argsn: 0, Doc: "Lists all tmux sessions using gotmux library.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { tmux, err := gotmux.DefaultTmux() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to connect to tmux: "+err.Error(), "tmux-list-sessions") } sessions, err := tmux.ListSessions() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to list sessions: "+err.Error(), "tmux-list-sessions") } items := make([]env.Object, len(sessions)) for i, session := range sessions { items[i] = *env.NewNative(ps.Idx, session, "tmux-session") } return *env.NewBlock(*env.NewTSeries(items)) }, }, "session?": { Argsn: 1, Doc: "Gets a tmux session by name using gotmux library.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { tmux, err := gotmux.DefaultTmux() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to connect to tmux: "+err.Error(), "tmux-get-session") } switch name := arg0.(type) { case env.String: session, err := tmux.GetSessionByName(name.Value) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to get session: "+err.Error(), "tmux-get-session") } return *env.NewNative(ps.Idx, session, "tmux-session") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "tmux-get-session") } }, }, "tmux-window//Rename": { Argsn: 2, Doc: "Renames the tmux window.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch win := arg0.(type) { case env.Native: if window, ok := win.Value.(*gotmux.Window); ok { switch name := arg1.(type) { case env.String: if err := window.Rename(name.Value); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to rename window: "+err.Error(), "tmux-rename-window") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tmux-rename-window") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-window object", "tmux-rename-window") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-rename-window") } }, }, "tmux-window//Select": { Argsn: 1, Doc: "Selects (focuses) the tmux window.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch win := arg0.(type) { case env.Native: if window, ok := win.Value.(*gotmux.Window); ok { if err := window.Select(); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to select window: "+err.Error(), "tmux-select-window") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-window object", "tmux-select-window") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-select-window") } }, }, "tmux-session//Window": { Argsn: 1, Doc: "Creates a new window in the given tmux session.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { window, err := session.New() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to create window: "+err.Error(), "tmux-new-window") } return *env.NewNative(ps.Idx, window, "tmux-window") } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-new-window") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-new-window") } }, }, "tmux-session//Window\\named": { Argsn: 2, Doc: "Creates a new window in the given tmux session with a specific name.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { switch name := arg1.(type) { case env.String: window, err := session.NewWindow(&gotmux.NewWindowOptions{WindowName: name.Value}) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to create named window: "+err.Error(), "tmux-new-window-named") } return *env.NewNative(ps.Idx, window, "tmux-window") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tmux-new-window-named") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-new-window-named") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-new-window-named") } }, }, "tmux-session//Rename": { Argsn: 2, Doc: "Renames a tmux session.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { switch name := arg1.(type) { case env.String: if err := session.Rename(name.Value); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to rename session: "+err.Error(), "tmux-rename-session") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tmux-rename-session") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-rename-session") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-rename-session") } }, }, "tmux-session//Windows?": { Argsn: 1, Doc: "Lists all windows in the given tmux session.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { windows, err := session.ListWindows() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to list windows: "+err.Error(), "tmux-list-windows") } items := make([]env.Object, len(windows)) for i, window := range windows { items[i] = *env.NewNative(ps.Idx, window, "tmux-window") } return *env.NewBlock(*env.NewTSeries(items)) } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-list-windows") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-list-windows") } }, }, "tmux-window//Layout\\select": { Argsn: 2, Doc: "Selects layout for a window (even-horizontal, even-vertical, main-horizontal, tiled).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch win := arg0.(type) { case env.Native: if window, ok := win.Value.(*gotmux.Window); ok { switch layout := arg1.(type) { case env.String: var ly gotmux.WindowLayout switch layout.Value { case string(gotmux.WindowLayoutEvenHorizontal), string(gotmux.WindowLayoutEvenVertical), string(gotmux.WindowLayoutMainVertical), string(gotmux.WindowLayoutTiled): ly = gotmux.WindowLayout(layout.Value) default: return evaldo.MakeBuiltinError(ps, "Invalid layout", "tmux-select-layout") } if err := window.SelectLayout(ly); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to select layout: "+err.Error(), "tmux-select-layout") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tmux-select-layout") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-window object", "tmux-select-layout") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-select-layout") } }, }, "tmux-session//Pane?": { Argsn: 2, Doc: "Gets a pane from a tmux window by index.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch win := arg0.(type) { case env.Native: if window, ok := win.Value.(*gotmux.Window); ok { switch idx := arg1.(type) { case env.Integer: pane, err := window.GetPaneByIndex(int(idx.Value)) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to get pane: "+err.Error(), "tmux-get-pane") } return *env.NewNative(ps.Idx, pane, "tmux-pane") default: return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "tmux-get-pane") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-window object", "tmux-get-pane") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-get-pane") } }, }, "tmux-window//Panes?": { Argsn: 1, Doc: "Lists panes in the given tmux window.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch win := arg0.(type) { case env.Native: if window, ok := win.Value.(*gotmux.Window); ok { panes, err := window.ListPanes() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to list panes: "+err.Error(), "tmux-list-panes") } items := make([]env.Object, len(panes)) for i, p := range panes { items[i] = *env.NewNative(ps.Idx, p, "tmux-pane") } return *env.NewBlock(*env.NewTSeries(items)) } return evaldo.MakeBuiltinError(ps, "Expected tmux-window object", "tmux-list-panes") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-list-panes") } }, }, "tmux-pane//Kill": { Argsn: 1, Doc: "Kills the tmux pane.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: if pane, ok := p.Value.(*gotmux.Pane); ok { if err := pane.Kill(); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to kill pane: "+err.Error(), "tmux-kill-pane") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-pane object", "tmux-kill-pane") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-kill-pane") } }, }, "tmux-pane//Split-pane": { Argsn: 1, Doc: "Splits a tmux pane horizontally.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: if pane, ok := p.Value.(*gotmux.Pane); ok { err := pane.Split() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to split pane: "+err.Error(), "tmux-split-pane") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-pane object", "tmux-split-pane") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-split-pane") } }, }, "tmux-pane//Select": { Argsn: 1, Doc: "Selects (focuses) the tmux pane.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: if pane, ok := p.Value.(*gotmux.Pane); ok { if err := pane.Select(); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to select pane: "+err.Error(), "tmux-select-pane") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-pane object", "tmux-select-pane") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-select-pane") } }, }, "tmux-pane//Send-keys": { Argsn: 2, Doc: "Sends keys/command to a tmux pane.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch p := arg0.(type) { case env.Native: if pane, ok := p.Value.(*gotmux.Pane); ok { switch cmd := arg1.(type) { case env.String: err := pane.SendKeys(cmd.Value) if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to send keys: "+err.Error(), "tmux-send-keys") } return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tmux-send-keys") } } return evaldo.MakeBuiltinError(ps, "Expected tmux-pane object", "tmux-send-keys") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-send-keys") } }, }, "tmux-session//Attach": { Argsn: 1, Doc: "Attaches to a tmux session (switch-client).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { if err := session.Attach(); err != nil { return evaldo.MakeBuiltinError(ps, "Failed to attach to session: "+err.Error(), "tmux-attach-session") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-attach-session") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-attach-session") } }, }, "tmux-session//Kill": { Argsn: 1, Doc: "Kills/destroys a tmux session.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch sess := arg0.(type) { case env.Native: if session, ok := sess.Value.(*gotmux.Session); ok { err := session.Kill() if err != nil { return evaldo.MakeBuiltinError(ps, "Failed to kill session: "+err.Error(), "tmux-kill-session") } return arg0 } return evaldo.MakeBuiltinError(ps, "Expected tmux-session object", "tmux-kill-session") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tmux-kill-session") } }, }, }
var Builtins_tui = map[string]*env.Builtin{ "text": { Argsn: 1, Doc: "Creates a text widget (no wrapping). Returns { 'text { } content }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return tuiMakeWidget(ps, "text", *env.NewDict(nil), arg0) }, }, "text\\": { Argsn: 2, Doc: "Creates a styled text widget. Returns { 'text { styles } content }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var styles env.Dict switch s := arg0.(type) { case env.Dict: styles = s case env.Word: styles = *env.NewDict(map[string]any{"_style": ps.Idx.GetWord(s.Index)}) default: styles = *env.NewDict(nil) } return tuiMakeWidget(ps, "text", styles, arg1) }, }, "block": { Argsn: 1, Doc: "Creates a text block widget that wraps. Returns { 'block { } content }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return tuiMakeWidget(ps, "block", *env.NewDict(nil), arg0) }, }, "block\\": { Argsn: 2, Doc: "Creates a styled text block widget. Returns { 'block { styles } content }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { var styles env.Dict switch s := arg0.(type) { case env.Dict: styles = s default: styles = *env.NewDict(nil) } return tuiMakeWidget(ps, "block", styles, arg1) }, }, "hline": { Argsn: 0, Doc: "Creates a horizontal line widget. Returns { 'hline { } \"─\" }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return tuiMakeWidget(ps, "hline", *env.NewDict(nil), *env.NewString("─")) }, }, "hline\\char": { Argsn: 1, Doc: "Creates a horizontal line with custom character. Returns { 'hline { } char }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return tuiMakeWidget(ps, "hline", *env.NewDict(nil), arg0) }, }, "vspace": { Argsn: 1, Doc: "Creates a vertical spacer widget. Returns { 'vspace { } height }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { return tuiMakeWidget(ps, "vspace", *env.NewDict(nil), arg0) }, }, "vbox": { Argsn: 1, Doc: "Creates a vertical box container. Evaluates the block and collects widget results. Returns { 'vbox { } children }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch block := arg0.(type) { case env.Block: // Evaluate the block to get widget children // Each expression in the block should return a widget block var children []env.Object psTemp := *ps psTemp.Ser = block.Series psTemp.Ser.Reset() for psTemp.Ser.Pos() < psTemp.Ser.Len() { evaldo.EvalExpression(&psTemp, nil, false, false, false, false) if psTemp.ErrorFlag || psTemp.FailureFlag { return psTemp.Res } if psTemp.Res != nil { if _, ok := psTemp.Res.(env.Block); ok { children = append(children, psTemp.Res) } } } childrenBlock := *env.NewBlock(*env.NewTSeries(children)) return tuiMakeWidget(ps, "vbox", *env.NewDict(nil), childrenBlock) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "vbox") } }, }, "vbox\\": { Argsn: 2, Doc: "Creates a styled vertical box container. Supports background, color, padding, bold.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { styles, ok := arg0.(env.Dict) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.DictType}, "vbox\\") } switch block := arg1.(type) { case env.Block: // Evaluate the block to get widget children var children []env.Object psTemp := *ps psTemp.Ser = block.Series psTemp.Ser.Reset() for psTemp.Ser.Pos() < psTemp.Ser.Len() { evaldo.EvalExpression(&psTemp, nil, false, false, false, false) if psTemp.ErrorFlag || psTemp.FailureFlag { return psTemp.Res } if psTemp.Res != nil { if _, ok := psTemp.Res.(env.Block); ok { children = append(children, psTemp.Res) } } } childrenBlock := *env.NewBlock(*env.NewTSeries(children)) return tuiMakeWidget(ps, "vbox", styles, childrenBlock) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "vbox\\") } }, }, "select": { Argsn: 1, Doc: "Creates a selection list widget. Returns { 'select { selected: 0 } items }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { styles := env.NewDict(map[string]any{"selected": *env.NewInteger(0)}) return tuiMakeWidget(ps, "select", *styles, arg0) }, }, "select\\selected": { Argsn: 2, Doc: "Creates a selection list with initial selection. Returns { 'select { selected: n } items }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { idx, ok := arg0.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "select\\selected") } styles := env.NewDict(map[string]any{"selected": idx}) return tuiMakeWidget(ps, "select", *styles, arg1) }, }, "tabs": { Argsn: 1, Doc: "Creates a horizontal tabs widget. Returns { 'tabs { selected: 0 } items }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { styles := env.NewDict(map[string]any{"selected": *env.NewInteger(0)}) return tuiMakeWidget(ps, "tabs", *styles, arg0) }, }, "tabs\\selected": { Argsn: 2, Doc: "Creates tabs with initial selection. Returns { 'tabs { selected: n } items }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { idx, ok := arg0.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.IntegerType}, "tabs\\selected") } styles := env.NewDict(map[string]any{"selected": idx}) return tuiMakeWidget(ps, "tabs", *styles, arg1) }, }, "input": { Argsn: 1, Doc: "Creates a managed text input widget with built-in key handling. Returns native TuiInput.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { placeholder, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "input") } inp := NewTuiInput(placeholder.Value) inp.ps = ps return *env.NewNative(ps.Idx, inp, "tui-input") }, }, "field": { Argsn: 1, Doc: "Creates an unmanaged text field widget (pure data). Handle keys manually. Returns { 'field { } { value: '' placeholder: ... } }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { placeholder, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "field") } content := env.NewDict(map[string]any{ "value": *env.NewString(""), "placeholder": placeholder, "cursor": *env.NewInteger(0), }) return tuiMakeWidget(ps, "field", *env.NewDict(nil), *content) }, }, "field\\value": { Argsn: 2, Doc: "Creates an unmanaged text field with initial value.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { value, ok := arg0.(env.String) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.StringType}, "field\\value") } placeholder, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "field\\value") } content := env.NewDict(map[string]any{ "value": value, "placeholder": placeholder, "cursor": *env.NewInteger(int64(len(value.Value))), }) return tuiMakeWidget(ps, "field", *env.NewDict(nil), *content) }, }, "tui-input//On-submit": { Argsn: 2, Doc: "Sets the callback function called when Enter is pressed. Callback receives (value).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { tinp.onSubmit = arg1 tinp.ps = ps return arg0 } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//On-submit") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//On-submit") } }, }, "tui-input//On-change": { Argsn: 2, Doc: "Sets the callback function called when value changes. Callback receives (value).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { tinp.onChange = arg1 tinp.ps = ps return arg0 } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//On-change") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//On-change") } }, }, "tui-input//Value?": { Argsn: 1, Doc: "Returns the current value of the input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { return *env.NewString(tinp.GetValue()) } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Value?") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Value?") } }, }, "tui-input//Set-value": { Argsn: 2, Doc: "Sets the value of the input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { if val, ok := arg1.(env.String); ok { tinp.SetValue(val.Value) return arg0 } return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tui-input//Set-value") } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Set-value") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Set-value") } }, }, "tui-input//Focus": { Argsn: 2, Doc: "Sets the focus state of the input (1 = focused, 0 = not focused).", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { if val, ok := arg1.(env.Integer); ok { tinp.focused = val.Value != 0 return arg0 } return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "tui-input//Focus") } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Focus") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Focus") } }, }, "tui-input//Width": { Argsn: 2, Doc: "Sets the display width of the input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { if val, ok := arg1.(env.Integer); ok { tinp.width = int(val.Value) return arg0 } return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "tui-input//Width") } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Width") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Width") } }, }, "tui-input//Handle-key": { Argsn: 2, Doc: "Processes a key event. Returns 1 if handled, 0 if not.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { if key, ok := arg1.(env.String); ok { handled := tinp.HandleKey(key.Value, ps) if handled { return *env.NewInteger(1) } return *env.NewInteger(0) } return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tui-input//Handle-key") } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Handle-key") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Handle-key") } }, }, "tui-input//Widget": { Argsn: 1, Doc: "Returns the widget block for rendering this input.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch inp := arg0.(type) { case env.Native: if tinp, ok := inp.Value.(*TuiInput); ok { tinp.ps = ps return tinp.Render() } return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-input//Widget") default: return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-input//Widget") } }, }, "render": { Argsn: 1, Doc: "Renders a widget tree to the terminal and returns number of lines.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { widget, ok := arg0.(env.Block) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "render") } width := term.GetTerminalColumns() if width < 20 { width = 80 } theme := *env.NewDict(nil) lines := tuiRenderWidget(ps, widget, width, theme) for _, line := range lines { fmt.Println(line) } return *env.NewInteger(int64(len(lines))) }, }, "render\\theme": { Argsn: 2, Doc: "Renders a widget tree with a theme.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { theme, ok := arg0.(env.Dict) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.DictType}, "render\\theme") } widget, ok := arg1.(env.Block) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.BlockType}, "render\\theme") } width := term.GetTerminalColumns() if width < 20 { width = 80 } lines := tuiRenderWidget(ps, widget, width, theme) for _, line := range lines { fmt.Println(line) } return *env.NewInteger(int64(len(lines))) }, }, "render\\to-string": { Argsn: 2, Doc: "Renders a widget tree to a string.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { widget, ok := arg0.(env.Block) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "render\\to-string") } width, ok := arg1.(env.Integer) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.IntegerType}, "render\\to-string") } theme := *env.NewDict(nil) lines := tuiRenderWidget(ps, widget, int(width.Value), theme) return *env.NewString(strings.Join(lines, "\n")) }, }, "app": { Argsn: 1, Doc: "Creates a new TUI app with the given theme.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { theme, ok := arg0.(env.Dict) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.DictType}, "app") } app := NewTuiApp(theme) return *env.NewNative(ps.Idx, app, "tui-app") }, }, "tui-app//View": { Argsn: 2, Doc: "Sets the view for the TUI app. Can be a widget block or a function that returns one.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//View") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//View") } app.SetView(arg1) return arg0 }, }, "tui-app//State": { Argsn: 2, Doc: "Sets the state for the TUI app.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//State") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//State") } state, ok := arg1.(env.Dict) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.DictType}, "tui-app//State") } app.SetState(state) return arg0 }, }, "tui-app//State?": { Argsn: 1, Doc: "Gets the current state of the TUI app.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//State?") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//State?") } return app.GetState() }, }, "tui-app//Update": { Argsn: 2, Doc: "Updates the state and re-renders.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Update") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Update") } updates, ok := arg1.(env.Dict) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.DictType}, "tui-app//Update") } app.Update(updates) return arg0 }, }, "tui-app//On-key": { Argsn: 3, Doc: "Registers a handler for a specific key. Key can be 'up', 'down', 'enter', 'escape', 'q', etc.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//On-key") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//On-key") } key, ok := arg1.(env.String) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.StringType}, "tui-app//On-key") } switch arg2.(type) { case env.Function, env.Block: app.OnKey(key.Value, arg2) return arg0 default: return evaldo.MakeArgError(ps, 3, []env.Type{env.FunctionType, env.BlockType}, "tui-app//On-key") } }, }, "tui-app//On-keys": { Argsn: 2, Doc: "Registers a handler for ALL keys. Function receives (state, key). Use switch on key to handle different keys.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//On-keys") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//On-keys") } switch arg1.(type) { case env.Function, env.Block: app.OnKeys(arg1) return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.FunctionType, env.BlockType}, "tui-app//On-keys") } }, }, "tui-app//Focus": { Argsn: 2, Doc: "Sets the focused input widget. Keys are routed to focused input first.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Focus") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Focus") } if i, ok := arg1.(env.Integer); ok && i.Value == 0 { app.mu.Lock() app.focusedInput = nil app.mu.Unlock() return arg0 } inputNative, ok := arg1.(env.Native) if !ok { return evaldo.MakeArgError(ps, 2, []env.Type{env.NativeType}, "tui-app//Focus") } inp, ok := inputNative.Value.(*TuiInput) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiInput", "tui-app//Focus") } app.mu.Lock() app.focusedInput = inp inp.focused = true inp.ps = ps app.mu.Unlock() return arg0 }, }, "tui-app//Start": { Argsn: 1, Doc: "Starts the TUI app, entering raw mode and beginning the event loop.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Start") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Start") } err := app.Start(ps) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "tui-app//Start") } return arg0 }, }, "tui-app//Stop": { Argsn: 1, Doc: "Stops the TUI app.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Stop") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Stop") } app.Stop() return arg0 }, }, "tui-app//Wait": { Argsn: 1, Doc: "Blocks until the TUI app stops.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Wait") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Wait") } app.Wait() return arg0 }, }, "tui-app//Redraw": { Argsn: 1, Doc: "Forces a re-render of the TUI app.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Redraw") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Redraw") } app.mu.Lock() if app.ps == nil { app.ps = ps } app.mu.Unlock() app.Render() return arg0 }, }, "tui-app//Send": { Argsn: 2, Doc: "Sends a message into the app's event loop. Thread-safe, can be called from goroutines. The message is handled by the on-message handler.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//Send") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//Send") } select { case app.msgChan <- arg1: default: } return arg0 }, }, "tui-app//On-message": { Argsn: 2, Doc: "Registers a handler for async messages sent via Send. Function receives (state, msg). Return a dict to update state.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { native, ok := arg0.(env.Native) if !ok { return evaldo.MakeArgError(ps, 1, []env.Type{env.NativeType}, "tui-app//On-message") } app, ok := native.Value.(*TuiApp) if !ok { return evaldo.MakeBuiltinError(ps, "Expected TuiApp", "tui-app//On-message") } switch arg1.(type) { case env.Function: app.mu.Lock() app.msgHandler = arg1 app.mu.Unlock() return arg0 default: return evaldo.MakeArgError(ps, 2, []env.Type{env.FunctionType}, "tui-app//On-message") } }, }, "style": { Argsn: 1, Doc: "Creates a style dict from a block. Example: tui-style { bold: 1 color: 'blue }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch b := arg0.(type) { case env.Block: data := make(map[string]any) for i := 0; i < b.Series.Len(); i += 2 { if i+1 >= b.Series.Len() { break } key := b.Series.Get(i) val := b.Series.Get(i + 1) var keyStr string switch k := key.(type) { case env.Tagword: keyStr = ps.Idx.GetWord(k.Index) case env.Word: keyStr = ps.Idx.GetWord(k.Index) case env.String: keyStr = k.Value default: continue } data[keyStr] = val } return *env.NewDict(data) case env.Dict: return b default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.DictType}, "style") } }, }, "theme": { Argsn: 1, Doc: "Creates a theme dict. Example: tui-theme { text { color: 'blue } hline { color: 'gray } }", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch b := arg0.(type) { case env.Block: data := make(map[string]any) for i := 0; i < b.Series.Len(); i += 2 { if i+1 >= b.Series.Len() { break } key := b.Series.Get(i) val := b.Series.Get(i + 1) var keyStr string switch k := key.(type) { case env.Tagword: keyStr = ps.Idx.GetWord(k.Index) case env.Word: keyStr = ps.Idx.GetWord(k.Index) case env.String: keyStr = k.Value default: continue } switch v := val.(type) { case env.Block: styleData := make(map[string]any) for j := 0; j < v.Series.Len(); j += 2 { if j+1 >= v.Series.Len() { break } sk := v.Series.Get(j) sv := v.Series.Get(j + 1) var skStr string switch skk := sk.(type) { case env.Tagword: skStr = ps.Idx.GetWord(skk.Index) case env.Word: skStr = ps.Idx.GetWord(skk.Index) case env.String: skStr = skk.Value default: continue } styleData[skStr] = sv } data[keyStr] = *env.NewDict(styleData) case env.Dict: data[keyStr] = v } } return *env.NewDict(data) case env.Dict: return b default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType, env.DictType}, "theme") } }, }, }
var Builtins_vector = map[string]*env.Builtin{ "vector": { Argsn: 1, Doc: "Creates a vector from a block of numbers.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s := arg0.(type) { case env.Block: data := ArrayFloat32FromSeries(s.Series) val, err := govector.AsVector(data) if err != nil { return evaldo.MakeError(ps, err.Error()) } return *env.NewVector(val) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "vector") } }, }, "normalize": { Argsn: 1, Doc: "Calculates the L2 norm (Euclidean length) of a vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Vector: return *env.NewDecimal(govector.Norm(val.Value, 2.0)) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "normalize") } }, }, "std-deviation": { Argsn: 1, Doc: "Calculates the standard deviation of a vector's elements.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch val := arg0.(type) { case env.Vector: return *env.NewDecimal(val.Value.Sd()) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "std-deviation?") } }, }, "cosine-similarity": { Argsn: 2, Doc: "Calculates the cosine similarity between two vectors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: res, err := govector.Cosine(v1.Value, v2.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "cosine-similarity?") } return *env.NewDecimal(res) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "cosine-similarity?") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "cosine-similarity?") } }, }, "correlation": { Argsn: 2, Doc: "Calculates the correlation coefficient between two vectors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: res, err := govector.Cor(v1.Value, v2.Value) if err != nil { return evaldo.MakeError(ps, err.Error()) } return *env.NewDecimal(res) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "correlation") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "correlation") } }, }, "dot-product": { Argsn: 2, Doc: "Calculates the dot product between two vectors.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: res, err := govector.DotProduct(v1.Value, v2.Value) if err != nil { return evaldo.MakeError(ps, err.Error()) } return *env.NewDecimal(res) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "dot-product") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "dot-product") } }, }, "euclidean-distance": { Argsn: 2, Doc: "Calculates the Euclidean distance between two vectors. Useful for K-Means clustering.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: if len(v1.Value) != len(v2.Value) { return evaldo.MakeBuiltinError(ps, "Vectors must have the same length", "euclidean-distance") } var sum float64 for i := 0; i < len(v1.Value); i++ { diff := v1.Value[i] - v2.Value[i] sum += diff * diff } return *env.NewDecimal(sqrtFloat64(sum)) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "euclidean-distance") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "euclidean-distance") } }, }, "mean-vectors": { Argsn: 1, Doc: "Calculates the element-wise mean of multiple vectors. Useful for creating 'Master Anchors'.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch block := arg0.(type) { case env.Block: if block.Series.Len() == 0 { return evaldo.MakeBuiltinError(ps, "Block must contain at least one vector", "mean-vectors") } first := block.Series.Get(0) firstVec, ok := first.(env.Vector) if !ok { return evaldo.MakeBuiltinError(ps, "Block must contain only vectors", "mean-vectors") } vecLen := len(firstVec.Value) result := make(govector.Vector, vecLen) for i := 0; i < block.Series.Len(); i++ { item := block.Series.Get(i) vec, ok := item.(env.Vector) if !ok { return evaldo.MakeBuiltinError(ps, "Block must contain only vectors", "mean-vectors") } if len(vec.Value) != vecLen { return evaldo.MakeBuiltinError(ps, "All vectors must have the same length", "mean-vectors") } for j := 0; j < vecLen; j++ { result[j] += vec.Value[j] } } count := float64(block.Series.Len()) for i := 0; i < vecLen; i++ { result[i] /= count } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.BlockType}, "mean-vectors") } }, }, "unit-vector": { Argsn: 1, Doc: "Returns a new normalized vector (length = 1). Essential for consistent dot products and overlays.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v := arg0.(type) { case env.Vector: norm := govector.Norm(v.Value, 2.0) if norm == 0 { return evaldo.MakeBuiltinError(ps, "Cannot normalize zero vector", "Vector//unit") } result := make(govector.Vector, len(v.Value)) for i := 0; i < len(v.Value); i++ { result[i] = v.Value[i] / norm } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "Vector//unit") } }, }, "project-vector": { Argsn: 2, Doc: "Projects vector onto another vector. Answers: 'How much of this vector is in the direction of another?'", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: if len(v1.Value) != len(v2.Value) { return evaldo.MakeBuiltinError(ps, "Vectors must have the same length", "Vector//project") } dotAB, err := govector.DotProduct(v1.Value, v2.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Vector//project") } dotBB, err := govector.DotProduct(v2.Value, v2.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Vector//project") } if dotBB == 0 { return evaldo.MakeBuiltinError(ps, "Cannot project onto zero vector", "Vector//project") } scalar := dotAB / dotBB result := make(govector.Vector, len(v2.Value)) for i := 0; i < len(v2.Value); i++ { result[i] = v2.Value[i] * scalar } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "Vector//project") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "Vector//project") } }, }, "reject-vector": { Argsn: 2, Doc: "Removes projection from vector. Use this to 'subtract' a concept direction from a vector.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch v1 := arg0.(type) { case env.Vector: switch v2 := arg1.(type) { case env.Vector: if len(v1.Value) != len(v2.Value) { return evaldo.MakeBuiltinError(ps, "Vectors must have the same length", "Vector//reject") } dotAB, err := govector.DotProduct(v1.Value, v2.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Vector//reject") } dotBB, err := govector.DotProduct(v2.Value, v2.Value) if err != nil { return evaldo.MakeBuiltinError(ps, err.Error(), "Vector//reject") } if dotBB == 0 { return v1 } scalar := dotAB / dotBB result := make(govector.Vector, len(v1.Value)) for i := 0; i < len(v1.Value); i++ { result[i] = v1.Value[i] - (v2.Value[i] * scalar) } return *env.NewVector(result) default: return evaldo.MakeArgError(ps, 2, []env.Type{env.VectorType}, "Vector//reject") } default: return evaldo.MakeArgError(ps, 1, []env.Type{env.VectorType}, "Vector//reject") } }, }, }
Functions ¶
func ArrayFloat32FromSeries ¶
func BlockToJSON ¶
BlockToJSON converts a Block to JSON array format.
func BlockToJSONWithIdxs ¶
BlockToJSONWithIdxs converts a Block to JSON array format with Idxs for context support.
func BsonToValue_Map ¶
func BsonToValue_Val ¶
func BuiConvert ¶
func BuiParseArgs ¶
BuiParseArgs is the main builtin function for parse-args
func BuiParseArgsFull ¶ added in v0.2.70
BuiParseArgsFull parses arguments and on failure prints both the parse errors and the generated help text. It returns the parsed Dict on success and the help text on failure.
func ContextToJSON ¶
ContextToJSON converts a RyeCtx to JSON object format.
func Conversion_EvalBlockCtx ¶
func DialectMath ¶
func DictToJSON ¶
DictToJSON converts a Dict to JSON object format.
func DictToJSONWithIdxs ¶
DictToJSONWithIdxs converts a Dict to JSON object format with Idxs for context support.
func EscapeJson ¶
func EvalBlockInPersistentCtx ¶
func EvalBlockInPersistentCtx(ps *env.ProgramState, pctx *PersistentCtx)
EvalBlockInPersistentCtx evaluates a block within a PersistentCtx, ensuring persistence
func Eyr_CallBuiltin ¶
func Eyr_CallBuiltin(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object, toLeft bool) *env.ProgramState
func Eyr_CallBuiltinPipe ¶
func Eyr_CallBuiltinPipe(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object) *env.ProgramState
func Eyr_CallFunction ¶
func Eyr_CallFunction(fn env.Function, es *env.ProgramState, leftVal env.Object, toLeft bool, session *env.RyeCtx) *env.ProgramState
This is separate from CallFuncitonArgsN so it can manage pulling args directly off of the eyr stack
func Eyr_EvalBlock ¶
func Eyr_EvalBlock(ps *env.ProgramState, full bool) *env.ProgramState
func Eyr_EvalBlockInside ¶
func Eyr_EvalBlockInside(ps *env.ProgramState, inj env.Object, injnow bool) *env.ProgramState
func Eyr_EvalExpression ¶
func Eyr_EvalExpression(ps *env.ProgramState) *env.ProgramState
func Eyr_EvalLSetword ¶
func Eyr_EvalLSetword(ps *env.ProgramState, word env.LSetword, leftVal env.Object, toLeft bool) *env.ProgramState
func Eyr_EvalObject ¶
func Eyr_EvalWord ¶
func Eyr_EvalWord(ps *env.ProgramState, word env.Object, leftVal env.Object, pipeWord bool) *env.ProgramState
func ListToJSON ¶
ListToJSON converts a List to JSON array format.
func ListToJSONWithIdxs ¶
ListToJSONWithIdxs converts a List to JSON array format with Idxs for context support.
func Math_EvalBlock ¶
func Math_EvalBlock(es *env.ProgramState) []env.Object
func RegisterBatteries ¶
func RegisterBatteries(ps *env.ProgramState)
RegisterBatteries registers all battery (non-base) builtins into the program state. Call this after evaldo.RegisterBuiltins to get the full standard set of Rye builtins.
func RyeToJSONLines ¶
func SQL_EvalBlock ¶
func SQL_EvalBlock(es *env.ProgramState, mode int, values []any) (*env.ProgramState, []any)
SQL_EvalBlock evaluates a block of SQL expressions and builds a SQL string
func SQL_EvalExpression ¶
func SQL_EvalExpression(es *env.ProgramState, vals []any, mode int) (*env.ProgramState, string, []any)
SQL_EvalExpression evaluates a single SQL expression and converts Rye objects to SQL syntax mode 1: SQLite (uses ? placeholders), mode 2: PostgreSQL (uses $1, $2, etc. placeholders)
func Stck_CallBuiltin ¶
func Stck_CallBuiltin(bi env.Builtin, ps *env.ProgramState, arg0_ env.Object, toLeft bool) *env.ProgramState
func Stck_EvalBlock ¶
func Stck_EvalBlock(ps *env.ProgramState) *env.ProgramState
func Stck_EvalExpression ¶
func Stck_EvalExpression(ps *env.ProgramState) *env.ProgramState
func Stck_EvalObject ¶
func Stck_EvalWord ¶
func Stck_EvalWord(ps *env.ProgramState, word env.Object, leftVal env.Object, toLeft bool) *env.ProgramState
func TableRowToJSON ¶
TableRowToJSON converts a TableRow to JSON object format.
func TableRowToJSONWithIdxs ¶
TableRowToJSONWithIdxs converts a TableRow to JSON object format with Idxs for context support.
func TableToJSON ¶
TableToJSON converts a Table to JSON array format.
func TableToJSONLines ¶
func TableToJSONWithIdxs ¶
TableToJSONWithIdxs converts a Table to JSON array format with Idxs for context support.
func TruncateToWidth ¶
TruncateToWidth truncates a string to fit within the given width, preserving ANSI escape codes and optionally adding an ellipsis
func VectorToJSON ¶
func VisibleWidth ¶
VisibleWidth returns the display width of a string, ignoring ANSI escape codes
Types ¶
type ArgSpec ¶
type ArgSpec struct {
Name string // Name for the result (from flagword long name or setword)
ShortFlag string // Short flag name (e.g., "v")
LongFlag string // Long flag name (e.g., "verbose")
IsFlag bool // True if it's a boolean flag (no value)
IsPositional bool // True if it's a positional argument
IsRequired bool // True if required
IsList bool // True if can be repeated (collects into list)
IsMany bool // True if positional accepts many values
ValueType string // "string", "integer", "decimal", "boolean", "file", "any"
Default env.Object // Default value
DoBlock *env.Block // Action evaluated for each explicitly supplied flag
CheckBlock *env.Block // Optional validation block
CheckError string // Error message if check fails
Doc string // Documentation string
}
ArgSpec holds the specification for a single argument
type CLISpec ¶
type CLISpec struct {
GlobalArgs []ArgSpec
Subcommands map[string]*SubcommandSpec
ProgramName string // Optional program name for help
ProgramDoc string // Optional program description for help
}
CLISpec holds the complete CLI specification
func CLI_ParseSpec ¶
CLI_ParseSpec parses the specification block into a CLISpec
type ConversionError ¶
type ConversionError struct {
// contains filtered or unexported fields
}
Integer represents an integer.
type HtmlDialectNode ¶
type HtmlNavigCondition ¶
type HtmlNavigCondition struct {
}
type MessageDispatcher ¶
type MessageDispatcher struct {
// contains filtered or unexported fields
}
MessageDispatcher provides a high-performance message routing system
func NewMessageDispatcher ¶
func NewMessageDispatcher(bufferSize int, initialState env.Dict) *MessageDispatcher
NewMessageDispatcher creates a new message dispatcher
func (*MessageDispatcher) GetState ¶
func (md *MessageDispatcher) GetState() env.Dict
GetState returns a copy of the current state
func (*MessageDispatcher) RegisterHandler ¶
func (md *MessageDispatcher) RegisterHandler(msgType string, handler env.Function)
RegisterHandler registers a message handler function
func (*MessageDispatcher) Send ¶
func (md *MessageDispatcher) Send(msg env.Object) error
Send sends a message to the dispatcher
func (*MessageDispatcher) SetState ¶
func (md *MessageDispatcher) SetState(state env.Dict)
SetState updates the state
func (*MessageDispatcher) Start ¶
func (md *MessageDispatcher) Start(ps *env.ProgramState, updateCallback env.Function)
Start begins processing messages in a goroutine
func (*MessageDispatcher) Stop ¶
func (md *MessageDispatcher) Stop()
Stop stops the message processing loop
func (*MessageDispatcher) UnregisterHandler ¶
func (md *MessageDispatcher) UnregisterHandler(msgType string)
UnregisterHandler removes a message handler
type ParsedArgs ¶
type ParsedArgs struct {
Values map[string]env.Object
Command string // Full command path: "remote add"
CommandPath []string // ["remote", "add"]
Positional []env.Object
// contains filtered or unexported fields
}
ParsedArgs holds the result of parsing
func CLI_ParseArgs ¶
func CLI_ParseArgs(es *env.ProgramState, args env.Block, spec *CLISpec) (*ParsedArgs, map[string]env.Object)
CLI_ParseArgs parses command line arguments (as Rye values) according to the spec
type PersistentCtx ¶
type PersistentCtx struct {
env.RyeCtx // Minimal in-memory context for interface compatibility only
Idxs *env.Idxs
// contains filtered or unexported fields
}
PersistentCtx wraps a RyeCtx with a BadgerDB backend for persistence. It operates in database-first mode for ACID compliance.
func NewPersistentCtx ¶
func NewPersistentCtx(dbPath string, ps *env.ProgramState) (*PersistentCtx, error)
NewPersistentCtx creates a new persistent context or loads an existing one.
func (*PersistentCtx) AsRyeCtx ¶
func (pc *PersistentCtx) AsRyeCtx() *env.RyeCtx
AsRyeCtx returns the underlying RyeCtx for backward compatibility
func (*PersistentCtx) Copy ¶
func (pc *PersistentCtx) Copy() env.Context
Copy creates a copy of the persistent context (note: copy won't be persistent)
func (*PersistentCtx) Get ¶
func (pc *PersistentCtx) Get(word int) (env.Object, bool)
Get overrides the embedded Get method to read from database.
func (*PersistentCtx) GetDoc ¶
func (pc *PersistentCtx) GetDoc() string
GetDoc returns the documentation string
func (*PersistentCtx) GetKindWord ¶
func (pc *PersistentCtx) GetKindWord() env.Word
GetKindWord returns the Kind as a Word
func (*PersistentCtx) GetParent ¶
func (pc *PersistentCtx) GetParent() env.Context
GetParent returns the parent context
func (*PersistentCtx) IsVariable ¶
func (pc *PersistentCtx) IsVariable(word int) bool
IsVariable checks if a word is a variable by reading from database
func (*PersistentCtx) MarkAsVariable ¶
func (pc *PersistentCtx) MarkAsVariable(word int)
MarkAsVariable marks a word as a variable in the database
func (*PersistentCtx) Mod ¶
func (pc *PersistentCtx) Mod(word int, val env.Object) bool
Mod overrides the embedded Mod method to add ACID persistence.
func (*PersistentCtx) SetDoc ¶
func (pc *PersistentCtx) SetDoc(doc string)
SetDoc sets the documentation string
func (*PersistentCtx) SetKindWord ¶
func (pc *PersistentCtx) SetKindWord(kind env.Word)
SetKindWord sets the Kind
func (*PersistentCtx) SetParent ¶
func (pc *PersistentCtx) SetParent(parent env.Context)
SetParent sets the parent context
func (PersistentCtx) Type ¶
func (pc PersistentCtx) Type() env.Type
type PersistentCtxEvaluator ¶
type PersistentCtxEvaluator struct {
// contains filtered or unexported fields
}
PersistentCtxEvaluator intercepts evaluation to ensure persistence operations go through PersistentCtx
func (*PersistentCtxEvaluator) Eval ¶
func (pce *PersistentCtxEvaluator) Eval()
evaldo.EvalBlock evaluates the current series while intercepting persistence operations
type PersistentRyeCtx ¶
PersistentRyeCtx is a RyeCtx with persistence methods injected
func CreatePersistentRyeCtx ¶
func CreatePersistentRyeCtx(pctx *PersistentCtx) *PersistentRyeCtx
CreatePersistentRyeCtx creates a RyeCtx that has persistent behavior by injecting persistence functions
func (*PersistentRyeCtx) Mod ¶
func (w *PersistentRyeCtx) Mod(word int, val env.Object) bool
Override Mod to use PersistentCtx persistence
type RyeMutex ¶
type RyeMutex struct {
// contains filtered or unexported fields
}
RyeMutex wraps sync.Mutex with state tracking to prevent fatal errors on unlocking unlocked mutex
type SubcommandSpec ¶
type SubcommandSpec struct {
Name string
Args []ArgSpec
Subcommands map[string]*SubcommandSpec // Nested subcommands
Doc string // Documentation for subcommand
}
SubcommandSpec holds the specification for a subcommand
type TuiApp ¶
type TuiApp struct {
// contains filtered or unexported fields
}
TuiApp represents an inline terminal app
type TuiInput ¶
type TuiInput struct {
// contains filtered or unexported fields
}
TuiInput represents a text input field with cursor and selection
func NewTuiInput ¶
NewTuiInput creates a new input widget
func (*TuiInput) HandleKey ¶
func (inp *TuiInput) HandleKey(key string, ps *env.ProgramState) bool
HandleKey processes a key event, returns true if handled
Source Files
¶
- builtins_auditd.go
- builtins_bcrypt.go
- builtins_bson.go
- builtins_chitosocket.go
- builtins_cli.go
- builtins_complex.go
- builtins_console.go
- builtins_control.go
- builtins_conversion.go
- builtins_crypto.go
- builtins_echarts.go
- builtins_email.go
- builtins_encoding.go
- builtins_error_handling.go
- builtins_eyr.go
- builtins_flui.go
- builtins_flui_v2.go
- builtins_goroutines.go
- builtins_gpio_not.go
- builtins_html.go
- builtins_imap.go
- builtins_js_interop_not.go
- builtins_json.go
- builtins_mail.go
- builtins_match.go
- builtins_math.go
- builtins_matrix.go
- builtins_mcp.go
- builtins_mqtt.go
- builtins_msgdispatcher.go
- builtins_mysql.go
- builtins_persistent_contexts.go
- builtins_pipes.go
- builtins_prometheus.go
- builtins_psql.go
- builtins_regex.go
- builtins_smtpd.go
- builtins_sql.go
- builtins_sqlite.go
- builtins_ssh_not.go
- builtins_stackless.go
- builtins_structures.go
- builtins_sxml.go
- builtins_telegrambot.go
- builtins_term.go
- builtins_termstr.go
- builtins_tmux.go
- builtins_trees.go
- builtins_tui.go
- builtins_unique.go
- builtins_vector.go
- goroutines_select.go
- register.go