commit 67fdd306c6945fd9e85d51ca251717db495462d8
parent 623896e7320d121df90ead595159b47e2b2a0a06
Author: knutsen <samuel@knutsen.co>
Date: Tue, 6 Apr 2021 01:43:45 +0100
Fix way of searching nodes,
Diffstat:
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());
}