Skip to content

Commit

Permalink
Initial CLI package implementation w/ tests and updated examples (#1897)
Browse files Browse the repository at this point in the history
  • Loading branch information
cquinn authored and jemc committed Jun 21, 2017
1 parent b90ec8f commit c1603f0
Show file tree
Hide file tree
Showing 14 changed files with 1,727 additions and 311 deletions.
47 changes: 47 additions & 0 deletions examples/commandline/main.pony
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use "cli"

actor Main
new create(env: Env) =>
try
let cmd =
match CommandParser(cli_spec()).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
return
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
return
end

// cmd is a valid Command, now use it.

end

fun tag cli_spec(): CommandSpec box ? =>
"""
Builds and returns the spec for a sample chat client's CLI.
"""
let cs = CommandSpec.parent("chat", "A sample chat program", [
OptionSpec.bool("admin", "Chat as admin" where default' = false)
OptionSpec.string("name", "Your name" where short' = 'n')
OptionSpec.i64("volume", "Chat volume" where short' = 'v')
], [
CommandSpec.leaf("say", "Say something", Array[OptionSpec](), [
ArgSpec.string("words", "The words to say")
])
CommandSpec.leaf("emote", "Send an emotion", [
OptionSpec.f64("speed", "Emote play speed" where default' = F64(1.0))
], [
ArgSpec.string("emotion", "Emote to send")
])
CommandSpec.parent("config", "Configuration commands", Array[OptionSpec](), [
CommandSpec.leaf("server", "Server configuration", Array[OptionSpec](), [
ArgSpec.string("address", "Address of the server")
])
])
])
cs.add_help()
cs
84 changes: 42 additions & 42 deletions examples/gups_basic/main.pony
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
use "cli"
use "collections"
use "options"
use "time"

class val Config
let logtable: USize
let iterate: USize
let chunk: USize
let streamer_count: USize
let updater_count: USize

new val create(env: Env) ? =>
let cs = CommandSpec.parent("gups_basic", "", [
OptionSpec.i64("table", "Log2 of the total table size." where default' = 20)
OptionSpec.i64("iterate", "Number of iterations." where default' = 10000)
OptionSpec.i64("chunk", "Chunk size." where default' = 1024)
OptionSpec.i64("streamers", "Number of streamers." where default' = 4)
OptionSpec.i64("updaters", "Number of updaters." where default' = 8)
]).>add_help()
let cmd =
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
end
logtable = cmd.option("table").i64().usize()
iterate = cmd.option("iterate").i64().usize()
chunk = cmd.option("chunk").i64().usize()
streamer_count = cmd.option("streamers").i64().usize()
updater_count = cmd.option("updaters").i64().usize()

actor Main
let _env: Env
var _logtable: USize = 20
var _iterate: USize = 10000
var _chunk: USize = 1024
var _streamer_count: USize = 4
var _updater_count: USize = 8
var _streamer_count: USize = 0
var _updater_count: USize = 0
var _updates: USize = 0
var _to: Array[Updater] val
var _start: U64
Expand All @@ -19,10 +49,12 @@ actor Main
_start = Time.nanos()

try
arguments()
let c = Config(env)
_streamer_count = c.streamer_count
_updater_count = c.updater_count

var size = (1 << _logtable) / _updater_count
_updates = _chunk * _iterate * _streamer_count
var size = (1 << c.logtable) / _updater_count
_updates = c.chunk * c.iterate * _streamer_count

let count = _updater_count

Expand All @@ -37,7 +69,7 @@ actor Main
end

for i in Range(0, _streamer_count) do
Streamer(this, _to, size, _chunk, _chunk * _iterate * i)(_iterate)
Streamer(this, _to, size, c.chunk, c.chunk * c.iterate * i)(c.iterate)
end
end

Expand All @@ -57,38 +89,6 @@ actor Main
)
end

fun ref arguments() ? =>
var options = Options(_env.args)

options
.add("table", "t", I64Argument)
.add("iterate", "i", I64Argument)
.add("chunk", "c", I64Argument)
.add("streamers", "s", I64Argument)
.add("updaters", "u", I64Argument)

for option in options do
match option
| ("table", let arg: I64) => _logtable = arg.usize()
| ("iterate", let arg: I64) => _iterate = arg.usize()
| ("chunk", let arg: I64) => _chunk = arg.usize()
| ("streamers", let arg: I64) => _streamer_count = arg.usize()
| ("updaters", let arg: I64) => _updater_count = arg.usize()
| let err: ParseError => err.report(_env.out) ; usage() ; error
end
end

fun ref usage() =>
_env.out.print(
"""
gups_basic [OPTIONS]
--table N log2 of the total table size. Defaults to 20.
--iterate N number of iterations. Defaults to 10000.
--chunk N chunk size. Defaults to 1024.
--streamers N number of streamers. Defaults to 4.
--updaters N number of updaters. Defaults to 8.
"""
)

actor Streamer
let main: Main
Expand Down
117 changes: 55 additions & 62 deletions examples/gups_opt/main.pony
Original file line number Diff line number Diff line change
@@ -1,88 +1,81 @@
use "options"
use "time"
use "cli"
use "collections"
use "time"

class Config
var logtable: USize = 20
var iterate: USize = 10000
var logchunk: USize = 10
var logactors: USize = 2

fun ref apply(env: Env): Bool =>
var options = Options(env.args)

options
.add("table", "t", I64Argument)
.add("iterate", "i", I64Argument)
.add("chunk", "c", I64Argument)
.add("actors", "a", I64Argument)

for option in options do
match option
| ("table", let arg: I64) => logtable = arg.usize()
| ("iterate", let arg: I64) => iterate = arg.usize()
| ("chunk", let arg: I64) => logchunk = arg.usize()
| ("actors", let arg: I64) => logactors = arg.usize()
| let err: ParseError =>
err.report(env.out)
env.out.print(
"""
gups_opt [OPTIONS]
--table N log2 of the total table size. Defaults to 20.
--iterate N number of iterations. Defaults to 10000.
--chunk N log2 of the chunk size. Defaults to 10.
--actors N log2 of the actor count. Defaults to 2.
"""
)
return false
class val Config
let logtable: USize
let iterate: USize
let logchunk: USize
let logactors: USize

new val create(env: Env) ? =>
let cs = CommandSpec.parent("gups_opt", "", [
OptionSpec.i64("table", "Log2 of the total table size."
where default' = 20)
OptionSpec.i64("iterate", "Number of iterations." where default' = 10000)
OptionSpec.i64("chunk", "Log2 of the chunk size." where default' = 10)
OptionSpec.i64("actors", "Log2 of the actor count." where default' = 2)
]).>add_help()
let cmd =
match CommandParser(cs).parse(env.args, env.vars())
| let c: Command => c
| let ch: CommandHelp =>
ch.print_help(env.out)
env.exitcode(0)
error
| let se: SyntaxError =>
env.out.print(se.string())
env.exitcode(1)
error
end
end
logtable = cmd.option("table").i64().usize()
iterate = cmd.option("iterate").i64().usize()
logchunk = cmd.option("chunk").i64().usize()
logactors = cmd.option("actors").i64().usize()

env.out.print(
"logtable: " + logtable.string() +
"\niterate: " + iterate.string() +
"\nlogchunk: " + logchunk.string() +
"\nlogactors: " + logactors.string()
)
true
"\nlogactors: " + logactors.string())

actor Main
let _env: Env
let _config: Config = Config

var _updates: USize = 0
var _confirm: USize = 0
let _start: U64
var _start: U64 = 0
var _actors: Array[Updater] val

new create(env: Env) =>
_env = env

if _config(env) then
let actor_count = 1 << _config.logactors
let loglocal = _config.logtable - _config.logactors
let chunk_size = 1 << _config.logchunk
let chunk_iterate = chunk_size * _config.iterate
let c = try
Config(env)
else
_actors = recover Array[Updater] end
return
end

let actor_count = 1 << c.logactors
let loglocal = c.logtable - c.logactors
let chunk_size = 1 << c.logchunk
let chunk_iterate = chunk_size * c.iterate

_updates = chunk_iterate * actor_count
_confirm = actor_count
_updates = chunk_iterate * actor_count
_confirm = actor_count

var updaters = recover Array[Updater](actor_count) end
var updaters = recover Array[Updater](actor_count) end

for i in Range(0, actor_count) do
updaters.push(Updater(this, actor_count, i, loglocal, chunk_size,
chunk_iterate * i))
end
for i in Range(0, actor_count) do
updaters.push(Updater(this, actor_count, i, loglocal, chunk_size,
chunk_iterate * i))
end

_actors = consume updaters
_start = Time.nanos()
_actors = consume updaters
_start = Time.nanos()

for a in _actors.values() do
a.start(_actors, _config.iterate)
end
else
_start = 0
_actors = recover Array[Updater] end
for a in _actors.values() do
a.start(_actors, c.iterate)
end

be done() =>
Expand Down
Loading

0 comments on commit c1603f0

Please sign in to comment.