nushell/crates/nu-protocol/src/signature.rs

252 lines
8.1 KiB
Rust
Raw Normal View History

use crate::syntax_shape::SyntaxShape;
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
use crate::type_shape::Type;
2019-05-26 08:54:41 +02:00
use indexmap::IndexMap;
use nu_source::{b, DebugDocBuilder, PrettyDebug, PrettyDebugWithSource};
2019-07-02 09:56:20 +02:00
use serde::{Deserialize, Serialize};
2019-05-26 08:54:41 +02:00
/// The types of named parameter that a command can have
2019-07-16 09:08:35 +02:00
#[derive(Debug, Serialize, Deserialize, Clone)]
2019-05-28 08:45:18 +02:00
pub enum NamedType {
/// A flag without any associated argument. eg) `foo --bar`
Switch,
/// A mandatory flag, with associated argument. eg) `foo --required xyz`
Mandatory(SyntaxShape),
/// An optional flag, with associated argument. eg) `foo --optional abc`
Optional(SyntaxShape),
Add --help for commands (#1226) * WIP --help works for PerItemCommands. * De-linting * Add more comments (#1228) * Add some more docs * More docs * More docs * More docs (#1229) * Add some more docs * More docs * More docs * Add more docs * External commands: wrap values that contain spaces in quotes (#1214) (#1220) * External commands: wrap values that contain spaces in quotes (#1214) * Add fn's argument_contains_whitespace & add_quotes (#1214) * Fix formatting with cargo fmt * Don't wrap argument in quotes when $it is already quoted (#1214) * Implement --help for internal commands * Externals now spawn independently. (#1230) This commit changes the way we shell out externals when using the `"$it"` argument. Also pipes per row to an external's stdin if no `"$it"` argument is present for external commands. Further separation of logic (preparing the external's command arguments, getting the data for piping, emitting values, spawning processes) will give us a better idea for lower level details regarding external commands until we can find the right abstractions for making them more generic and unify within the pipeline calling logic of Nu internal's and external's. * Poll externals quicker. (#1231) * WIP --help works for PerItemCommands. * De-linting * Implement --help for internal commands * Make having --help the default * Update test to include new default switch Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com> Co-authored-by: Koenraad Verheyden <mail@koenraadverheyden.com> Co-authored-by: Andrés N. Robalino <andres@androbtech.com>
2020-01-17 23:46:18 +01:00
Help,
2019-05-26 08:54:41 +02:00
}
/// The type of positional arguments
2019-07-02 09:56:20 +02:00
#[derive(Debug, Clone, Serialize, Deserialize)]
2019-05-28 08:45:18 +02:00
pub enum PositionalType {
/// A mandatory postional argument with the expected shape of the value
Mandatory(String, SyntaxShape),
/// An optional positional argument with the expected shape of the value
Optional(String, SyntaxShape),
2019-05-28 08:45:18 +02:00
}
impl PrettyDebug for PositionalType {
/// Prepare the PositionalType for pretty-printing
fn pretty(&self) -> DebugDocBuilder {
match self {
PositionalType::Mandatory(string, shape) => {
b::description(string) + b::delimit("(", shape.pretty(), ")").into_kind().group()
}
PositionalType::Optional(string, shape) => {
b::description(string)
+ b::operator("?")
+ b::delimit("(", shape.pretty(), ")").into_kind().group()
}
}
}
}
2019-05-28 08:45:18 +02:00
impl PositionalType {
/// Helper to create a mandatory positional argument type
pub fn mandatory(name: &str, ty: SyntaxShape) -> PositionalType {
2019-07-15 23:16:27 +02:00
PositionalType::Mandatory(name.to_string(), ty)
}
/// Helper to create a mandatory positional argument with an "any" type
2019-07-15 23:16:27 +02:00
pub fn mandatory_any(name: &str) -> PositionalType {
PositionalType::Mandatory(name.to_string(), SyntaxShape::Any)
2019-07-13 04:07:06 +02:00
}
/// Helper to create a mandatory positional argument with a block type
2019-07-16 21:10:25 +02:00
pub fn mandatory_block(name: &str) -> PositionalType {
PositionalType::Mandatory(name.to_string(), SyntaxShape::Block)
2019-07-16 21:10:25 +02:00
}
/// Helper to create a optional positional argument type
pub fn optional(name: &str, ty: SyntaxShape) -> PositionalType {
2019-07-16 09:25:48 +02:00
PositionalType::Optional(name.to_string(), ty)
}
/// Helper to create a optional positional argument with an "any" type
2019-07-16 09:25:48 +02:00
pub fn optional_any(name: &str) -> PositionalType {
PositionalType::Optional(name.to_string(), SyntaxShape::Any)
2019-07-16 09:25:48 +02:00
}
/// Gets the name of the positional argument
pub fn name(&self) -> &str {
match self {
PositionalType::Mandatory(s, _) => s,
PositionalType::Optional(s, _) => s,
}
}
2019-07-15 23:16:27 +02:00
/// Gets the expected type of a positional argument
pub fn syntax_type(&self) -> SyntaxShape {
2019-07-15 23:16:27 +02:00
match *self {
PositionalType::Mandatory(_, t) => t,
PositionalType::Optional(_, t) => t,
}
}
2019-05-28 08:45:18 +02:00
}
2019-10-28 06:15:35 +01:00
type Description = String;
/// The full signature of a command. All commands have a signature similar to a function signature.
/// Commands will use this information to register themselves with Nu's core engine so that the command
/// can be invoked, help can be displayed, and calls to the command can be error-checked.
2019-11-18 04:12:37 +01:00
#[derive(Debug, Serialize, Deserialize, Clone)]
2019-08-02 21:15:07 +02:00
pub struct Signature {
/// The name of the command. Used when calling the command
2019-07-02 09:56:20 +02:00
pub name: String,
/// Usage instructions about the command
pub usage: String,
/// The list of positional arguments, both required and optional, and their corresponding types and help text
2019-10-28 06:15:35 +01:00
pub positional: Vec<(PositionalType, Description)>,
/// After the positional arguments, a catch-all for the rest of the arguments that might follow, their type, and help text
2019-10-28 06:15:35 +01:00
pub rest_positional: Option<(SyntaxShape, Description)>,
/// The named flags with corresponding type and help text
2019-10-28 06:15:35 +01:00
pub named: IndexMap<String, (NamedType, Description)>,
/// The type of values being sent out from the command into the pipeline, if any
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
pub yields: Option<Type>,
/// The type of values being read in from the pipeline into the command, if any
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
pub input: Option<Type>,
/// If the command is expected to filter data, or to consume it (as a sink)
2019-07-02 09:56:20 +02:00
pub is_filter: bool,
2019-05-28 08:45:18 +02:00
}
impl PrettyDebugWithSource for Signature {
/// Prepare a Signature for pretty-printing
fn pretty_debug(&self, source: &str) -> DebugDocBuilder {
b::typed(
"signature",
b::description(&self.name)
+ b::preceded(
b::space(),
b::intersperse(
self.positional
.iter()
.map(|(ty, _)| ty.pretty_debug(source)),
b::space(),
),
),
)
}
}
2019-08-02 21:15:07 +02:00
impl Signature {
/// Create a new command signagure with the given name
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
pub fn new(name: impl Into<String>) -> Signature {
2019-11-18 04:12:37 +01:00
Signature {
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
name: name.into(),
2019-11-18 04:12:37 +01:00
usage: String::new(),
positional: vec![],
rest_positional: None,
Add --help for commands (#1226) * WIP --help works for PerItemCommands. * De-linting * Add more comments (#1228) * Add some more docs * More docs * More docs * More docs (#1229) * Add some more docs * More docs * More docs * Add more docs * External commands: wrap values that contain spaces in quotes (#1214) (#1220) * External commands: wrap values that contain spaces in quotes (#1214) * Add fn's argument_contains_whitespace & add_quotes (#1214) * Fix formatting with cargo fmt * Don't wrap argument in quotes when $it is already quoted (#1214) * Implement --help for internal commands * Externals now spawn independently. (#1230) This commit changes the way we shell out externals when using the `"$it"` argument. Also pipes per row to an external's stdin if no `"$it"` argument is present for external commands. Further separation of logic (preparing the external's command arguments, getting the data for piping, emitting values, spawning processes) will give us a better idea for lower level details regarding external commands until we can find the right abstractions for making them more generic and unify within the pipeline calling logic of Nu internal's and external's. * Poll externals quicker. (#1231) * WIP --help works for PerItemCommands. * De-linting * Implement --help for internal commands * Make having --help the default * Update test to include new default switch Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com> Co-authored-by: Koenraad Verheyden <mail@koenraadverheyden.com> Co-authored-by: Andrés N. Robalino <andres@androbtech.com>
2020-01-17 23:46:18 +01:00
named: indexmap::indexmap! {"help".into() => (NamedType::Help, "Display this help message".into())},
2019-11-18 04:12:37 +01:00
is_filter: false,
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
yields: None,
input: None,
2019-11-18 04:12:37 +01:00
}
}
/// Create a new signature
2019-08-02 21:15:07 +02:00
pub fn build(name: impl Into<String>) -> Signature {
Signature::new(name.into())
2019-07-24 06:10:48 +02:00
}
/// Add a description to the signature
pub fn desc(mut self, usage: impl Into<String>) -> Signature {
self.usage = usage.into();
self
}
/// Add a required positional argument to the signature
2019-10-28 06:15:35 +01:00
pub fn required(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
self.positional.push((
PositionalType::Mandatory(name.into(), ty.into()),
desc.into(),
));
2019-07-24 06:10:48 +02:00
self
}
/// Add an optional positional argument to the signature
2019-10-28 06:15:35 +01:00
pub fn optional(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
self.positional.push((
PositionalType::Optional(name.into(), ty.into()),
desc.into(),
));
2019-07-24 06:10:48 +02:00
self
}
/// Add an optional named flag argument to the signature
2019-10-28 06:15:35 +01:00
pub fn named(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
desc: impl Into<String>,
) -> Signature {
2019-08-02 21:15:07 +02:00
self.named
2019-10-28 06:15:35 +01:00
.insert(name.into(), (NamedType::Optional(ty.into()), desc.into()));
2019-08-02 21:15:07 +02:00
self
}
/// Add a required named flag argument to the signature
2019-08-02 21:15:07 +02:00
pub fn required_named(
mut self,
name: impl Into<String>,
ty: impl Into<SyntaxShape>,
2019-10-28 06:15:35 +01:00
desc: impl Into<String>,
2019-08-02 21:15:07 +02:00
) -> Signature {
self.named
2019-10-28 06:15:35 +01:00
.insert(name.into(), (NamedType::Mandatory(ty.into()), desc.into()));
2019-08-02 21:15:07 +02:00
self
}
/// Add a switch to the signature
2019-10-28 06:15:35 +01:00
pub fn switch(mut self, name: impl Into<String>, desc: impl Into<String>) -> Signature {
self.named
.insert(name.into(), (NamedType::Switch, desc.into()));
2019-07-24 06:10:48 +02:00
self
}
Add --help for commands (#1226) * WIP --help works for PerItemCommands. * De-linting * Add more comments (#1228) * Add some more docs * More docs * More docs * More docs (#1229) * Add some more docs * More docs * More docs * Add more docs * External commands: wrap values that contain spaces in quotes (#1214) (#1220) * External commands: wrap values that contain spaces in quotes (#1214) * Add fn's argument_contains_whitespace & add_quotes (#1214) * Fix formatting with cargo fmt * Don't wrap argument in quotes when $it is already quoted (#1214) * Implement --help for internal commands * Externals now spawn independently. (#1230) This commit changes the way we shell out externals when using the `"$it"` argument. Also pipes per row to an external's stdin if no `"$it"` argument is present for external commands. Further separation of logic (preparing the external's command arguments, getting the data for piping, emitting values, spawning processes) will give us a better idea for lower level details regarding external commands until we can find the right abstractions for making them more generic and unify within the pipeline calling logic of Nu internal's and external's. * Poll externals quicker. (#1231) * WIP --help works for PerItemCommands. * De-linting * Implement --help for internal commands * Make having --help the default * Update test to include new default switch Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com> Co-authored-by: Koenraad Verheyden <mail@koenraadverheyden.com> Co-authored-by: Andrés N. Robalino <andres@androbtech.com>
2020-01-17 23:46:18 +01:00
/// Remove the default help switch
pub fn remove_help(mut self) -> Signature {
self.named.remove("help");
self
}
/// Set the filter flag for the signature
2019-08-02 21:15:07 +02:00
pub fn filter(mut self) -> Signature {
self.is_filter = true;
self
}
/// Set the type for the "rest" of the positional arguments
2019-10-28 06:15:35 +01:00
pub fn rest(mut self, ty: SyntaxShape, desc: impl Into<String>) -> Signature {
self.rest_positional = Some((ty, desc.into()));
2019-08-02 21:15:07 +02:00
self
}
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
/// Add a type for the output of the command to the signature
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
pub fn yields(mut self, ty: Type) -> Signature {
self.yields = Some(ty);
self
}
/// Add a type for the input of the command to the signature
Add Range and start Signature support This commit contains two improvements: - Support for a Range syntax (and a corresponding Range value) - Work towards a signature syntax Implementing the Range syntax resulted in cleaning up how operators in the core syntax works. There are now two kinds of infix operators - tight operators (`.` and `..`) - loose operators Tight operators may not be interspersed (`$it.left..$it.right` is a syntax error). Loose operators require whitespace on both sides of the operator, and can be arbitrarily interspersed. Precedence is left to right in the core syntax. Note that delimited syntax (like `( ... )` or `[ ... ]`) is a single token node in the core syntax. A single token node can be parsed from beginning to end in a context-free manner. The rule for `.` is `<token node>.<member>`. The rule for `..` is `<token node>..<token node>`. Loose operators all have the same syntactic rule: `<token node><space><loose op><space><token node>`. The second aspect of this pull request is the beginning of support for a signature syntax. Before implementing signatures, a necessary prerequisite is for the core syntax to support multi-line programs. That work establishes a few things: - `;` and newlines are handled in the core grammar, and both count as "separators" - line comments begin with `#` and continue until the end of the line In this commit, multi-token productions in the core grammar can use separators interchangably with spaces. However, I think we will ultimately want a different rule preventing separators from occurring before an infix operator, so that the end of a line is always unambiguous. This would avoid gratuitous differences between modules and repl usage. We already effectively have this rule, because otherwise `x<newline> | y` would be a single pipeline, but of course that wouldn't work.
2019-12-04 22:14:52 +01:00
pub fn input(mut self, ty: Type) -> Signature {
self.input = Some(ty);
self
}
2019-07-24 06:10:48 +02:00
}