Support evaluating most expressions

Blocks, paths, and others

Plus a bunch of other infra improvements
This commit is contained in:
Yehuda Katz
2019-06-29 01:55:42 -07:00
parent 7074d3ffcc
commit 3379c23a49
13 changed files with 497 additions and 150 deletions

View File

@ -12,6 +12,14 @@ pub struct Spanned<T> {
pub item: T,
}
pub trait SpannedItem: Sized {
fn spanned(self, span: impl Into<Span>) -> Spanned<Self> {
Spanned::from_item(self, span.into())
}
}
impl<T> SpannedItem for T {}
impl<T> std::ops::Deref for Spanned<T> {
type Target = T;
@ -56,6 +64,12 @@ pub struct Span {
// source: &'source str,
}
impl<T> From<&Spanned<T>> for Span {
fn from(input: &Spanned<T>) -> Span {
input.span
}
}
impl From<&Span> for Span {
fn from(input: &Span) -> Span {
*input

View File

@ -3,6 +3,8 @@ use crate::parser::parse::{call_node::*, flag::*, operator::*, pipeline::*, span
use crate::Text;
use derive_new::new;
use enum_utils::FromStr;
use getset::Getters;
use std::fmt;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum TokenNode {
@ -20,6 +22,67 @@ pub enum TokenNode {
Path(Spanned<PathNode>),
}
pub struct DebugTokenNode<'a> {
node: &'a TokenNode,
source: &'a Text,
}
impl fmt::Debug for DebugTokenNode<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.node {
TokenNode::Token(t) => write!(f, "{:?}", t.debug(self.source)),
TokenNode::Call(s) => {
write!(f, "(")?;
write!(f, "{:?}", s.head().debug(self.source))?;
if let Some(children) = s.children() {
for child in children {
write!(f, "{:?}", child.debug(self.source))?;
}
}
write!(f, ")")
}
TokenNode::Delimited(d) => {
write!(
f,
"{}",
match d.delimiter {
Delimiter::Brace => "{",
Delimiter::Paren => "(",
Delimiter::Square => "[",
}
)?;
for child in d.children() {
write!(f, "{:?}", child.debug(self.source))?;
}
write!(
f,
"{}",
match d.delimiter {
Delimiter::Brace => "}",
Delimiter::Paren => ")",
Delimiter::Square => "]",
}
)
}
TokenNode::Pipeline(s) => write!(f, "<todo:pipeline>"),
TokenNode::Error(s) => write!(f, "<error> for {:?}", s.span().slice(self.source)),
rest => write!(f, "{}", rest.span().slice(self.source)),
}
}
}
impl From<&TokenNode> for Span {
fn from(token: &TokenNode) -> Span {
token.span()
}
}
impl TokenNode {
pub fn span(&self) -> Span {
match self {
@ -36,6 +99,10 @@ impl TokenNode {
}
}
pub fn debug(&'a self, source: &'a Text) -> DebugTokenNode<'a> {
DebugTokenNode { node: self, source }
}
pub fn as_external_arg(&self, source: &Text) -> String {
self.span().slice(source).to_string()
}
@ -73,7 +140,8 @@ impl TokenNode {
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, new)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
#[get = "crate"]
pub struct DelimitedNode {
delimiter: Delimiter,
children: Vec<TokenNode>,
@ -86,7 +154,8 @@ pub enum Delimiter {
Square,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, new)]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
#[get = "crate"]
pub struct PathNode {
head: Box<TokenNode>,
tail: Vec<TokenNode>,

View File

@ -1,5 +1,7 @@
use crate::parser::parse::span::*;
use crate::parser::parse::unit::*;
use crate::Text;
use std::fmt;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum RawToken {
@ -10,4 +12,36 @@ pub enum RawToken {
Bare,
}
impl RawToken {
pub fn type_name(&self) -> &'static str {
match self {
RawToken::Integer(_) => "Integer",
RawToken::Size(..) => "Size",
RawToken::String(_) => "String",
RawToken::Variable(_) => "Variable",
RawToken::Bare => "String",
}
}
}
pub type Token = Spanned<RawToken>;
impl Token {
pub fn debug(&self, source: &'a Text) -> DebugToken<'a> {
DebugToken {
node: *self,
source,
}
}
}
pub struct DebugToken<'a> {
node: Token,
source: &'a Text,
}
impl fmt::Debug for DebugToken<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.node.span().slice(self.source))
}
}