Implement repeat loops
This commit is contained in:
parent
745920b139
commit
877f85ef78
24
ast.go
24
ast.go
@ -100,6 +100,22 @@ func executeCmd(cmd *Command) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if cmd.RptLoops != nil {
|
||||
// For each repeat loop
|
||||
for _, RptLoop := range cmd.RptLoops {
|
||||
for i:=0;i<*RptLoop.Times;i++ {
|
||||
if RptLoop.IndexVar != nil {
|
||||
Vars[*RptLoop.IndexVar] = i
|
||||
}
|
||||
for _, InnerCmd := range RptLoop.InnerCmds {
|
||||
// Execute command recursively
|
||||
err := executeCmd(InnerCmd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %s", InnerCmd.Pos, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -110,6 +126,7 @@ type Command struct {
|
||||
Tokens []lexer.Token
|
||||
Vars []*Var `( @@`
|
||||
Ifs []*If `| @@`
|
||||
RptLoops []*RptLoop`| @@`
|
||||
Calls []*FuncCall `| @@)`
|
||||
}
|
||||
|
||||
@ -120,6 +137,13 @@ type If struct {
|
||||
InnerCmds []*Command `@@* "}"`
|
||||
}
|
||||
|
||||
type RptLoop struct {
|
||||
Pos lexer.Position
|
||||
Times *int `"repeat" @Number "times" "{"`
|
||||
IndexVar *string `(@Ident "in")?`
|
||||
InnerCmds []*Command `@@* "}"`
|
||||
}
|
||||
|
||||
// FuncCall stores any function calls encountered while parsing a script
|
||||
type FuncCall struct {
|
||||
Pos lexer.Position
|
||||
|
@ -81,3 +81,11 @@ func doShellScript(args map[string]interface{}) (interface{}, error) {
|
||||
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
|
||||
}
|
2
lexer.go
2
lexer.go
@ -10,7 +10,7 @@ var scptLexer = lexer.Must(stateful.NewSimple([]stateful.Rule{
|
||||
{"Ident", `[a-zA-Z]\w*`, nil},
|
||||
{"String", `"[^"]*"`, nil},
|
||||
{"Number", `(?:\d*\.)?\d+`, nil},
|
||||
{"Punct", `[-[!@#$&()_{}\|:;"',.?/]|]`, nil},
|
||||
{"Punct", `[-[!@$&()_{}\|:;"',.?/]|]`, nil},
|
||||
{"Whitespace", `[ \t\r\n]+`, nil},
|
||||
{"Comment", `#[^\n]+`, nil},
|
||||
{"Operator", `(>=|<=|>|<|==|!=)|[-+*/^%]`, nil},
|
||||
|
1
scpt.go
1
scpt.go
@ -36,6 +36,7 @@ type FuncMap map[string]func(map[string]interface{}) (interface{}, error)
|
||||
var Funcs = FuncMap{
|
||||
"display-dialog": displayDialog,
|
||||
"do-shell-script": doShellScript,
|
||||
"string": toString,
|
||||
}
|
||||
|
||||
// AddFuncs adds all functions from the provided FuncMap into
|
||||
|
Loading…
Reference in New Issue
Block a user