first pass AST complete!
parent
e24bbe91ca
commit
9e142003f1
120
src/main.rs
120
src/main.rs
|
|
@ -1,12 +1,16 @@
|
||||||
|
mod transformers;
|
||||||
|
|
||||||
|
use std::borrow::Borrow;
|
||||||
|
|
||||||
use bnf::{Grammar, ParseTree};
|
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() {
|
fn main() {
|
||||||
|
|
||||||
|
|
@ -30,115 +34,15 @@ fn main() {
|
||||||
|
|
||||||
println!("Computed {} {} for program", trees.len(), pluralize(trees.len(), "tree", "trees"));
|
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);
|
let program = Program::new(tree);
|
||||||
|
|
||||||
println!("{:?}", program);
|
println!("{:#?}", program);
|
||||||
|
|
||||||
println!("---");
|
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 {
|
fn pluralize<'a>(n: usize, singular: &'a str, plural: &'a str) -> &'a str {
|
||||||
if n == 1 {
|
if n == 1 {
|
||||||
return singular;
|
return singular;
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
use vlib::Console
|
use vlib::Console
|
||||||
|
use vlib::Map
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod base;
|
||||||
|
mod use_clause;
|
||||||
|
|
@ -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("");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue