seam

Symbolic-Expressions As Markup.
git clone git://git.knutsen.co/seam
Log | Files | Refs | README | LICENSE

commit 67fdd306c6945fd9e85d51ca251717db495462d8
parent 623896e7320d121df90ead595159b47e2b2a0a06
Author: knutsen <samuel@knutsen.co>
Date:   Tue,  6 Apr 2021 01:43:45 +0100

Fix way of searching nodes,

Diffstat:
MCargo.toml | 2+-
Msrc/assemble/html.rs | 11++++++-----
Msrc/lib.rs | 2+-
Msrc/parse/parser.rs | 34++++++++++++++++++----------------
4 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml @@ -4,7 +4,7 @@ description = "Symbolic Expressions As Markup." keywords = ["markup", "lisp", "macro", "symbolic-expression", "sexp"] license-file = "LICENSE" homepage = "https://git.knutsen.co/seam" -version = "0.1.7" +version = "0.1.8" authors = ["Demonstrandum <moi@knutsen.co>"] edition = "2018" diff --git a/src/assemble/html.rs b/src/assemble/html.rs @@ -2,7 +2,7 @@ use super::{GenerationError, MarkupDisplay, Formatter}; use super::css::CSSFormatter; -use crate::parse::parser::{ParseNode, ParseTree, SearchTree}; +use crate::parse::parser::{ParseNode, ParseTree, SearchTree, SearchType}; #[derive(Debug, Clone)] pub struct HTMLFormatter { @@ -33,18 +33,19 @@ impl MarkupDisplay for HTMLFormatter { // Check if top-level <!DOCTYPE html> exists. let doctype_tag - = self.tree.search_node(ParseNode::List, "!DOCTYPE", true, 1); + = self.tree.search_node(SearchType::ListHead, "!doctype", true, 1); // Check if top-level <html></html> root object exists. let html_tag - = self.tree.search_node(ParseNode::List, "html", true, 1); + = self.tree.search_node(SearchType::ListHead, "html", true, 1); // Check if <head></head> tag object exists. let head_tag - = self.tree.search_node(ParseNode::List, "head", true, 2); + = self.tree.search_node(SearchType::ListHead, "head", true, 2); // Check if <body></body> tag object exists. let body_tag - = self.tree.search_node(ParseNode::List, "body", true, 2); + = self.tree.search_node(SearchType::ListHead, "body", true, 2); if doctype_tag.is_none() { + eprintln!("no doctype found"); doc += "<!DOCTYPE html>\n"; if html_tag.is_none() { doc += "<html>\n"; diff --git a/src/lib.rs b/src/lib.rs @@ -10,7 +10,7 @@ use parse::{expander, parser, lexer}; use std::error::Error; use std::{fs, io, path::Path}; -pub const VERSION : (u8, u8, u8) = (0, 1, 7); +pub const VERSION : (u8, u8, u8) = (0, 1, 8); pub fn parse<P: AsRef<Path>>(string : String, source : Option<P>) -> Result<parser::ParseTree, Box<dyn Error>> { diff --git a/src/parse/parser.rs b/src/parse/parser.rs @@ -68,25 +68,27 @@ impl ParseNode { pub type ParseTree = Vec<ParseNode>; pub trait SearchTree { - type Constructor<T> = fn(T) -> ParseNode; /// Search the parse-tree for a specific node with a specific value. - /// if `kind == ParseNode::List`, then check if the list has - /// first value (head/caller) equal to `value`, etc. - fn search_node<T>(&self, kind : Self::Constructor<T>, - value : &str, - case_insensitive : bool, - level : usize) -> Option<ParseNode>; + fn search_node(&self, kind : SearchType, + value : &str, + case_insensitive : bool, + level : usize) -> Option<ParseNode>; +} + +#[derive(Clone, Copy, PartialEq)] +pub enum SearchType { + ListHead, ListMember, + Symbol, Number, String, + Attribute } impl SearchTree for ParseTree { - fn search_node<T>(&self, kind : Self::Constructor<T>, value : &str, - insensitive : bool, level: usize) -> Option<ParseNode> { + fn search_node(&self, kind : SearchType, value : &str, + insensitive : bool, level: usize) -> Option<ParseNode> { if level == 0 { return None; } - let fnptr = kind as usize; - let is_equal = |string: &str| if insensitive { string.to_lowercase() == value.to_lowercase() } else { @@ -96,7 +98,7 @@ impl SearchTree for ParseTree { for node in self { let found = match node { ParseNode::List(nodes) => { - if fnptr == ParseNode::List as usize { + if kind == SearchType::ListHead { if let Some(Some(caller)) = nodes.get(0).map(ParseNode::atomic) { if is_equal(&caller.value) { return Some(node.clone()); @@ -106,28 +108,28 @@ impl SearchTree for ParseTree { nodes.search_node(kind, value, insensitive, level - 1) }, ParseNode::Symbol(name) => { - if fnptr == ParseNode::Symbol as usize && is_equal(&name.value) { + if kind == SearchType::Symbol && is_equal(&name.value) { Some(node.clone()) } else { None } }, ParseNode::String(name) => { - if fnptr == ParseNode::String as usize && is_equal(&name.value) { + if kind == SearchType::String && is_equal(&name.value) { Some(node.clone()) } else { None } }, ParseNode::Number(name) => { - if fnptr == ParseNode::Number as usize && is_equal(&name.value) { + if kind == SearchType::Number && is_equal(&name.value) { Some(node.clone()) } else { None } }, ParseNode::Attribute(attr) => { - if kind as usize == ParseNode::Attribute as usize { + if kind == SearchType::Attribute { if is_equal(&attr.keyword) { return Some(node.clone()); }