From b388d04bfaec53a8cc969f1832d832727f28d22e Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Sat, 5 Jun 2021 18:35:43 +0200 Subject: [PATCH] asdf --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/config.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lexer.rs | 85 --------------------------------------------------- src/main.rs | 18 +++++++++++ 5 files changed, 106 insertions(+), 85 deletions(-) create mode 100644 src/config.rs delete mode 100644 src/lexer.rs diff --git a/Cargo.lock b/Cargo.lock index 7806c6c..5d6f7ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,6 +9,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" + [[package]] name = "arrayref" version = "0.3.6" @@ -266,6 +272,7 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" name = "nomwut" version = "0.1.0" dependencies = [ + "anyhow", "itertools", "lalrpop", "lalrpop-util", diff --git a/Cargo.toml b/Cargo.toml index d938bfb..8824444 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ build = "build.rs" lalrpop-util = "0.19.5" regex = "1" itertools = "0.10" +anyhow = "1.0" [build-dependencies] lalrpop = "0.19.5" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..27f7293 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; + +use super::*; +use anyhow::*; + +type VarName = String; +type AttrValue = String; +type AttrName = String; + +pub enum AstError { + UnexpectedNode, + InvalidDefinition, + WrongExprType, +} + +impl From for AstError { + fn from(_: WrongExprType) -> Self { + AstError::WrongExprType + } +} + +pub trait FromExpr: Sized { + fn from_expr(e: Expr) -> Result; + fn from_sp(e: Sp) -> Result { + Self::from_expr(e.1) + } +} + +pub enum DefType { + Widget, +} + +impl FromExpr for DefType { + fn from_expr(e: Expr) -> Result { + if let Expr::Symbol(sym) = e { + match sym.as_str() { + "defwidget" => Ok(DefType::Widget), + _ => Err(AstError::InvalidDefinition), + } + } else { + Err(AstError::UnexpectedNode) + } + } +} + +pub struct Definitional { + def_type: DefType, + name: String, + attrs: HashMap>, + children: Vec, +} + +impl FromExpr for Definitional { + fn from_expr(e: Expr) -> Result { + if let Expr::List(list) = e { + let mut iter = list.into_iter(); + let def_type = DefType::from_sp(iter.next().unwrap())?; + let name = iter.next().unwrap().1.str()?; + let mut attrs = HashMap::new(); + while let Some(Sp(_, Expr::Keyword(x), _)) = iter.next() { + attrs.insert(x, iter.next().unwrap()); + } + + let children = iter.map(T::from_sp).collect::, AstError>>()?; + Ok(Definitional { + def_type, + name, + attrs, + children, + }) + } else { + Err(AstError::UnexpectedNode) + } + } +} + +pub struct WidgetDefinition { + name: String, + argnames: Vec, +} diff --git a/src/lexer.rs b/src/lexer.rs deleted file mode 100644 index 8deea40..0000000 --- a/src/lexer.rs +++ /dev/null @@ -1,85 +0,0 @@ -use std::str::CharIndices; - -pub type Spanned = Result<(Loc, Tok, Loc), Error>; - -#[derive(Copy, Clone, Debug)] -pub enum Tok { - LPren, - RPren, - Space, - Int(i32), -} - -#[derive(Debug, Copy, Clone)] -pub enum LexicalError { - InvalidDigit, - UnknownToken, -} - -impl std::fmt::Display for LexicalError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) - } -} - -pub struct Lexer<'input> { - chars: CharIndices<'input>, -} - -impl<'input> Lexer<'input> { - pub fn new(input: &'input str) -> Self { - Lexer { - chars: input.char_indices(), - } - } -} - -impl<'input> Iterator for Lexer<'input> { - type Item = Spanned; - - fn next(&mut self) -> Option { - let c = self.chars.next(); - match c { - Some((i, '(')) => Some(Ok((i, Tok::LPren, i + 1))), - Some((i, ')')) => Some(Ok((i, Tok::RPren, i + 1))), - Some((i, s)) if s.is_whitespace() => { - let mut last_space = i; - loop { - match self.chars.next() { - Some((i, next)) if next.is_whitespace() => { - last_space = i; - } - _ => { - break; - } - } - } - Some(Ok((i, Tok::Space, last_space + 1))) - } - Some((i, s)) if s.is_digit(10) || s == '-' => { - let mut end = i; - let mut digits = String::new(); - - loop { - match self.chars.next() { - Some((i, next)) if next.is_digit(10) => { - end = i; - digits.push(next); - } - _ => { - break; - } - } - } - - let num = match digits.parse::() { - Ok(num) => num, - Err(_err) => return Some(Err(LexicalError::InvalidDigit)), - }; - Some(Ok((i, Tok::Int(num), end + 1))) - } - Some((_, _)) => Some(Err(LexicalError::UnknownToken)), - None => None, - } - } -} diff --git a/src/main.rs b/src/main.rs index 99bbd5d..e9ea411 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,9 @@ #![allow(unused_imports)] +#![allow(unused)] + +mod config; + +use std::ops::Deref; use itertools::Itertools; @@ -17,6 +22,9 @@ impl std::fmt::Display for Sp { } } +#[derive(Debug, Clone, Copy)] +pub struct WrongExprType; + #[derive(Debug)] pub enum Expr { List(Vec>), @@ -28,6 +36,16 @@ pub enum Expr { Comment, } +impl Expr { + fn str(self) -> Result { + use Expr::*; + match self { + Str(x) => Ok(x), + _ => Err(WrongExprType), + } + } +} + impl std::fmt::Display for Expr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use Expr::*;