2019-06-22 03:36:57 +02:00
|
|
|
crate mod baseline_parse;
|
|
|
|
crate mod baseline_parse_tokens;
|
|
|
|
crate mod binary;
|
|
|
|
crate mod named;
|
|
|
|
crate mod path;
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
use crate::evaluate::Scope;
|
2019-08-09 06:51:21 +02:00
|
|
|
use crate::parser::{registry, Unit};
|
2019-07-24 00:22:11 +02:00
|
|
|
use crate::prelude::*;
|
2019-06-22 03:36:57 +02:00
|
|
|
use derive_new::new;
|
|
|
|
use getset::Getters;
|
2019-08-02 21:15:07 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
2019-07-24 00:22:11 +02:00
|
|
|
use std::fmt;
|
2019-06-22 03:36:57 +02:00
|
|
|
|
2019-07-15 23:16:27 +02:00
|
|
|
crate use baseline_parse::{baseline_parse_single_token, baseline_parse_token_as_string};
|
|
|
|
crate use baseline_parse_tokens::{baseline_parse_next_expr, SyntaxType, TokensIterator};
|
2019-06-22 03:36:57 +02:00
|
|
|
crate use binary::Binary;
|
|
|
|
crate use named::NamedArguments;
|
|
|
|
crate use path::Path;
|
|
|
|
|
2019-08-01 03:58:42 +02:00
|
|
|
pub fn path(head: impl Into<Expression>, tail: Vec<Tagged<impl Into<String>>>) -> Path {
|
2019-06-29 10:55:42 +02:00
|
|
|
Path::new(
|
|
|
|
head.into(),
|
|
|
|
tail.into_iter()
|
|
|
|
.map(|item| item.map(|string| string.into()))
|
|
|
|
.collect(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Getters, Serialize, Deserialize, new)]
|
2019-06-22 03:36:57 +02:00
|
|
|
pub struct Call {
|
|
|
|
#[get = "crate"]
|
|
|
|
head: Box<Expression>,
|
|
|
|
#[get = "crate"]
|
|
|
|
positional: Option<Vec<Expression>>,
|
|
|
|
#[get = "crate"]
|
|
|
|
named: Option<NamedArguments>,
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
impl Call {
|
|
|
|
pub fn evaluate(
|
|
|
|
&self,
|
|
|
|
registry: ®istry::CommandRegistry,
|
|
|
|
scope: &Scope,
|
|
|
|
source: &Text,
|
|
|
|
) -> Result<registry::EvaluatedArgs, ShellError> {
|
|
|
|
registry::evaluate_args(self, registry, scope, source)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToDebug for Call {
|
|
|
|
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
|
|
|
write!(f, "({}", self.head.debug(source))?;
|
|
|
|
|
|
|
|
if let Some(positional) = &self.positional {
|
|
|
|
write!(f, " ")?;
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"{}",
|
|
|
|
&itertools::join(positional.iter().map(|p| p.debug(source)), " ")
|
|
|
|
)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(named) = &self.named {
|
|
|
|
write!(f, "{}", named.debug(source))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
2019-06-22 03:36:57 +02:00
|
|
|
pub enum RawExpression {
|
|
|
|
Literal(Literal),
|
2019-07-24 00:22:11 +02:00
|
|
|
Synthetic(Synthetic),
|
2019-06-22 03:36:57 +02:00
|
|
|
Variable(Variable),
|
|
|
|
Binary(Box<Binary>),
|
2019-06-29 10:55:42 +02:00
|
|
|
Block(Vec<Expression>),
|
2019-08-02 21:15:07 +02:00
|
|
|
List(Vec<Expression>),
|
2019-06-22 03:36:57 +02:00
|
|
|
Path(Box<Path>),
|
|
|
|
|
|
|
|
#[allow(unused)]
|
|
|
|
Boolean(bool),
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum Synthetic {
|
|
|
|
String(String),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Synthetic {
|
|
|
|
pub fn type_name(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Synthetic::String(_) => "string",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-30 08:14:40 +02:00
|
|
|
impl RawExpression {
|
|
|
|
pub fn type_name(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
RawExpression::Literal(literal) => literal.type_name(),
|
2019-07-24 00:22:11 +02:00
|
|
|
RawExpression::Synthetic(synthetic) => synthetic.type_name(),
|
2019-06-30 08:14:40 +02:00
|
|
|
RawExpression::Variable(..) => "variable",
|
2019-08-02 21:15:07 +02:00
|
|
|
RawExpression::List(..) => "list",
|
2019-06-30 08:14:40 +02:00
|
|
|
RawExpression::Binary(..) => "binary",
|
|
|
|
RawExpression::Block(..) => "block",
|
|
|
|
RawExpression::Path(..) => "path",
|
|
|
|
RawExpression::Boolean(..) => "boolean",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-01 03:58:42 +02:00
|
|
|
pub type Expression = Tagged<RawExpression>;
|
2019-06-22 03:36:57 +02:00
|
|
|
|
|
|
|
impl Expression {
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn int(i: impl Into<i64>, span: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Integer(i.into())), span)
|
2019-06-22 03:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn size(i: impl Into<i64>, unit: impl Into<Unit>, span: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(
|
2019-06-22 03:36:57 +02:00
|
|
|
RawExpression::Literal(Literal::Size(i.into(), unit.into())),
|
|
|
|
span,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn synthetic_string(s: impl Into<String>) -> Expression {
|
2019-08-09 06:51:21 +02:00
|
|
|
RawExpression::Synthetic(Synthetic::String(s.into())).tagged_unknown()
|
2019-07-24 00:22:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
crate fn string(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(
|
2019-06-22 03:36:57 +02:00
|
|
|
RawExpression::Literal(Literal::String(inner.into())),
|
|
|
|
outer.into(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn bare(span: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(RawExpression::Literal(Literal::Bare), span.into())
|
2019-06-22 03:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(
|
2019-06-22 03:36:57 +02:00
|
|
|
RawExpression::Variable(Variable::Other(inner.into())),
|
|
|
|
outer.into(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
crate fn it_variable(inner: impl Into<Span>, outer: impl Into<Span>) -> Expression {
|
2019-08-05 10:54:29 +02:00
|
|
|
Tagged::from_simple_spanned_item(
|
2019-06-22 03:36:57 +02:00
|
|
|
RawExpression::Variable(Variable::It(inner.into())),
|
|
|
|
outer.into(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
impl ToDebug for Expression {
|
|
|
|
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
|
|
|
match self.item() {
|
2019-08-09 06:51:21 +02:00
|
|
|
RawExpression::Literal(l) => write!(f, "{:?}", l),
|
2019-07-24 00:22:11 +02:00
|
|
|
RawExpression::Synthetic(Synthetic::String(s)) => write!(f, "{:?}", s),
|
|
|
|
RawExpression::Variable(Variable::It(_)) => write!(f, "$it"),
|
|
|
|
RawExpression::Variable(Variable::Other(s)) => write!(f, "${}", s.slice(source)),
|
|
|
|
RawExpression::Binary(b) => write!(f, "{}", b.debug(source)),
|
|
|
|
RawExpression::Block(exprs) => {
|
|
|
|
write!(f, "{{ ")?;
|
|
|
|
|
|
|
|
for expr in exprs {
|
|
|
|
write!(f, "{} ", expr.debug(source))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "}}")
|
|
|
|
}
|
2019-08-02 21:15:07 +02:00
|
|
|
RawExpression::List(exprs) => {
|
|
|
|
write!(f, "[ ")?;
|
|
|
|
|
|
|
|
for expr in exprs {
|
|
|
|
write!(f, "{} ", expr.debug(source))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "]")
|
|
|
|
}
|
2019-07-24 00:22:11 +02:00
|
|
|
RawExpression::Path(p) => write!(f, "{}", p.debug(source)),
|
|
|
|
RawExpression::Boolean(true) => write!(f, "$yes"),
|
|
|
|
RawExpression::Boolean(false) => write!(f, "$no"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-01 03:58:42 +02:00
|
|
|
impl From<Tagged<Path>> for Expression {
|
|
|
|
fn from(path: Tagged<Path>) -> Expression {
|
2019-06-29 10:55:42 +02:00
|
|
|
path.map(|p| RawExpression::Path(Box::new(p)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
2019-06-22 03:36:57 +02:00
|
|
|
pub enum Literal {
|
|
|
|
Integer(i64),
|
|
|
|
Size(i64, Unit),
|
|
|
|
String(Span),
|
|
|
|
Bare,
|
|
|
|
}
|
|
|
|
|
2019-08-09 06:51:21 +02:00
|
|
|
impl ToDebug for Tagged<&Literal> {
|
2019-07-24 00:22:11 +02:00
|
|
|
fn fmt_debug(&self, f: &mut fmt::Formatter, source: &str) -> fmt::Result {
|
|
|
|
match self.item() {
|
|
|
|
Literal::Integer(int) => write!(f, "{}", *int),
|
|
|
|
Literal::Size(int, unit) => write!(f, "{}{:?}", *int, unit),
|
|
|
|
Literal::String(span) => write!(f, "{}", span.slice(source)),
|
|
|
|
Literal::Bare => write!(f, "{}", self.span().slice(source)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-30 08:14:40 +02:00
|
|
|
impl Literal {
|
|
|
|
fn type_name(&self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Literal::Integer(_) => "integer",
|
|
|
|
Literal::Size(..) => "size",
|
|
|
|
Literal::String(..) => "string",
|
|
|
|
Literal::Bare => "string",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:22:11 +02:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
|
2019-06-22 03:36:57 +02:00
|
|
|
pub enum Variable {
|
|
|
|
It(Span),
|
|
|
|
Other(Span),
|
|
|
|
}
|