Add a flag to show the AST/Token list

pull/4/head
Lily Aurora N. 3 weeks ago
parent 77ae300c2c
commit 6d894b2038
Signed by untrusted user: MinekPo1
GPG Key ID: DD811C9D0D40B8CE

@ -2,15 +2,23 @@ use compiler::{backend::spirv_meta, meta_compile};
use error::print_error;
use std::{env, fs, path::PathBuf};
use parser::parse_string;
use parser::{parse_string, tokenize, Token};
pub mod compiler;
mod error;
pub mod parser;
#[derive(Debug, Default, PartialEq)]
enum Trace {
Tokens,
AST,
#[default] Normal
}
#[derive(Debug, Default)]
struct CompilerArgs {
input: Option<PathBuf>,
output: Option<PathBuf>,
trace: Trace,
print_help: bool,
print_version: bool,
}
@ -43,6 +51,17 @@ fn main() {
return;
}
};
if args.trace == Trace::Tokens {
let tokens = tokenize(&src);
for tok in tokens {
match tok.item {
Token::LeftParen => println!("{:>3}:{:<3} LeftParen",tok.location.line_start(), tok.location.col_start()),
Token::RightParen => println!("{:>3}:{:<3} RightParen",tok.location.line_start(), tok.location.col_start()),
Token::Symbol( val ) => println!("{:>3}:{:<3} Symbol `{}`",tok.location.line_start(), tok.location.col_start(), val)
}
}
return;
}
let ast = match parse_string(&src) {
Ok(i) => i,
@ -51,6 +70,11 @@ fn main() {
return;
}
};
if args.trace == Trace::AST {
ast.pretty_print(None,None);
return;
}
let module = match meta_compile(ast) {
Ok(m) => m,
@ -111,6 +135,36 @@ fn parse_args() -> CompilerArgs {
return parsed_args;
}
}
"trace" => {
if parsed_args.trace == Trace::Normal {
let Some(output) = args.next() else {
parsed_args.print_help = true;
eprintln!("trace needs a file");
eprintln!();
return parsed_args;
};
match output.as_str() {
"ast" | "AST" | "Ast" => {
parsed_args.trace = Trace::AST;
}
"token" | "tokens" => {
parsed_args.trace = Trace::Tokens;
}
a => {
eprintln!("unknown trace value {a}");
eprintln!();
parsed_args.print_help = true;
return parsed_args;
}
}
} else {
eprintln!("trace can be passed only once");
eprintln!();
parsed_args.print_help = true;
return parsed_args;
}
}
a => {
eprintln!("unknown arg --{a}");
eprintln!();

@ -155,6 +155,31 @@ impl Ast {
Ast::Root(_) => &Location::All,
}
}
pub fn pretty_print(&self, prefix: Option<&String>, body_prefix: Option<&String>) {
let empty_string_to_make_rust_happy = &String::from("");
let prefix_ = prefix.unwrap_or(&empty_string_to_make_rust_happy);
let body_prefix_ = body_prefix.unwrap_or(&empty_string_to_make_rust_happy);
match self {
Ast::Symbol(Localised { item, location }) => {
println!("{} Symbol `{}` ({}:{})", prefix_, item, location.line_start(), location.col_start());
},
Ast::List(Localised { item, location }) => {
println!("{} List ({}:{})", prefix_, location.line_start(), location.col_start());
for i in 0..item.len()-2 {
item[i].pretty_print(Some(&(body_prefix_.to_owned() + &String::from(" ├─ "))), Some(&(body_prefix_.to_owned() + &String::from(" │ "))));
}
item[item.len()-1].pretty_print(Some(&(body_prefix_.to_owned() + &String::from(" ╰─ "))), Some(&(body_prefix_.to_owned() + &String::from(" "))));
},
Ast::Root( items ) => {
println!("{} Root", prefix_);
for i in 0..items.len()-2 {
items[i].pretty_print(Some(&(body_prefix_.to_owned() + &String::from(" ├─ "))), Some(&(body_prefix_.to_owned() + &String::from(" │ "))));
}
items[items.len()-1].pretty_print(Some(&(body_prefix_.to_owned() + &String::from(" ╰─ "))), Some(&(body_prefix_.to_owned() + &String::from(" "))));
},
}
}
}
pub fn tokenize(input: &str) -> Vec<Localised<Token>> {

Loading…
Cancel
Save