tomo/docs/command-line-parsing.md

3.3 KiB

Command Line Parsing

Tomo supports automatic command line argument parsing for programs. Here's a simple example:

# greet.tm
func main(name:Text, be_excited=no):
    if be_excited
        say("Hello $name!!!")
    else:
        say("Hi $name.")

This program will automatically support command line argument parsing for the arguments to main():

$ tomo greet.tm 
greet: Required argument 'name' was not provided!
Signature: greet [--help] <name> [--be-excited]

$ tomo greet.tm --help
Signature: greet [--help] <name> [--be-excited]

$ tomo greet.tm "Zaphod"
Hi Zaphod. 

$ tomo greet.tm "Zaphod" --be-excited
Hello Zaphod!!!

$ tomo greet.tm --no-be-excited --name="Zaphod"
Hi Zaphod.

$ tomo greet.tm --not-a-real-argument "Bob"
greet: Unrecognized argument: --not-a-real-argument
Signature: greet [--help] <name> [--be-excited]

Underscores in argument names are converted to dashes when parsing command line arguments.

Positional vs Default Arguments

Any arguments with a default value must be specified with a --flag=value or --flag value. Arguments without a default value can be specified either by explicit --flag or positionally. If an argument does not have a default value it is required and the program will report a usage error if it is missing.

Supported Argument Types

Tomo automatically supports several argument types out of the box, but if there is a type that isn't supported, you can always fall back to accepting a Text argument and parsing it yourself.

Text

Text arguments are the simplest: the input arguments are taken verbatim.

Bool

For a boolean argument, foo, the argument can be passed in several ways:

  • --foo or --no-foo provide the argument as yes/no respectively
  • --foo=yes/--foo=on/--foo=true/--foo=1 all parse as yes (case insensitive)
  • --foo=no/--foo=off/--foo=false/--foo=0 all parse as no (case insensitive)
  • Any other values will report a usage error

Integers and Numbers

Integer and number values can be passed and parsed automatically. Any failures to parse will cause a usage error. Integers support decimal (123), hexadecimal (0xFF), and octal values (0o644). Nums support regular (123 or 1.23) or scientific notation (1e99).

For fixed-size integers (Int64, Int32, Int16, Int8), arguments that exceed the representable range for those values are considered usage errors.

Enums

For enums that do not have member values (e.g. enum Foo(Baz, Qux), not enum Foo(Baz(x:Int), Qux), Tomo supports automatic command line argument parsing. Parsing is case-insensitive:

# foo.tm
enum Foo(One, Two, Three)
func main(foo:Foo):
    >> foo

# Signature:
$ tomo foo.tm one
>> Foo.One

$ tomo foo.tm xxx
foo: Invalid value provided for --foo; valid values are: One Two
Signature: foo [--help] <foo>

Arrays of Text

Currently, Tomo supports accepting arguments that take an array of text. Array-of-text arguments can be passed like this:

# many-texts.tm
func main(args:[Text]):
    >> args
$ tomo many-texts.tm
>> [] : [Text]

$ tomo many-texts.tm one two three
>> ["one", "two", "three"] : [Text]

$ tomo many-texts.tm --args=one,two,three
>> ["one", "two", "three"] : [Text]

$ tomo many-texts.tm -- one --not-a-flag 'a space'
>> ["one", "--not-a-flag", "a space"] : [Text]