command_parser: switch from logos to nom
This commit is contained in:
parent
328f6921fa
commit
5c58c4370d
56
firmware/Cargo.lock
generated
56
firmware/Cargo.lock
generated
@ -169,8 +169,8 @@ dependencies = [
|
|||||||
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"logos 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=cd893e6)",
|
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=cd893e6)",
|
||||||
"tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -195,36 +195,30 @@ name = "linked_list_allocator"
|
|||||||
version = "0.6.4"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "logos"
|
|
||||||
version = "0.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "logos-derive"
|
|
||||||
version = "0.9.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "managed"
|
name = "managed"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nb"
|
name = "nb"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "5.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
@ -275,11 +269,6 @@ name = "rand_core"
|
|||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -357,13 +346,13 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8-ranges"
|
name = "vcell"
|
||||||
version = "1.0.4"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcell"
|
name = "version_check"
|
||||||
version = "0.1.2"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -428,10 +417,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||||
"checksum linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "47314ec1d29aa869ee7cb5a5be57be9b1055c56567d59c3fb6689926743e0bea"
|
"checksum linked_list_allocator 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "47314ec1d29aa869ee7cb5a5be57be9b1055c56567d59c3fb6689926743e0bea"
|
||||||
"checksum logos 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f494e22d293fa05db60b3fd95fb30e9409feb5672b56ce6f250f99d9fbae6b93"
|
|
||||||
"checksum logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "13ff1b1068db09ee21d12baf55eccc0900a781a735273e0a606f6f4fbb32a322"
|
|
||||||
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
||||||
|
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||||
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
||||||
|
"checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca"
|
||||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||||
@ -439,7 +428,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
|
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
|
||||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
@ -450,8 +438,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d430ed4ed06dd9fff3d4517a37343e1b53789218f2f608bf1e0432f67abf624"
|
"checksum tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d430ed4ed06dd9fff3d4517a37343e1b53789218f2f608bf1e0432f67abf624"
|
||||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
"checksum utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
|
|
||||||
"checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
|
"checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
|
||||||
|
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum volatile-register 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a470889aa8f2d3ad893bd43cd90c824e63e8ac0ee5fe64c5d81a932d184fd549"
|
"checksum volatile-register 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a470889aa8f2d3ad893bd43cd90c824e63e8ac0ee5fe64c5d81a932d184fd549"
|
||||||
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
||||||
|
@ -19,9 +19,11 @@ cortex-m-semihosting = "0.3"
|
|||||||
byteorder = { version = "1.3", default-features = false }
|
byteorder = { version = "1.3", default-features = false }
|
||||||
bit_field = "0.10"
|
bit_field = "0.10"
|
||||||
bare-metal = "0.2"
|
bare-metal = "0.2"
|
||||||
logos = { version = "~0.9", default-features = false, features = ["export_derive"] }
|
# TODO: remove
|
||||||
alloc-cortex-m = "0.3"
|
alloc-cortex-m = "0.3"
|
||||||
|
# TODO: needed with nom?
|
||||||
btoi = { version = "~0.4", default-features = false }
|
btoi = { version = "~0.4", default-features = false }
|
||||||
|
nom = { version = "~5", default-features = false }
|
||||||
|
|
||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
git = "https://github.com/m-labs/smoltcp"
|
git = "https://github.com/m-labs/smoltcp"
|
||||||
|
@ -1,125 +1,133 @@
|
|||||||
use logos::Logos;
|
use nom::{
|
||||||
|
IResult,
|
||||||
|
branch::alt,
|
||||||
|
bytes::complete::{tag, take_while1},
|
||||||
|
character::{is_digit, complete::char},
|
||||||
|
combinator::{map, value},
|
||||||
|
sequence::{preceded, tuple, Tuple},
|
||||||
|
multi::fold_many1,
|
||||||
|
error::ErrorKind,
|
||||||
|
};
|
||||||
use btoi::{btoi, ParseIntegerError};
|
use btoi::{btoi, ParseIntegerError};
|
||||||
use super::session::ReportMode;
|
use super::session::ReportMode;
|
||||||
|
|
||||||
#[derive(Logos, Debug, PartialEq)]
|
|
||||||
enum Token {
|
|
||||||
#[end]
|
|
||||||
End,
|
|
||||||
#[error]
|
|
||||||
Error,
|
|
||||||
|
|
||||||
#[token = "Quit"]
|
|
||||||
Quit,
|
|
||||||
#[token = "report"]
|
|
||||||
Report,
|
|
||||||
#[token = "mode"]
|
|
||||||
Mode,
|
|
||||||
#[token = "off"]
|
|
||||||
Off,
|
|
||||||
#[token = "once"]
|
|
||||||
Once,
|
|
||||||
#[token = "continuous"]
|
|
||||||
Continuous,
|
|
||||||
#[token = "pwm"]
|
|
||||||
Pwm,
|
|
||||||
|
|
||||||
#[regex = "[0-9]+"]
|
|
||||||
Number,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Parser,
|
Parser(ErrorKind),
|
||||||
UnexpectedEnd,
|
Incomplete,
|
||||||
UnexpectedToken(Token),
|
UnexpectedInput(u8),
|
||||||
ParseInteger(ParseIntegerError)
|
ParseInteger(ParseIntegerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'t> From<nom::Err<(&'t [u8], ErrorKind)>> for Error {
|
||||||
|
fn from(e: nom::Err<(&'t [u8], ErrorKind)>) -> Self {
|
||||||
|
match e {
|
||||||
|
nom::Err::Incomplete(_) =>
|
||||||
|
Error::Incomplete,
|
||||||
|
nom::Err::Error((_, e)) =>
|
||||||
|
Error::Parser(e),
|
||||||
|
nom::Err::Failure((_, e)) =>
|
||||||
|
Error::Parser(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ParseIntegerError> for Error {
|
impl From<ParseIntegerError> for Error {
|
||||||
fn from(e: ParseIntegerError) -> Self {
|
fn from(e: ParseIntegerError) -> Self {
|
||||||
Error::ParseInteger(e)
|
Error::ParseInteger(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ShowCommand {
|
pub enum ShowCommand {
|
||||||
ReportMode,
|
ReportMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Quit,
|
Quit,
|
||||||
Show(ShowCommand),
|
Show(ShowCommand),
|
||||||
Report(ReportMode),
|
Report(ReportMode),
|
||||||
Pwm {
|
Pwm {
|
||||||
pwm_match: u32,
|
width: u32,
|
||||||
pwm_reload: u32,
|
total: u32,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn whitespace(input: &[u8]) -> IResult<&[u8], ()> {
|
||||||
|
fold_many1(char(' '), (), |(), _| ())(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unsigned(input: &[u8]) -> IResult<&[u8], Result<u32, ParseIntegerError>> {
|
||||||
|
take_while1(is_digit)(input)
|
||||||
|
.map(|(input, digits)| (input, btoi(digits)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report_mode(input: &[u8]) -> IResult<&[u8], ReportMode> {
|
||||||
|
alt((value(ReportMode::Off, tag("off")),
|
||||||
|
value(ReportMode::Once, tag("once")),
|
||||||
|
value(ReportMode::Continuous, tag("continuous"))
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn report(input: &[u8]) -> IResult<&[u8], Command> {
|
||||||
|
preceded(
|
||||||
|
preceded(
|
||||||
|
tag("report"),
|
||||||
|
whitespace
|
||||||
|
),
|
||||||
|
alt((
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
preceded(
|
||||||
|
tag("mode"),
|
||||||
|
alt((
|
||||||
|
preceded(
|
||||||
|
whitespace,
|
||||||
|
map(report_mode,
|
||||||
|
|mode| Command::Report(mode))
|
||||||
|
),
|
||||||
|
|input| Ok((input, Command::Show(ShowCommand::ReportMode)))
|
||||||
|
))
|
||||||
|
)),
|
||||||
|
|input| Ok((input, Command::Report(ReportMode::Once)))
|
||||||
|
))
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pwm(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
||||||
|
let (input, _) = tag("pwm")(input)?;
|
||||||
|
let (input, _) = whitespace(input)?;
|
||||||
|
let (input, width) = unsigned(input)?;
|
||||||
|
let width = match width {
|
||||||
|
Ok(width) => width,
|
||||||
|
Err(e) => return Ok((input, Err(e.into()))),
|
||||||
|
};
|
||||||
|
let (input, _) = whitespace(input)?;
|
||||||
|
let (input, total) = unsigned(input)?;
|
||||||
|
let total = match total {
|
||||||
|
Ok(total) => total,
|
||||||
|
Err(e) => return Ok((input, Err(e.into()))),
|
||||||
|
};
|
||||||
|
Ok((input, Ok(Command::Pwm { width, total })))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn command(input: &[u8]) -> IResult<&[u8], Command> {
|
||||||
|
alt((value(Command::Quit, tag("quit")),
|
||||||
|
report
|
||||||
|
))(input)
|
||||||
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
pub fn parse(input: &str) -> Result<Self, Error> {
|
pub fn parse(input: &[u8]) -> Result<Self, Error> {
|
||||||
let mut lexer = Token::lexer(input);
|
match command(input) {
|
||||||
|
Ok((b"", command)) =>
|
||||||
/// Match against a set of expected tokens
|
Ok(command),
|
||||||
macro_rules! choice {
|
Ok((input_remain, _)) =>
|
||||||
[$($token: tt => $block: stmt,)*] => {
|
Err(Error::UnexpectedInput(input_remain[0])),
|
||||||
match lexer.token {
|
Err(e) =>
|
||||||
$(
|
Err(e.into()),
|
||||||
Token::$token => {
|
|
||||||
lexer.advance();
|
|
||||||
$block
|
|
||||||
}
|
}
|
||||||
)*
|
|
||||||
Token::End => return Err(Error::UnexpectedEnd),
|
|
||||||
_ => return Err(Error::UnexpectedToken(lexer.token))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/// Expecting no further tokens
|
|
||||||
macro_rules! end {
|
|
||||||
($result: expr) => {
|
|
||||||
match lexer.token {
|
|
||||||
Token::End => Ok($result),
|
|
||||||
_ => return Err(Error::UnexpectedToken(lexer.token)),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Command grammar
|
|
||||||
choice![
|
|
||||||
Quit => Ok(Command::Quit),
|
|
||||||
Report => choice![
|
|
||||||
Mode => choice![
|
|
||||||
End => end!(Command::Show(ShowCommand::ReportMode)),
|
|
||||||
Off => Ok(Command::Report(ReportMode::Off)),
|
|
||||||
Once => Ok(Command::Report(ReportMode::Once)),
|
|
||||||
Continuous => Ok(Command::Report(ReportMode::Continuous)),
|
|
||||||
],
|
|
||||||
End => Ok(Command::Report(ReportMode::Once)),
|
|
||||||
],
|
|
||||||
Pwm => {
|
|
||||||
if lexer.token != Token::Number {
|
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
|
||||||
}
|
|
||||||
let pwm_match = btoi(lexer.slice().as_bytes())?;
|
|
||||||
lexer.advance();
|
|
||||||
|
|
||||||
if lexer.token != Token::Number {
|
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
|
||||||
}
|
|
||||||
let pwm_reload = btoi(lexer.slice().as_bytes())?;
|
|
||||||
lexer.advance();
|
|
||||||
|
|
||||||
if lexer.token != Token::End {
|
|
||||||
return Err(Error::UnexpectedToken(lexer.token));
|
|
||||||
}
|
|
||||||
|
|
||||||
end!(Command::Pwm {
|
|
||||||
pwm_match, pwm_reload,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,9 +265,9 @@ fn main() -> ! {
|
|||||||
Command::Show(ShowCommand::ReportMode) => {
|
Command::Show(ShowCommand::ReportMode) => {
|
||||||
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
||||||
}
|
}
|
||||||
Command::Pwm { pwm_match, pwm_reload } => {
|
Command::Pwm { width, total } => {
|
||||||
board::set_timer_pwm(pwm_match, pwm_reload);
|
board::set_timer_pwm(width, total);
|
||||||
let _ = writeln!(socket, "PWM duty cycle: {}/{}", pwm_match, pwm_reload);
|
let _ = writeln!(socket, "PWM duty cycle: {}/{}", width, total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(SessionOutput::Error(e)) => {
|
Ok(SessionOutput::Error(e)) => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
use core::ops::Deref;
|
||||||
use super::command_parser::{Command, Error as ParserError};
|
use super::command_parser::{Command, Error as ParserError};
|
||||||
|
|
||||||
|
|
||||||
const MAX_LINE_LEN: usize = 64;
|
const MAX_LINE_LEN: usize = 64;
|
||||||
|
|
||||||
struct LineReader {
|
struct LineReader {
|
||||||
@ -16,13 +16,16 @@ impl LineReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feed(&mut self, c: u8) -> Option<&str> {
|
pub fn feed(&mut self, c: u8) -> Option<LineResult> {
|
||||||
if c == 13 || c == 10 {
|
if c == 13 || c == 10 {
|
||||||
// Enter
|
// Enter
|
||||||
if self.pos > 0 {
|
if self.pos > 0 {
|
||||||
let len = self.pos;
|
let len = self.pos;
|
||||||
self.pos = 0;
|
self.pos = 0;
|
||||||
core::str::from_utf8(&self.buf[..len]).ok()
|
Some(LineResult {
|
||||||
|
buf: self.buf.clone(),
|
||||||
|
len,
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -38,6 +41,18 @@ impl LineReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LineResult {
|
||||||
|
buf: [u8; MAX_LINE_LEN],
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for LineResult {
|
||||||
|
type Target = [u8];
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.buf[..self.len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ReportMode {
|
pub enum ReportMode {
|
||||||
Off,
|
Off,
|
||||||
@ -105,9 +120,10 @@ impl Session {
|
|||||||
let mut buf_bytes = 0;
|
let mut buf_bytes = 0;
|
||||||
for (i, b) in buf.iter().enumerate() {
|
for (i, b) in buf.iter().enumerate() {
|
||||||
buf_bytes = i + 1;
|
buf_bytes = i + 1;
|
||||||
match self.reader.feed(*b) {
|
let line = self.reader.feed(*b);
|
||||||
|
match line {
|
||||||
Some(line) => {
|
Some(line) => {
|
||||||
let command = Command::parse(line);
|
let command = Command::parse(&line);
|
||||||
match command {
|
match command {
|
||||||
Ok(Command::Report(mode)) => {
|
Ok(Command::Report(mode)) => {
|
||||||
self.report_mode = mode;
|
self.report_mode = mode;
|
||||||
|
Loading…
Reference in New Issue
Block a user