add compnentcall in define token; improve output format

This commit is contained in:
Keisuke Hirata 2024-12-09 04:41:27 +09:00
parent 8687b21821
commit ba3b003792
2 changed files with 65 additions and 9 deletions

View File

@ -4,10 +4,24 @@ pub mod om;
pub mod renderer; pub mod renderer;
fn main() { fn main() {
let mut input = String::new(); let mut input = String::new();
io::stdin().read_to_string(&mut input).expect("Failed to read from stdin"); io::stdin()
om::tokenizer::Tokenizer::new(input).for_each(|token| { .read_to_string(&mut input)
println!("\n{:?}", token); .expect("Failed to read from stdin");
}); let mut index = 0;
println!(); om::tokenizer::Tokenizer::new(input).for_each(|token| {
if let om::tokenizer::Token::NodeEnd = token {
index -= 1;
}
println!("{}{:?}", " ".repeat(index), token);
if let om::tokenizer::Token::Define {
name,
component,
behavior,
} = token
{
index += 1;
}
});
println!();
} }

View File

@ -49,7 +49,7 @@ impl Iterator for Tokenizer {
return Some(Token::EOF); return Some(Token::EOF);
} }
let c = self.consume_input(); let c = self.consume_input();
print!("{}", c); // print!("{}", c);
match self.state { match self.state {
State::Data => match c { State::Data => match c {
'(' => { '(' => {
@ -81,6 +81,16 @@ impl Iterator for Tokenizer {
self.state = State::AfterDefine; self.state = State::AfterDefine;
self.latest = Some(Token::Define { self.latest = Some(Token::Define {
name: self.buffer.clone(), name: self.buffer.clone(),
component: None,
behavior: Behavior::new(),
});
self.buffer.clear();
}
'<' => {
self.state = State::CompCall;
self.latest = Some(Token::Define {
name: self.buffer.clone(),
component: None,
behavior: Behavior::new(), behavior: Behavior::new(),
}); });
self.buffer.clear(); self.buffer.clear();
@ -93,6 +103,31 @@ impl Iterator for Tokenizer {
if self.is_eof() { if self.is_eof() {
return Some(Token::Define { return Some(Token::Define {
name: self.buffer.clone(), name: self.buffer.clone(),
component: None,
behavior: Behavior::new(),
});
}
}
},
State::CompCall => match c {
'>' => {
self.state = State::AfterDefine;
if let Some(t) = self.latest.as_mut() {
if let Token::Define { component, .. } = t {
*component = Some(self.buffer.clone());
}
}
self.buffer.clear();
}
_ => {
if !c.is_ascii_alphanumeric() {
panic!("Unexpected character: {}", c);
}
self.buffer.push(c);
if self.is_eof() {
return Some(Token::Define {
name: self.buffer.clone(),
component: None,
behavior: Behavior::new(), behavior: Behavior::new(),
}); });
} }
@ -172,7 +207,6 @@ impl Iterator for Tokenizer {
self.reconsume = true; self.reconsume = true;
self.state = State::Behavior; self.state = State::Behavior;
println!("BehaviorItem: {:?}", BehaviorItem::from(&self.buffer));
} }
} }
}, },
@ -186,6 +220,7 @@ enum State {
Data, Data,
NodeOpen, NodeOpen,
Define, Define,
CompCall,
AfterDefine, AfterDefine,
Behavior, Behavior,
BehaviorSeparator, BehaviorSeparator,
@ -193,7 +228,11 @@ enum State {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Token { pub enum Token {
Define { name: String, behavior: Behavior }, Define {
name: String,
component: Option<String>,
behavior: Behavior,
},
Character(char), Character(char),
NodeEnd, NodeEnd,
EOF, EOF,
@ -217,6 +256,7 @@ mod tests {
let expected = [ let expected = [
Token::Define { Token::Define {
name: "foo".to_string(), name: "foo".to_string(),
component: None,
behavior: Behavior { behavior: Behavior {
items: vec![BehaviorItem::KeyValue { items: vec![BehaviorItem::KeyValue {
prefix: Some("prefix".to_string()), prefix: Some("prefix".to_string()),
@ -239,6 +279,7 @@ mod tests {
let expected = [ let expected = [
Token::Define { Token::Define {
name: "foo".to_string(), name: "foo".to_string(),
component: None,
behavior: Behavior { behavior: Behavior {
items: vec![BehaviorItem::KeyValue { items: vec![BehaviorItem::KeyValue {
prefix: Some("prefix".to_string()), prefix: Some("prefix".to_string()),
@ -249,6 +290,7 @@ mod tests {
}, },
Token::Define { Token::Define {
name: "bar".to_string(), name: "bar".to_string(),
component: None,
behavior: Behavior { behavior: Behavior {
items: vec![BehaviorItem::KeyValue { items: vec![BehaviorItem::KeyValue {
prefix: Some("prefix".to_string()), prefix: Some("prefix".to_string()),