start adding more eww-specific stuff

This commit is contained in:
elkowar 2021-07-18 20:52:17 +02:00
parent bfb7c5a27b
commit 5f164650e9
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
8 changed files with 104 additions and 10 deletions

View file

@ -1,5 +1,4 @@
use eww_config::{
config::*,
format_diagnostic::ToDiagnostic,
parser::{ast::*, element::FromAst},
};

View file

@ -2,7 +2,7 @@ use eww_config::{
config::{widget_definition::WidgetDefinition, widget_use::WidgetUse, *},
error::AstError,
format_diagnostic::ToDiagnostic,
parser::{ast::*, element::FromAst},
parser::element::FromAst,
};
fn main() {

57
src/config/config.rs Normal file
View file

@ -0,0 +1,57 @@
use std::collections::HashMap;
use simplexpr::SimplExpr;
use super::{var::VarDefinition, widget_definition::WidgetDefinition, widget_use::WidgetUse};
use crate::{
error::{AstError, AstResult, OptionAstErrorExt},
parser::{
ast::{Ast, AstIterator, Span},
element::{Element, FromAst},
},
spanned,
value::{AttrName, VarName},
};
pub enum TopLevel {
VarDefinition(VarDefinition),
WidgetDefinition(WidgetDefinition),
}
impl FromAst for TopLevel {
fn from_ast(e: Ast) -> AstResult<Self> {
let span = e.span();
spanned!(e.span(), {
let list = e.as_list_ref()?;
match list.first().or_missing()?.as_symbol_ref()?.as_ref() {
"defwidget" => Self::WidgetDefinition(WidgetDefinition::from_ast(e)?),
"defvar" => Self::VarDefinition(VarDefinition::from_ast(e)?),
x => return Err(AstError::UnknownToplevel(Some(span), x.to_string())),
}
})
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Config {
widget_definitions: HashMap<String, WidgetDefinition>,
var_definitions: HashMap<VarName, VarDefinition>,
}
impl FromAst for Config {
fn from_ast(e: Ast) -> AstResult<Self> {
let list = e.as_list()?;
let mut config = Self { widget_definitions: HashMap::new(), var_definitions: HashMap::new() };
for element in list {
match TopLevel::from_ast(element)? {
TopLevel::VarDefinition(x) => {
config.var_definitions.insert(x.name.clone(), x);
}
TopLevel::WidgetDefinition(x) => {
config.widget_definitions.insert(x.name.clone(), x);
}
}
}
Ok(config)
}
}

View file

@ -1,3 +1,5 @@
mod config;
pub mod validate;
pub mod var;
pub mod widget_definition;
pub mod widget_use;

34
src/config/var.rs Normal file
View file

@ -0,0 +1,34 @@
use std::collections::HashMap;
use simplexpr::{dynval::DynVal, SimplExpr};
use crate::{
error::AstResult,
parser::{
ast::{Ast, AstIterator, Span},
element::{Element, FromAst},
},
spanned,
value::{AttrName, VarName},
};
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct VarDefinition {
pub name: VarName,
pub initial_value: DynVal,
pub span: Span,
}
impl FromAst for VarDefinition {
fn from_ast(e: Ast) -> AstResult<Self> {
let span = e.span();
spanned!(e.span(), {
let list = e.as_list()?;
let mut iter = AstIterator::new(list.into_iter());
let _ = iter.expect_symbol()?;
let (_, name) = iter.expect_symbol()?;
let (_, initial_value) = iter.expect_value()?;
Self { name: VarName(name), initial_value, span }
})
}
}

View file

@ -12,8 +12,8 @@ pub type AstResult<T> = Result<T, AstError>;
#[derive(Debug, Error)]
pub enum AstError {
#[error("Definition invalid")]
InvalidDefinition(Option<Span>),
#[error("Unknown toplevel declaration `{1}`")]
UnknownToplevel(Option<Span>, String),
#[error("Expected another element, but got nothing")]
MissingNode(Option<Span>),
#[error("Wrong type of expression: Expected {1} but got {2}")]
@ -31,7 +31,7 @@ pub enum AstError {
impl AstError {
pub fn get_span(&self) -> Option<Span> {
match self {
AstError::InvalidDefinition(span) => *span,
AstError::UnknownToplevel(span, _) => *span,
AstError::MissingNode(span) => *span,
AstError::WrongExprType(span, ..) => *span,
AstError::NotAValue(span, ..) => *span,
@ -67,7 +67,7 @@ fn get_parse_error_span(
pub fn spanned(span: Span, err: impl Into<AstError>) -> AstError {
use AstError::*;
match err.into() {
AstError::InvalidDefinition(None) => AstError::InvalidDefinition(Some(span)),
AstError::UnknownToplevel(None, x) => AstError::UnknownToplevel(Some(span), x),
AstError::MissingNode(None) => AstError::MissingNode(Some(span)),
AstError::WrongExprType(None, x, y) => AstError::WrongExprType(Some(span), x, y),
x => x,

View file

@ -52,8 +52,7 @@ impl ToDiagnostic for AstError {
}
} else if let Some(span) = self.get_span() {
match self {
AstError::InvalidDefinition(_) => todo!(),
AstError::UnknownToplevel(_, name) => gen_diagnostic!(format!("{}", self), span),
AstError::MissingNode(_) => gen_diagnostic! {
msg = "Expected another element",
label = span => "Expected another element here",

View file

@ -26,10 +26,13 @@ extern {
}
}
pub Toplevel: Vec<Ast> = {
<(<Ast>)*> => <>
}
pub Ast: Ast = {
<l:@L> "(" <elems:(<Ast>)+> ")" <r:@R> => Ast::List(Span(l, r, file_id), elems),
<l:@L> "[" <elems:(<Ast>)+> "]" <r:@R> => Ast::Array(Span(l, r, file_id), elems),
<l:@L> "(" <elems:(<Ast>)*> ")" <r:@R> => Ast::List(Span(l, r, file_id), elems),
<l:@L> "[" <elems:(<Ast>)*> "]" <r:@R> => Ast::Array(Span(l, r, file_id), elems),
<l:@L> <expr:SimplExpr> <r:@R> => Ast::SimplExpr(Span(l, r, file_id), expr),
<x:Keyword> => x,
<x:Symbol> => x,