first pass AST complete!

stable
Ivory 2023-06-04 16:00:27 -04:00
parent e24bbe91ca
commit 9e142003f1
5 changed files with 161 additions and 109 deletions

View File

@ -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 "<program>";
}
}
#[derive(Debug)]
struct Program<'a> {
pub uses: Vec<UseDeclaration<'a>>
}
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() == "<program$1>" {
self.digest_1(tree);
return;
} else if tree.lhs.to_string() == "<unit>" {
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() == "<program$1>" {
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;

View File

@ -1 +1,2 @@
use vlib::Console
use vlib::Map

View File

@ -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<UseDeclaration>
}
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 == "<use_clause>" {
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()
}
}
}

View File

@ -0,0 +1,2 @@
pub mod base;
mod use_clause;

View File

@ -0,0 +1,89 @@
use bnf::ParseTree;
use bnf::ParseTreeNode::{Nonterminal, Terminal};
#[derive(Debug, Clone)]
pub struct UseDeclaration {
namespace: Vec<String>
}
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 == "<identifier>" {
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 == "<LETTER>" {
return letter(tree);
}
assert!(term == "<identifier>");
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 == "<LETTER>");
for term in tree.rhs_iter() {
match term {
Terminal(str) => {
return String::from(str.to_owned());
},
Nonterminal(_tree) => {}
}
}
return String::from("");
}