package scpt import ( "errors" "fmt" "os" "strconv" ) // Vars stores any variables set during script runtime var Vars = map[string]interface{}{} // FuncMap is a map of strings mapped to suitable script functions type FuncMap map[string]func(map[string]interface{}) (interface{}, error) // Funcs stores the functions allowed for use in a script var Funcs = FuncMap{ "str": toString, "num": parseNumber, "bool": parseBool, "break": setBreakLoop, "append": appendArray, "exit": scptExit, "return": setReturn, "print": scptPrint, } // Default function to convert unnamed argument to a string using fmt.Sprint func toString(args map[string]interface{}) (interface{}, error) { val, ok := args[""] if !ok { return nil, errors.New("no value provided") } return fmt.Sprint(val), nil } // Default function to parse unnamed argument to a number using strconv.ParseFloat func parseNumber(args map[string]interface{}) (interface{}, error) { val, ok := args[""].(string) if !ok { return nil, errors.New("no value provided") } return strconv.ParseFloat(val, 64) } // Default function to parse unnamed argument to a boolean using strconv.ParseBool func parseBool(args map[string]interface{}) (interface{}, error) { val, ok := args[""].(string) if !ok { return nil, errors.New("no value provided") } return strconv.ParseBool(val) } // Default function to set the breakLoop variable to true, breaking any loops that may be running func setBreakLoop(_ map[string]interface{}) (interface{}, error) { // If a loop is running if loopRunning { // Set breakLoop to true, breaking the loop on next cycle breakLoop = true } else { return nil, errors.New("break not inside loop") } return nil, nil } // Default function to set the breakLoop variable to true, breaking any loops that may be running func setReturn(args map[string]interface{}) (interface{}, error) { // If a loop is running if funcRunning { // Set breakLoop to true, breaking the loop on next cycle retValue = args[""] } else { return nil, errors.New("return not inside function") } return nil, nil } func scptExit(args map[string]interface{}) (interface{}, error) { exitCode, ok := args[""].(float64) if !ok { return nil, errors.New("exit requires an unnamed number argument") } os.Exit(int(exitCode)) return nil, nil } // Default function that returns an array with an appended element func appendArray(args map[string]interface{}) (interface{}, error) { // Attempt to get unnamed argument and assert as []interface{} val, ok := args[""].([]interface{}) if !ok { return nil, errors.New("cannot append to non-array object") } // Attempt to get items argument and assert as []interface{} items, ok := args["items"].([]interface{}) if !ok { return nil, errors.New("items argument invalid or not provided") } // For every item in items argument for _, item := range items { // Append to unnamed argument val = append(val, item) } // Return appended unnamed argument return val, nil } // Print message via fmt.Println func scptPrint(args map[string]interface{}) (interface{}, error) { // Get message val, ok := args[""] if !ok { return nil, errors.New("print requires an unnamed argument") } // Print message fmt.Println(val) return nil, nil }