rename expr to ast
This commit is contained in:
parent
641796d38f
commit
5899489250
6 changed files with 71 additions and 70 deletions
|
@ -1,4 +1,4 @@
|
||||||
use eww_config::{config::*, expr::*};
|
use eww_config::{ast::*, config::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut files = codespan_reporting::files::SimpleFiles::new();
|
let mut files = codespan_reporting::files::SimpleFiles::new();
|
||||||
|
@ -7,7 +7,7 @@ fn main() {
|
||||||
|
|
||||||
let file_id = files.add("foo.eww", input);
|
let file_id = files.add("foo.eww", input);
|
||||||
let ast = eww_config::parse_string(file_id, input);
|
let ast = eww_config::parse_string(file_id, input);
|
||||||
match ast.and_then(Element::<Expr, Expr>::from_expr) {
|
match ast.and_then(Element::<Ast, Ast>::from_ast) {
|
||||||
Ok(ast) => {
|
Ok(ast) => {
|
||||||
println!("{:?}", ast);
|
println!("{:?}", ast);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{config::FromExpr, error::*};
|
use crate::{config::FromAst, error::*};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||||
|
@ -20,7 +20,7 @@ impl std::fmt::Debug for Span {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
pub enum ExprType {
|
pub enum AstType {
|
||||||
List,
|
List,
|
||||||
Keyword,
|
Keyword,
|
||||||
Symbol,
|
Symbol,
|
||||||
|
@ -28,15 +28,16 @@ pub enum ExprType {
|
||||||
Comment,
|
Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ExprType {
|
impl Display for AstType {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "{:?}", self)
|
write!(f, "{:?}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub enum Expr {
|
pub enum Ast {
|
||||||
List(Span, Vec<Expr>),
|
List(Span, Vec<Ast>),
|
||||||
|
// ArgList(Span, Vec<Ast>),
|
||||||
Keyword(Span, String),
|
Keyword(Span, String),
|
||||||
Symbol(Span, String),
|
Symbol(Span, String),
|
||||||
Value(Span, String),
|
Value(Span, String),
|
||||||
|
@ -61,46 +62,46 @@ macro_rules! as_func {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expr {
|
impl Ast {
|
||||||
as_func!(ExprType::Value, as_value as_value_ref<String> = Expr::Value(_, x) => x);
|
as_func!(AstType::Value, as_value as_value_ref<String> = Ast::Value(_, x) => x);
|
||||||
|
|
||||||
as_func!(ExprType::Symbol, as_symbol as_symbol_ref<String> = Expr::Symbol(_, x) => x);
|
as_func!(AstType::Symbol, as_symbol as_symbol_ref<String> = Ast::Symbol(_, x) => x);
|
||||||
|
|
||||||
as_func!(ExprType::Keyword, as_keyword as_keyword_ref<String> = Expr::Keyword(_, x) => x);
|
as_func!(AstType::Keyword, as_keyword as_keyword_ref<String> = Ast::Keyword(_, x) => x);
|
||||||
|
|
||||||
as_func!(ExprType::List, as_list as_list_ref<Vec<Expr>> = Expr::List(_, x) => x);
|
as_func!(AstType::List, as_list as_list_ref<Vec<Ast>> = Ast::List(_, x) => x);
|
||||||
|
|
||||||
pub fn expr_type(&self) -> ExprType {
|
pub fn expr_type(&self) -> AstType {
|
||||||
match self {
|
match self {
|
||||||
Expr::List(..) => ExprType::List,
|
Ast::List(..) => AstType::List,
|
||||||
Expr::Keyword(..) => ExprType::Keyword,
|
Ast::Keyword(..) => AstType::Keyword,
|
||||||
Expr::Symbol(..) => ExprType::Symbol,
|
Ast::Symbol(..) => AstType::Symbol,
|
||||||
Expr::Value(..) => ExprType::Value,
|
Ast::Value(..) => AstType::Value,
|
||||||
Expr::Comment(_) => ExprType::Comment,
|
Ast::Comment(_) => AstType::Comment,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
match self {
|
match self {
|
||||||
Expr::List(span, _) => *span,
|
Ast::List(span, _) => *span,
|
||||||
Expr::Keyword(span, _) => *span,
|
Ast::Keyword(span, _) => *span,
|
||||||
Expr::Symbol(span, _) => *span,
|
Ast::Symbol(span, _) => *span,
|
||||||
Expr::Value(span, _) => *span,
|
Ast::Value(span, _) => *span,
|
||||||
Expr::Comment(span) => *span,
|
Ast::Comment(span) => *span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn first_list_elem(&self) -> Option<&Expr> {
|
pub fn first_list_elem(&self) -> Option<&Ast> {
|
||||||
match self {
|
match self {
|
||||||
Expr::List(_, list) => list.first(),
|
Ast::List(_, list) => list.first(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Expr {
|
impl std::fmt::Display for Ast {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
use Expr::*;
|
use Ast::*;
|
||||||
match self {
|
match self {
|
||||||
List(_, x) => write!(f, "({})", x.iter().map(|e| format!("{}", e)).join(" ")),
|
List(_, x) => write!(f, "({})", x.iter().map(|e| format!("{}", e)).join(" ")),
|
||||||
Keyword(_, x) => write!(f, "{}", x),
|
Keyword(_, x) => write!(f, "{}", x),
|
||||||
|
@ -110,9 +111,9 @@ impl std::fmt::Display for Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl std::fmt::Debug for Expr {
|
impl std::fmt::Debug for Ast {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
use Expr::*;
|
use Ast::*;
|
||||||
match self {
|
match self {
|
||||||
List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(),
|
List(span, x) => f.debug_tuple(&format!("List<{}>", span)).field(x).finish(),
|
||||||
Keyword(span, x) => write!(f, "Number<{}>({})", span, x),
|
Keyword(span, x) => write!(f, "Number<{}>({})", span, x),
|
||||||
|
@ -123,7 +124,7 @@ impl std::fmt::Debug for Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ExprIterator<I: Iterator<Item = Expr>> {
|
pub struct AstIterator<I: Iterator<Item = Ast>> {
|
||||||
iter: itertools::PutBack<I>,
|
iter: itertools::PutBack<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,24 +146,24 @@ macro_rules! return_or_put_back {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator<Item = Expr>> ExprIterator<I> {
|
impl<I: Iterator<Item = Ast>> AstIterator<I> {
|
||||||
return_or_put_back!(expect_symbol, ExprType::Symbol, (Span, String) = Expr::Symbol(span, x) => (span, x));
|
return_or_put_back!(expect_symbol, AstType::Symbol, (Span, String) = Ast::Symbol(span, x) => (span, x));
|
||||||
|
|
||||||
return_or_put_back!(expect_string, ExprType::Value, (Span, String) = Expr::Value(span, x) => (span, x));
|
return_or_put_back!(expect_string, AstType::Value, (Span, String) = Ast::Value(span, x) => (span, x));
|
||||||
|
|
||||||
return_or_put_back!(expect_list, ExprType::List, (Span, Vec<Expr>) = Expr::List(span, x) => (span, x));
|
return_or_put_back!(expect_list, AstType::List, (Span, Vec<Ast>) = Ast::List(span, x) => (span, x));
|
||||||
|
|
||||||
pub fn new(iter: I) -> Self {
|
pub fn new(iter: I) -> Self {
|
||||||
ExprIterator { iter: itertools::put_back(iter) }
|
AstIterator { iter: itertools::put_back(iter) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_key_values<T: FromExpr>(&mut self) -> AstResult<HashMap<String, T>> {
|
pub fn expect_key_values<T: FromAst>(&mut self) -> AstResult<HashMap<String, T>> {
|
||||||
parse_key_values(&mut self.iter)
|
parse_key_values(&mut self.iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Iterator<Item = Expr>> Iterator for ExprIterator<I> {
|
impl<I: Iterator<Item = Ast>> Iterator for AstIterator<I> {
|
||||||
type Item = Expr;
|
type Item = Ast;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.iter.next()
|
self.iter.next()
|
||||||
|
@ -170,16 +171,16 @@ impl<I: Iterator<Item = Expr>> Iterator for ExprIterator<I> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse consecutive `:keyword value` pairs from an expression iterator into a HashMap. Transforms the keys using the FromExpr trait.
|
/// Parse consecutive `:keyword value` pairs from an expression iterator into a HashMap. Transforms the keys using the FromExpr trait.
|
||||||
fn parse_key_values<T: FromExpr, I: Iterator<Item = Expr>>(iter: &mut itertools::PutBack<I>) -> AstResult<HashMap<String, T>> {
|
fn parse_key_values<T: FromAst, I: Iterator<Item = Ast>>(iter: &mut itertools::PutBack<I>) -> AstResult<HashMap<String, T>> {
|
||||||
let mut data = HashMap::new();
|
let mut data = HashMap::new();
|
||||||
loop {
|
loop {
|
||||||
match iter.next() {
|
match iter.next() {
|
||||||
Some(Expr::Keyword(span, kw)) => match iter.next() {
|
Some(Ast::Keyword(span, kw)) => match iter.next() {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
data.insert(kw, T::from_expr(value)?);
|
data.insert(kw, T::from_ast(value)?);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
iter.put_back(Expr::Keyword(span, kw));
|
iter.put_back(Ast::Keyword(span, kw));
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
},
|
},
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
ast::{Ast, AstIterator, AstType, Span},
|
||||||
error::*,
|
error::*,
|
||||||
expr::{Expr, ExprIterator, ExprType, Span},
|
|
||||||
parser, spanned,
|
parser, spanned,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -14,12 +14,12 @@ type VarName = String;
|
||||||
type AttrValue = String;
|
type AttrValue = String;
|
||||||
type AttrName = String;
|
type AttrName = String;
|
||||||
|
|
||||||
pub trait FromExpr: Sized {
|
pub trait FromAst: Sized {
|
||||||
fn from_expr(e: Expr) -> AstResult<Self>;
|
fn from_ast(e: Ast) -> AstResult<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromExpr for Expr {
|
impl FromAst for Ast {
|
||||||
fn from_expr(e: Expr) -> AstResult<Self> {
|
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||||
Ok(e)
|
Ok(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,15 @@ pub struct Element<C, A> {
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: FromExpr, A: FromExpr> FromExpr for Element<C, A> {
|
impl<C: FromAst, A: FromAst> FromAst for Element<C, A> {
|
||||||
fn from_expr(e: Expr) -> AstResult<Self> {
|
fn from_ast(e: Ast) -> AstResult<Self> {
|
||||||
let span = e.span();
|
let span = e.span();
|
||||||
spanned!(e.span(), {
|
spanned!(e.span(), {
|
||||||
let list = e.as_list()?;
|
let list = e.as_list()?;
|
||||||
let mut iter = ExprIterator::new(list.into_iter());
|
let mut iter = AstIterator::new(list.into_iter());
|
||||||
let (_, name) = iter.expect_symbol()?;
|
let (_, name) = iter.expect_symbol()?;
|
||||||
let attrs = iter.expect_key_values()?;
|
let attrs = iter.expect_key_values()?;
|
||||||
let children = iter.map(C::from_expr).collect::<AstResult<Vec<_>>>()?;
|
let children = iter.map(C::from_ast).collect::<AstResult<Vec<_>>>()?;
|
||||||
Element { span, name, attrs, children }
|
Element { span, name, attrs, children }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
let parser = parser::ExprParser::new();
|
let parser = parser::AstParser::new();
|
||||||
insta::with_settings!({sort_maps => true}, {
|
insta::with_settings!({sort_maps => true}, {
|
||||||
let lexer = lexer::Lexer::new("(box :bar 12 :baz \"hi\" foo (bar))");
|
let lexer = lexer::Lexer::new("(box :bar 12 :baz \"hi\" foo (bar))");
|
||||||
insta::assert_debug_snapshot!(
|
insta::assert_debug_snapshot!(
|
||||||
Element::<Expr, Expr>::from_expr(parser.parse(0, lexer).unwrap()).unwrap()
|
Element::<Ast, Ast>::from_ast(parser.parse(0, lexer).unwrap()).unwrap()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
10
src/error.rs
10
src/error.rs
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
expr::{Expr, ExprType, Span},
|
ast::{Ast, AstType, Span},
|
||||||
lexer,
|
lexer,
|
||||||
};
|
};
|
||||||
use codespan_reporting::{diagnostic, files};
|
use codespan_reporting::{diagnostic, files};
|
||||||
|
@ -12,9 +12,9 @@ pub enum AstError {
|
||||||
#[error("Definition invalid")]
|
#[error("Definition invalid")]
|
||||||
InvalidDefinition(Option<Span>),
|
InvalidDefinition(Option<Span>),
|
||||||
#[error("Expected a {1}, but got nothing")]
|
#[error("Expected a {1}, but got nothing")]
|
||||||
MissingNode(Option<Span>, ExprType),
|
MissingNode(Option<Span>, AstType),
|
||||||
#[error("Wrong type of expression: Expected {1} but got {2}")]
|
#[error("Wrong type of expression: Expected {1} but got {2}")]
|
||||||
WrongExprType(Option<Span>, ExprType, ExprType),
|
WrongExprType(Option<Span>, AstType, AstType),
|
||||||
|
|
||||||
#[error("Parse error: {source}")]
|
#[error("Parse error: {source}")]
|
||||||
ParseError { file_id: Option<usize>, source: lalrpop_util::ParseError<usize, lexer::Token, lexer::LexicalError> },
|
ParseError { file_id: Option<usize>, source: lalrpop_util::ParseError<usize, lexer::Token, lexer::LexicalError> },
|
||||||
|
@ -68,10 +68,10 @@ pub fn spanned(span: Span, err: impl Into<AstError>) -> AstError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait OptionAstErrorExt<T> {
|
pub trait OptionAstErrorExt<T> {
|
||||||
fn or_missing(self, t: ExprType) -> Result<T, AstError>;
|
fn or_missing(self, t: AstType) -> Result<T, AstError>;
|
||||||
}
|
}
|
||||||
impl<T> OptionAstErrorExt<T> for Option<T> {
|
impl<T> OptionAstErrorExt<T> for Option<T> {
|
||||||
fn or_missing(self, t: ExprType) -> Result<T, AstError> {
|
fn or_missing(self, t: AstType) -> Result<T, AstError> {
|
||||||
self.ok_or(AstError::MissingNode(None, t))
|
self.ok_or(AstError::MissingNode(None, t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -2,12 +2,12 @@
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
|
|
||||||
|
pub mod ast;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod expr;
|
|
||||||
mod lexer;
|
mod lexer;
|
||||||
|
use ast::Ast;
|
||||||
use error::{AstError, AstResult};
|
use error::{AstError, AstResult};
|
||||||
use expr::Expr;
|
|
||||||
|
|
||||||
use std::{fmt::Display, ops::Deref};
|
use std::{fmt::Display, ops::Deref};
|
||||||
|
|
||||||
|
@ -17,15 +17,15 @@ use lalrpop_util::lalrpop_mod;
|
||||||
|
|
||||||
lalrpop_mod!(pub parser);
|
lalrpop_mod!(pub parser);
|
||||||
|
|
||||||
pub fn parse_string(file_id: usize, s: &str) -> AstResult<Expr> {
|
pub fn parse_string(file_id: usize, s: &str) -> AstResult<Ast> {
|
||||||
let lexer = lexer::Lexer::new(s);
|
let lexer = lexer::Lexer::new(s);
|
||||||
let parser = parser::ExprParser::new();
|
let parser = parser::AstParser::new();
|
||||||
Ok(parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))?)
|
Ok(parser.parse(file_id, lexer).map_err(|e| AstError::from_parse_error(file_id, e))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! test_parser {
|
macro_rules! test_parser {
|
||||||
($($text:literal),*) => {{
|
($($text:literal),*) => {{
|
||||||
let p = crate::parser::ExprParser::new();
|
let p = crate::parser::AstParser::new();
|
||||||
use crate::lexer::Lexer;
|
use crate::lexer::Lexer;
|
||||||
|
|
||||||
::insta::with_settings!({sort_maps => true}, {
|
::insta::with_settings!({sort_maps => true}, {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use crate::lexer::{Token, LexicalError};
|
use crate::lexer::{Token, LexicalError};
|
||||||
use crate::expr::{Expr, Span};
|
use crate::ast::{Ast, Span};
|
||||||
|
|
||||||
grammar(file_id: usize);
|
grammar(file_id: usize);
|
||||||
|
|
||||||
|
@ -22,16 +22,16 @@ extern {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub Expr: Expr = {
|
pub Ast: Ast = {
|
||||||
<l:@L> "(" <elems:(<Expr>)+> ")" <r:@R> => Expr::List(Span(l, r, file_id), elems),
|
<l:@L> "(" <elems:(<Ast>)+> ")" <r:@R> => Ast::List(Span(l, r, file_id), elems),
|
||||||
<x:Keyword> => x,
|
<x:Keyword> => x,
|
||||||
<x:Symbol> => x,
|
<x:Symbol> => x,
|
||||||
<l:@L> <x:Value> <r:@R> => Expr::Value(Span(l, r, file_id), x),
|
<l:@L> <x:Value> <r:@R> => Ast::Value(Span(l, r, file_id), x),
|
||||||
<l:@L> "comment" <r:@R> => Expr::Comment(Span(l, r, file_id)),
|
<l:@L> "comment" <r:@R> => Ast::Comment(Span(l, r, file_id)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Keyword: Expr = <l:@L> <x:"keyword"> <r:@R> => Expr::Keyword(Span(l, r, file_id), x.to_string());
|
Keyword: Ast = <l:@L> <x:"keyword"> <r:@R> => Ast::Keyword(Span(l, r, file_id), x.to_string());
|
||||||
Symbol: Expr = <l:@L> <x:"symbol"> <r:@R> => Expr::Symbol(Span(l, r, file_id), x.to_string());
|
Symbol: Ast = <l:@L> <x:"symbol"> <r:@R> => Ast::Symbol(Span(l, r, file_id), x.to_string());
|
||||||
|
|
||||||
Value: String = {
|
Value: String = {
|
||||||
<StrLit> => <>,
|
<StrLit> => <>,
|
||||||
|
|
Loading…
Add table
Reference in a new issue