Skip to content

Commit

Permalink
CLI flags parsing, closes #79
Browse files Browse the repository at this point in the history
``` bash
$ abs --test --test2 2 --test3=3 --test4 -test5
Hello user, welcome to the ABS programming language!
Type 'quit' when you're done, 'help' if you get lost!
⧐  flag("test")
true
⧐  flag("test2")
2
⧐  flag("test3")
3
⧐  flag("test4")
true
⧐  flag("test5")
true
⧐  flag("test6")
⧐
```
  • Loading branch information
odino committed Jan 15, 2019
1 parent 77d6a57 commit c23a2bb
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 1 deletion.
41 changes: 41 additions & 0 deletions docs/types/builtin-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,47 @@ to `env("PWD")`:
pwd() # /go/src/github.com/abs-lang/abs
```
### flag(str)
Returns the value of a command-line flag. Both the `--flag` and `-flag`
form are accepted, and you can specify values with `--flag=x`
as well as `--flag x`:
``` bash
$ abs --test --test2 2 --test3=3 --test4 -test5
Hello user, welcome to the ABS programming language!
Type 'quit' when you're done, 'help' if you get lost!
⧐ flag("test")
true
⧐ flag("test2")
2
⧐ flag("test3")
3
⧐ flag("test4")
true
⧐ flag("test5")
true
⧐ flag("test6")
```
If a flag value is not set, it will default to `true`.
The value of a flag that does not exist is `NULL`.
In all other cases `flag(...)` returns the literal string
value of the flag:
``` bash
$ abs --number 10
Hello user, welcome to the ABS programming language!
Type 'quit' when you're done, 'help' if you get lost!
⧐ n = flag("number")
⧐ n
10
⧐ type(n)
STRING
```
## Next
That's about it for this section!
Expand Down
65 changes: 65 additions & 0 deletions evaluator/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,71 @@ func getFns() map[string]*object.Builtin {
return arg
},
},
// flag("my-flag")
// TODO:
// This seems a bit more complicated than it should,
// and I could probably use some unit testing for this.
// In any case it's a small function so YOLO
"flag": &object.Builtin{
Types: []string{object.STRING_OBJ},
Fn: func(args ...object.Object) object.Object {
err := validateArgs("exit", args, 1, [][]string{{object.STRING_OBJ}})
if err != nil {
return err
}

// flag we're trying to retrieve
name := args[0].(*object.String)
found := false

// Let's loop through all the arguments
// passed to the script
// This is O(n) but again, performance
// is not a big deal in ABS
for _, v := range os.Args {
// If the flag was found in the previous
// argument...
if found {
// ...and the next one is another flag
// means we're done parsing
// eg. --flag1 --flag2
if strings.HasPrefix(v, "-") {
break
}

// else return the next argument
// eg --flag1 something --flag2
return &object.String{Value: v}
}

// try to parse the flag as key=value
parts := strings.SplitN(v, "=", 2)
// let's just take the left-side of the flag
left := parts[0]

// if the left side of the current argument corresponds
// to the flag we're looking for (both in the form of "--flag" and "-flag")...
// ..BINGO!
if (len(left) > 1 && left[1:] == name.Value) || (len(left) > 2 && left[2:] == name.Value) {
if len(parts) > 1 {
return &object.String{Value: parts[1]}
} else {
found = true
}
}
}

// If the flag was found but we got here
// it means no value was assigned to it,
// so let's default to true
if found {
return &object.Boolean{Value: true}
}

// else a flag that's not found is NULL
return NULL
},
},
// pwd()
"pwd": &object.Builtin{
Types: []string{},
Expand Down
2 changes: 2 additions & 0 deletions examples/flags.abs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Call me `abs example.abs --example some_value`
echo(flag("example"))
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"os/user"
"strings"

"github.com/abs-lang/abs/repl"
)
Expand All @@ -22,7 +23,7 @@ func main() {

// if we're called without arguments,
// launch the REPL
if len(args) == 1 {
if len(args) == 1 || strings.HasPrefix(args[1], "-") {
fmt.Printf("Hello %s, welcome to the ABS programming language!\n", user.Username)
fmt.Printf("Type 'quit' when you're done, 'help' if you get lost!\n")
repl.Start(os.Stdin, os.Stdout)
Expand Down

0 comments on commit c23a2bb

Please sign in to comment.