diff --git a/src/main.rs b/src/main.rs index cf6e600..6ddbd4b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,16 @@ +mod transformers; + +use std::borrow::Borrow; use bnf::{Grammar, ParseTree}; -use bnf::ParseTreeNode::{Nonterminal, Terminal}; +use crate::transformers::base::Program; -const IGNORE: [&'static str; 3] = [ - "", - "", - "", -]; + +// const IGNORE: [&'static str; 3] = [ +// "", +// "", +// "", +// ]; fn main() { @@ -30,115 +34,15 @@ fn main() { println!("Computed {} {} for program", trees.len(), pluralize(trees.len(), "tree", "trees")); - let tree = trees.get(0).expect("lmao how"); + let tree = trees[0].borrow(); let program = Program::new(tree); - println!("{:?}", program); + println!("{:#?}", program); println!("---"); } -trait TermDigestor { - fn get_term_str(&self) -> &'static str; -} - -impl TermDigestor for Program<'_> { - fn get_term_str(&self) -> &'static str { - return ""; - } -} - -#[derive(Debug)] -struct Program<'a> { - pub uses: Vec> -} - -impl Program<'_> { - pub fn new(tree: &ParseTree) -> Self { - let program = Program { - uses: vec![] - }; - program.digest(tree); - return program - } - - fn digest(&self, tree: &ParseTree) { - - if tree.lhs.to_string() == "" { - self.digest_1(tree); - return; - } else if tree.lhs.to_string() == "" { - self.digest_unit(tree); - return; - } - - println!("Program::digest {}", tree.lhs.to_string()); - // mut because that recursion could get nasty. - - for term in tree.rhs_iter() { - match term { - Terminal(str) => { - println!("{:?}", str); - }, - Nonterminal(tree) => { - if tree.lhs.to_string().starts_with("<_") { - continue; - } - if tree.lhs.to_string() == "" { - self.digest(tree); - } - } - } - } - } - - fn digest_1(&self, tree: &ParseTree) { - println!("Program::digest$1 {}", tree.lhs.to_string()); - - for term in tree.rhs_iter() { - match term { - Terminal(str) => { - println!("{:?}", str); - }, - Nonterminal(tree) => { - if tree.lhs.to_string().starts_with("<_") { - continue; - } - self.digest(tree); - } - } - } - } - - fn digest_unit(&self, tree: &ParseTree) { - println!("Program::digest_unit {}", tree.lhs.to_string()); - for term in tree.rhs_iter() { - match term { - Terminal(str) => { - println!("{:?}", str); - }, - Nonterminal(tree) => { - if tree.lhs.to_string().starts_with("<_") { - continue; - } - println!("{:?}", tree.lhs.to_string()) - } - } - } - } -} - -#[derive(Debug)] -struct UseDeclaration<'a> { - namespace: Vec<&'a str> -} - -fn create_namespace(tree: ParseTree) -> Vec<&str> { - println!("{}", tree.lhs); - return vec![""] -} - fn pluralize<'a>(n: usize, singular: &'a str, plural: &'a str) -> &'a str { if n == 1 { return singular; diff --git a/src/person.vm b/src/person.vm index d6e9cc4..ff9d4be 100644 --- a/src/person.vm +++ b/src/person.vm @@ -1 +1,2 @@ -use vlib::Console \ No newline at end of file +use vlib::Console +use vlib::Map \ No newline at end of file diff --git a/src/transformers/base.rs b/src/transformers/base.rs new file mode 100644 index 0000000..1d79766 --- /dev/null +++ b/src/transformers/base.rs @@ -0,0 +1,56 @@ + +use bnf::ParseTree; +use bnf::ParseTreeNode::{Nonterminal, Terminal}; +use super::use_clause::UseDeclaration; + +#[derive(Debug)] +pub struct Program { + pub uses: Vec +} + +impl Default for Program { + fn default() -> Self { + return Self { + uses: vec![] + }; + } +} + +impl Program { + pub fn new(tree: &ParseTree) -> Self { + return Self::digest(tree); + } + + fn digest(tree: &ParseTree) -> Program { + // println!("Program::digest {}", tree.lhs.to_string()); + + let term = tree.lhs.to_string(); + if term.starts_with("<_") { + return Program::default(); + } + if term == "" { + return Program { + uses: vec![UseDeclaration::new(tree)] + } + } + + let mut program: Program = Program::default(); + + for term in tree.rhs_iter() { + match term { + Terminal(_str) => { }, + Nonterminal(tree) => { + program = Self::merge(program, Self::digest(tree)); + } + } + } + + return program; + } + + fn merge<'a>(a: Program, b: Program) -> Program { + return Program { + uses: [a.uses, b.uses].concat() + } + } +} \ No newline at end of file diff --git a/src/transformers/mod.rs b/src/transformers/mod.rs new file mode 100644 index 0000000..c516f32 --- /dev/null +++ b/src/transformers/mod.rs @@ -0,0 +1,2 @@ +pub mod base; +mod use_clause; \ No newline at end of file diff --git a/src/transformers/use_clause.rs b/src/transformers/use_clause.rs new file mode 100644 index 0000000..581e5ba --- /dev/null +++ b/src/transformers/use_clause.rs @@ -0,0 +1,89 @@ +use bnf::ParseTree; +use bnf::ParseTreeNode::{Nonterminal, Terminal}; + +#[derive(Debug, Clone)] +pub struct UseDeclaration { + namespace: Vec +} + +impl Default for UseDeclaration { + fn default() -> Self { + return Self { namespace: vec![] }; + } +} + +impl UseDeclaration { + pub fn new(tree: &ParseTree) -> Self { + return UseDeclaration::digest(tree); + } + + fn digest(tree: &ParseTree) -> UseDeclaration { + // println!("UseDeclaration::digeset {}", tree.lhs); + + let term = tree.lhs.to_string(); + + let mut decl = UseDeclaration::default(); + if term == "" { + return UseDeclaration { + namespace: vec![identifier(tree)] + } + } + + for term in tree.rhs_iter() { + match term { + Terminal(_str) => { }, + Nonterminal(tree) => { + decl = Self::merge(decl, UseDeclaration::new(tree)) + } + } + } + + return decl; + } + + fn merge(a: UseDeclaration, b: UseDeclaration) -> UseDeclaration { + return UseDeclaration { + namespace: [a.namespace, b.namespace].concat() + } + } +} + + +fn identifier (tree: &ParseTree) -> String { + + let term = tree.lhs.to_string(); + if term == "" { + return letter(tree); + } + + assert!(term == ""); + + let mut build: String = "".to_owned(); + + for term in tree.rhs_iter() { + match term { + Terminal(str) => { + build += str; + }, + Nonterminal(tree) => { + build += identifier(tree).as_str(); + } + } + } + + return build; +} + +fn letter(tree: &ParseTree) -> String { + let term = tree.lhs.to_string(); + assert!(term == ""); + for term in tree.rhs_iter() { + match term { + Terminal(str) => { + return String::from(str.to_owned()); + }, + Nonterminal(_tree) => {} + } + } + return String::from(""); +} \ No newline at end of file