Add opposite values and README.md
This commit is contained in:
parent
36d1eee759
commit
bb89c93344
80
README.md
Normal file
80
README.md
Normal file
@ -0,0 +1,80 @@
|
||||
# scpt
|
||||
|
||||
scpt is an applescript-inspired scripting language written for fun and to see if I could.
|
||||
|
||||
[![Go Reference](https://pkg.go.dev/badge/gitea.arsenm.dev/Arsen6331/scpt.svg)](https://pkg.go.dev/gitea.arsenm.dev/Arsen6331/scpt)
|
||||
|
||||
---
|
||||
|
||||
### Usage
|
||||
|
||||
scpt is to be used as a library imported into Go. A basic interpreter with no extra functionality would look like this:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"gitea.arsenm.dev/Arsen6331/scpt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func main() {
|
||||
filename := os.Args[1]
|
||||
file, err := os.Open(filepath.Clean(filename))
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
ast, err := scpt.Parse(file)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
err = ast.Execute()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Basic Syntax
|
||||
|
||||
The basic syntax of scpt can be learned from the test.scpt file.
|
||||
|
||||
---
|
||||
|
||||
### Default Functions
|
||||
|
||||
scpt comes with the following default functions:
|
||||
|
||||
- `str`: Convert value to string
|
||||
- `num`: Parse string to number (`float64`)
|
||||
- `bool`: Parse string to boolean
|
||||
- `break`: Break out of loop (Errors if not in loop)
|
||||
- `append`: Return an array with given items appended
|
||||
- `exit`: Exit with given exit code
|
||||
- `return`: Return value in function (Errors if not within function)
|
||||
- `print`: Print using `fmt.Println()`
|
||||
|
||||
---
|
||||
|
||||
### Adding functionality:
|
||||
|
||||
Adding functionality is simple and requires a call to `scpt.AddFuncs()` or `scpt.AddVars()`. Here are some examples:
|
||||
|
||||
```go
|
||||
scpt.AddFuncs(scpt.FuncMap{
|
||||
"my-function": myFunction
|
||||
})
|
||||
```
|
||||
Where `myFunction` is:
|
||||
```go
|
||||
func myFunction(args map[string]interface{}) (interface{}, error) {
|
||||
fmt.Println(args)
|
||||
return nil, nil
|
||||
}
|
||||
```
|
||||
|
||||
After the call to `scpt.AddFuncs()`, `my-function` can be used to run the function from within an scpt script. Variables work similarly.
|
1
ast.go
1
ast.go
@ -344,6 +344,7 @@ type Value struct {
|
||||
Expr *Expression `| "{" @@ "}"`
|
||||
Map []*MapKVPair `| "[" (@@ ("," @@)* )? "]"`
|
||||
Array []*Value `| "[" (@@ ("," @@)* )? "]"`
|
||||
Opposite *Value `| "!" @@`
|
||||
}
|
||||
|
||||
// Bool stores boolean values encountered while parsing a script.
|
||||
|
4
lexer.go
4
lexer.go
@ -24,8 +24,8 @@ 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)+###|#[^\n]+)`, nil},
|
||||
{"Operator", `(>=|<=|>|<|==|!=)|[-+*/^%]`, nil},
|
||||
{"Operator", `(>=|<=|>|<|==|!=)|[-+*%/^]`, nil},
|
||||
}))
|
||||
|
10
scpt.go
10
scpt.go
@ -165,6 +165,16 @@ func ParseValue(val *Value) (interface{}, error) {
|
||||
}
|
||||
// Return map[interface{}]interface{}
|
||||
return iMap, nil
|
||||
} else if val.Opposite != nil {
|
||||
value, err := callIfFunc(ParseValue(val.Opposite))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
boolean, ok := value.(bool)
|
||||
if !ok {
|
||||
return nil, errors.New("cannot take opposite of a non-boolean value")
|
||||
}
|
||||
return !boolean, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user