Add conversion functions and move other defaults to cmd/scpt

This commit is contained in:
Elara 2021-03-03 00:27:54 -08:00
parent ba11fdcf76
commit e6d195f364
6 changed files with 37 additions and 68 deletions

1
ast.go
View File

@ -138,6 +138,7 @@ type If struct {
InnerCmds []*Command `@@* "}"`
}
// RptLoop stores any repeat loops encountered while parsing a script
type RptLoop struct {
Pos lexer.Position
Times *int `"repeat" @Number "times" "{"`

View File

@ -27,6 +27,8 @@ func main() {
}
scpt.AddFuncs(scpt.FuncMap{
"print": scptPrint,
"display-dialog": displayDialog,
"do-shell-script": doShellScript,
})
err = ast.Execute()
if err != nil {

View File

@ -17,75 +17,29 @@ package scpt
import (
"errors"
"fmt"
"github.com/gen2brain/dlgs"
"os"
"os/exec"
"strconv"
)
// Default function to display a dialog
func displayDialog(args map[string]interface{}) (interface{}, error) {
// Get title
title, ok := args["title"]
if !ok {
return nil, errors.New("title not provided")
}
// Get unnamed argument as text
text, ok := args[""]
if !ok {
return nil, errors.New("text not provided")
}
// Display correct dialog based on given type
switch args["type"] {
case "yesno":
// Display yes or no dialog, returning bool based on user input
return dlgs.Question(fmt.Sprint(title), fmt.Sprint(text), true)
case "info":
// Display info dialog, returning bool based on success
return dlgs.Info(fmt.Sprint(title), fmt.Sprint(text))
case "error":
// Display error dialog, returning bool based on success
return dlgs.Error(fmt.Sprint(title), fmt.Sprint(text))
case "entry":
// Check if default text given
defaultText, ok := args["default"]
if !ok {
// Set to empty if not given
defaultText = ""
}
// Display entry dialog
input, _, err := dlgs.Entry(fmt.Sprint(title), fmt.Sprint(text), fmt.Sprint(defaultText))
// Return user input
return input, err
default:
// If type unknown, return error
return nil, fmt.Errorf("unknown dialog type: %v", args["type"])
}
}
// Default function to run a shell script using `sh -c`
func doShellScript(args map[string]interface{}) (interface{}, error) {
// Get unnamed argument and assert its type as string
script, ok := args[""].(string)
// If assertion successful
if ok {
// Create new exec.Cmd containing `sh -c <script>`
cmd := exec.Command("sh", "-c", script)
// Set command I/O
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
// Run command
_ = cmd.Run()
return "", nil
} else {
return nil, errors.New("script not provided")
}
}
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
}
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)
}
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)
}

View File

@ -12,6 +12,6 @@ var scptLexer = lexer.Must(stateful.NewSimple([]stateful.Rule{
{"Number", `(?:\d*\.)?\d+`, nil},
{"Punct", `[-[!@$&()_{}\|:;"',.?/]|]`, nil},
{"Whitespace", `[ \t\r\n]+`, nil},
{"Comment", `#[^\n]+`, nil},
{"Comment", `(###(.|\n)+###|#[^\n]+)`, nil},
{"Operator", `(>=|<=|>|<|==|!=)|[-+*/^%]`, nil},
}))

View File

@ -34,9 +34,9 @@ type FuncMap map[string]func(map[string]interface{}) (interface{}, error)
// Funcs stores the functions allowed for use in a script
var Funcs = FuncMap{
"display-dialog": displayDialog,
"do-shell-script": doShellScript,
"string": toString,
"str": toString,
"num": parseNumber,
"bool": parseBool,
}
// AddFuncs adds all functions from the provided FuncMap into

View File

@ -16,4 +16,16 @@ if {3 == 3} {
repeat 5 times { z in
print $z
}
}
print (str 10.5)
if (bool "true") {
print "True"
}
###
This is a multiline comment
###
# This is a single line comment