mirror of
https://github.com/nushell/nushell.git
synced 2025-04-29 07:34:28 +02:00
* Put parse_definition related funcs into own module * Add failing lexer test * Implement Parsing of definition signature This commit applied changes how the signature of a function is parsed. Before there was a little bit of "quick-and-dirty" string-matching/parsing involved. Now, a signature is a little bit more properly parsed. The grammar of a definition signature understood by these parsing-functions is as follows: `[ (parameter | flag | <eol>)* ]` where parameter is: `name (<:> type)? (<,> | <eol> | (#Comment <eol>))?` flag is: `--name (-shortform)? (<:> type)? (<,> | <eol> | (#Comment <eol>))?` (Note: After the last item no <,> has to come.) Note: It is now possible to pass comments to flags and parameters Example: [ d:int # The required d parameter --x (-x):string # The all powerful x flag --y (-y):int # The accompanying y flag ] (Sadly there seems to be a bug (Or is this expected behaviour?) in the lexer, because of which `--x(-x)` would be treated as one baseline token and is therefore not correctly recognized as 2. For now a space has to be inserted) During the implementation of the module, 2 question arose: Should flag/parameter names be allowed to be type names? Example case: ```shell def f [ string ] { echo $string } ``` Currently an error is thrown * Fix clippy lints * Remove wrong comment * Add spacing * Add Cargo.lock
48 lines
1.3 KiB
Rust
48 lines
1.3 KiB
Rust
use nu_errors::ParseError;
|
|
use nu_protocol::hir::{Expression, SpannedExpression};
|
|
use nu_source::{Span, Spanned, SpannedItem};
|
|
|
|
use crate::lex::Token;
|
|
|
|
pub(crate) fn token_to_spanned_string(token: &Token) -> Spanned<String> {
|
|
token.contents.to_string().spanned(token.span)
|
|
}
|
|
|
|
/// Easy shorthand function to create a garbage expression at the given span
|
|
pub fn garbage(span: Span) -> SpannedExpression {
|
|
SpannedExpression::new(Expression::Garbage, span)
|
|
}
|
|
|
|
pub(crate) fn trim_quotes(input: &str) -> String {
|
|
let mut chars = input.chars();
|
|
|
|
match (chars.next(), chars.next_back()) {
|
|
(Some('\''), Some('\'')) => chars.collect(),
|
|
(Some('"'), Some('"')) => chars.collect(),
|
|
(Some('`'), Some('`')) => chars.collect(),
|
|
_ => input.to_string(),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn verify_and_strip(
|
|
contents: &Spanned<String>,
|
|
left: char,
|
|
right: char,
|
|
) -> (String, Option<ParseError>) {
|
|
let mut chars = contents.item.chars();
|
|
|
|
match (chars.next(), chars.next_back()) {
|
|
(Some(l), Some(r)) if l == left && r == right => {
|
|
let output: String = chars.collect();
|
|
(output, None)
|
|
}
|
|
_ => (
|
|
String::new(),
|
|
Some(ParseError::mismatch(
|
|
format!("value in {} {}", left, right),
|
|
contents.clone(),
|
|
)),
|
|
),
|
|
}
|
|
}
|