use crate::{lexer::Token, parser::AST, push_output};
pub fn debug_token_array(tokens: Vec<Token>) -> String {
let mut output = "".to_string();
for token in tokens {
output += &token.token_type.to_string();
output += "\n";
}
output[..output.len()-1].to_string()
}
pub fn debug_ast(ast: AST, level: usize) -> String {
use crate::parser::ASTType::*;
use crate::parser::BinOp::*;
use crate::parser::UnOp::*;
use crate::parser::Lit::*;
let mut output = "".to_string();
match ast.ast_type {
Program(asts) => {
output += &"| ".repeat(level);
output += "Program";
for ast in asts {
output += "\n";
output += &debug_ast(ast, level+1);
}
}
Function(name, args, block) => {
output += &"| ".repeat(level);
output += "Function";
output += &(" ".to_string() + &name.name);
for arg in args {
output += &(" ".to_string() + &arg.name);
}
output += "\n";
output += &debug_ast(*block, level+1);
}
Return(expr) => {
output += &"| ".repeat(level);
output += "Return";
if let Some(expr) = *expr {
output += "\n";
output += &debug_ast(expr, level+1);
}
}
Loop(block) => {
output += &"| ".repeat(level);
output += "Loop";
output += "\n";
output += &debug_ast(*block, level+1);
}
While(condition, block) => {
output += &"| ".repeat(level);
output += "While";
output += "\n";
output += &debug_ast(*condition, level+1);
output += "\n";
output += &debug_ast(*block, level+1);
}
For(expr1, expr2, expr3, block) => {
output += &"| ".repeat(level);
output += "For";
if let Some(expr1) = *expr1 {
output += "\n";
output += &debug_ast(expr1, level+1);
}
if let Some(expr2) = *expr2 {
output += "\n";
output += &debug_ast(expr2, level+1);
}
if let Some(expr3) = *expr3 {
output += "\n";
output += &debug_ast(expr3, level+1);
}
output += "\n";
output += &debug_ast(*block, level+1);
}
Break => { output += "Break\n"; }
Continue => { output += "Continue\n"; }
If(condition, block, else_expr) => {
output += &"| ".repeat(level);
output += "If\n";
output += &debug_ast(*condition, level+1);
output += "\n";
output += &debug_ast(*block, level+1);
if let Some(else_expr) = *else_expr {
output += "\n";
output += &"| ".repeat(level);
output += "Else";
output += "\n";
output += &debug_ast(else_expr, level+1);
}
}
Block(asts) => {
output += &"| ".repeat(level);
output += "Block";
for ast in asts {
output += "\n";
output += &debug_ast(ast, level+1);
}
}
Decl(name, expr) => {
output += &"| ".repeat(level);
output += "Decl ";
output += &name.name;
output += "\n";
output += &debug_ast(*expr, level+1);
}
Assign(name, expr) => {
output += &"| ".repeat(level);
output += "Assign ";
output += &name.name;
output += "\n";
output += &debug_ast(*expr, level+1);
}
Ternary(condition, true_expr, false_expr) => {
output += &"| ".repeat(level);
output += "Ternary\n";
output += &debug_ast(*condition, level+1);
output += "\n";
output += &debug_ast(*true_expr, level+1);
output += "\n";
output += &debug_ast(*false_expr, level+1);
}
Subscript(array, index) => {
output += &"| ".repeat(level);
output += "Subscript\n";
output += &debug_ast(*array, level+1);
output += "\n";
output += &debug_ast(*index, level+1);
}
Binary(left, oper, right) => {
output += &"| ".repeat(level);
output += "Binary ";
push_output!(oper, output,
Add, Sub, Mul, Div, Mod, BitAnd, BitXor, BitOr,
Eq, Ne, Gr, Ge, Ls, Le, Or, And);
output += "\n";
output += &debug_ast(*left, level+1);
output += "\n";
output += &debug_ast(*right, level+1);
}
Unary(oper, right) => {
output += &"| ".repeat(level);
output += "Unary ";
push_output!(oper, output,
Not, Neg);
output += "\n";
output += &debug_ast(*right, level+1);
}
Lit(lit) => {
output += &"| ".repeat(level);
output += "Lit ";
match lit {
Ident(name) => {
output += &name;
}
Str(value) => {
output += &value;
}
Num(value) => {
output += &value.to_string();
}
Bool(value) => {
output += &value.to_string();
}
Array(value) => {
for value in value {
output += "\n";
output += &debug_ast(value, level+1);
}
}
}
}
Call(name, args) => {
output += &"| ".repeat(level);
output += "Call ";
output += &name.name;
for arg in args {
output += "\n";
output += &debug_ast(arg, level+1);
}
}
Member(left, right) => {
output += &"| ".repeat(level);
output += "Member\n";
output += &debug_ast(*left, level+1);
output += "\n";
output += &debug_ast(*right, level+1);
}
}
output
}