forked from extern/nushell
Add nu-protocol
This commit is contained in:
@ -3,117 +3,13 @@ use std::{
|
||||
ops::{Index, IndexMut},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
lex, lite_parse,
|
||||
parser_state::{Type, VarId},
|
||||
signature::{Flag, PositionalArg},
|
||||
BlockId, DeclId, Declaration, LiteBlock, ParseError, ParserWorkingSet, Signature, Span, Token,
|
||||
TokenContents,
|
||||
use crate::{lex, lite_parse, LiteBlock, ParseError, ParserWorkingSet, Token, TokenContents};
|
||||
|
||||
use nu_protocol::{
|
||||
span, BlockId, DeclId, Declaration, Flag, PositionalArg, Signature, Span, SyntaxShape, Type,
|
||||
VarId,
|
||||
};
|
||||
|
||||
/// The syntactic shapes that values must match to be passed into a command. You can think of this as the type-checking that occurs when you call a function.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SyntaxShape {
|
||||
/// A specific match to a word or symbol
|
||||
Keyword(Vec<u8>, Box<SyntaxShape>),
|
||||
|
||||
/// Any syntactic form is allowed
|
||||
Any,
|
||||
|
||||
/// Strings and string-like bare words are allowed
|
||||
String,
|
||||
|
||||
/// A dotted path to navigate the table
|
||||
ColumnPath,
|
||||
|
||||
/// A dotted path to navigate the table (including variable)
|
||||
FullColumnPath,
|
||||
|
||||
/// Only a numeric (integer or decimal) value is allowed
|
||||
Number,
|
||||
|
||||
/// A range is allowed (eg, `1..3`)
|
||||
Range,
|
||||
|
||||
/// Only an integer value is allowed
|
||||
Int,
|
||||
|
||||
/// A filepath is allowed
|
||||
FilePath,
|
||||
|
||||
/// A glob pattern is allowed, eg `foo*`
|
||||
GlobPattern,
|
||||
|
||||
/// A block is allowed, eg `{start this thing}`
|
||||
Block,
|
||||
|
||||
/// A table is allowed, eg `[[first, second]; [1, 2]]`
|
||||
Table,
|
||||
|
||||
/// A table is allowed, eg `[first second]`
|
||||
List(Box<SyntaxShape>),
|
||||
|
||||
/// A filesize value is allowed, eg `10kb`
|
||||
Filesize,
|
||||
|
||||
/// A duration value is allowed, eg `19day`
|
||||
Duration,
|
||||
|
||||
/// An operator
|
||||
Operator,
|
||||
|
||||
/// A math expression which expands shorthand forms on the lefthand side, eg `foo > 1`
|
||||
/// The shorthand allows us to more easily reach columns inside of the row being passed in
|
||||
RowCondition,
|
||||
|
||||
/// A general math expression, eg `1 + 2`
|
||||
MathExpression,
|
||||
|
||||
/// A variable name
|
||||
Variable,
|
||||
|
||||
/// A variable with optional type, `x` or `x: int`
|
||||
VarWithOptType,
|
||||
|
||||
/// A signature for a definition, `[x:int, --foo]`
|
||||
Signature,
|
||||
|
||||
/// A general expression, eg `1 + 2` or `foo --bar`
|
||||
Expression,
|
||||
}
|
||||
|
||||
impl SyntaxShape {
|
||||
pub fn to_type(&self) -> Type {
|
||||
match self {
|
||||
SyntaxShape::Any => Type::Unknown,
|
||||
SyntaxShape::Block => Type::Block,
|
||||
SyntaxShape::ColumnPath => Type::Unknown,
|
||||
SyntaxShape::Duration => Type::Duration,
|
||||
SyntaxShape::Expression => Type::Unknown,
|
||||
SyntaxShape::FilePath => Type::FilePath,
|
||||
SyntaxShape::Filesize => Type::Filesize,
|
||||
SyntaxShape::FullColumnPath => Type::Unknown,
|
||||
SyntaxShape::GlobPattern => Type::String,
|
||||
SyntaxShape::Int => Type::Int,
|
||||
SyntaxShape::List(x) => {
|
||||
let contents = x.to_type();
|
||||
Type::List(Box::new(contents))
|
||||
}
|
||||
SyntaxShape::Keyword(_, expr) => expr.to_type(),
|
||||
SyntaxShape::MathExpression => Type::Unknown,
|
||||
SyntaxShape::Number => Type::Number,
|
||||
SyntaxShape::Operator => Type::Unknown,
|
||||
SyntaxShape::Range => Type::Unknown,
|
||||
SyntaxShape::RowCondition => Type::Bool,
|
||||
SyntaxShape::Signature => Type::Unknown,
|
||||
SyntaxShape::String => Type::String,
|
||||
SyntaxShape::Table => Type::Table,
|
||||
SyntaxShape::VarWithOptType => Type::Unknown,
|
||||
SyntaxShape::Variable => Type::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Operator {
|
||||
Equal,
|
||||
@ -404,21 +300,6 @@ fn check_call(command: Span, sig: &Signature, call: &Call) -> Option<ParseError>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span(spans: &[Span]) -> Span {
|
||||
let length = spans.len();
|
||||
|
||||
if length == 0 {
|
||||
Span::unknown()
|
||||
} else if length == 1 {
|
||||
spans[0]
|
||||
} else {
|
||||
Span {
|
||||
start: spans[0].start,
|
||||
end: spans[length - 1].end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ParserWorkingSet<'a> {
|
||||
pub fn parse_external_call(&mut self, spans: &[Span]) -> (Expression, Option<ParseError>) {
|
||||
// TODO: add external parsing
|
||||
@ -725,7 +606,7 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
call.decl_id = decl_id;
|
||||
call.head = command_span;
|
||||
|
||||
let decl = self.get_decl(decl_id).clone();
|
||||
let signature = self.get_decl(decl_id).signature.clone();
|
||||
|
||||
// The index into the positional parameter in the definition
|
||||
let mut positional_idx = 0;
|
||||
@ -738,8 +619,7 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
let arg_span = spans[spans_idx];
|
||||
|
||||
// Check if we're on a long flag, if so, parse
|
||||
let (long_name, arg, err) =
|
||||
self.parse_long_flag(spans, &mut spans_idx, &decl.signature);
|
||||
let (long_name, arg, err) = self.parse_long_flag(spans, &mut spans_idx, &signature);
|
||||
if let Some(long_name) = long_name {
|
||||
// We found a long flag, like --bar
|
||||
error = error.or(err);
|
||||
@ -750,7 +630,7 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
|
||||
// Check if we're on a short flag or group of short flags, if so, parse
|
||||
let (short_flags, err) =
|
||||
self.parse_short_flags(spans, &mut spans_idx, positional_idx, &decl.signature);
|
||||
self.parse_short_flags(spans, &mut spans_idx, positional_idx, &signature);
|
||||
|
||||
if let Some(short_flags) = short_flags {
|
||||
error = error.or(err);
|
||||
@ -774,8 +654,9 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
}
|
||||
|
||||
// Parse a positional arg if there is one
|
||||
if let Some(positional) = decl.signature.get_positional(positional_idx) {
|
||||
if let Some(positional) = signature.get_positional(positional_idx) {
|
||||
//Make sure we leave enough spans for the remaining positionals
|
||||
let decl = self.get_decl(decl_id);
|
||||
|
||||
let end = self.calculate_end_span(&decl, spans, spans_idx, positional_idx);
|
||||
|
||||
@ -813,7 +694,7 @@ impl<'a> ParserWorkingSet<'a> {
|
||||
spans_idx += 1;
|
||||
}
|
||||
|
||||
let err = check_call(command_span, &decl.signature, &call);
|
||||
let err = check_call(command_span, &signature, &call);
|
||||
error = error.or(err);
|
||||
|
||||
// FIXME: type unknown
|
||||
|
Reference in New Issue
Block a user