#![feature(try_trait_v2)] use std::{fs::File, io::Read, collections::LinkedList, process::exit}; use logos::Logos; use parser::{program::Program, Parsable, WrappedLexer}; use crate::ir::evaluation::{EvaluateError, display_program}; mod token; mod parser; mod ir; fn main() -> std::io::Result<()> { let mut input_file = std::io::stdin(); let mut input = String::with_capacity(4096); input_file.read_to_string(&mut input)?; let lexer = token::Token::lexer(&input); let mut wrapped_lexer = WrappedLexer::new(lexer); let program = match Program::parse(&mut wrapped_lexer) { Err(e) => { let location = e.location; eprintln!("Parse error at {location:?}!"); eprintln!("Expected one of:"); for token in e.expected { eprintln!(" - {token:?}"); } exit(1); } Ok(p) => p }; println!("Parse successful!!"); for decl in &program.0 { println!("{decl:?}\n"); } println!("Building IR..."); match program.gen_ir() { Ok(program) => { println!( "IR built successfully!\n{}", program.iter() .map(|decl| format!("\n\n{decl}\n\n")) .collect::(), ); match display_program(program) { Ok(value) => println!("Evaluated successfully! Got:\n{value}"), Err(EvaluateError::UndefinedValue(v)) => println!("Hit an error: {v} is undefined"), Err(EvaluateError::EvaluatingZeroLengthExpr) => println!("Hit an error: Tried to evaluate a series of zero instructions"), Err(EvaluateError::ArgumentCountMismatch(op, real, ex)) => println!("Problem while evaluating operation {op:?}: expected {ex} arguments, got {real}"), Err(EvaluateError::FunctionArgumentCountMismatch(real, ex)) => println!("Problem while evaluating a function: expected {ex} arguments, got {real}"), Err(EvaluateError::TypeMismatch(a, b)) => println!("Type mismatch between {a:?} and {b:?}!"), Err(EvaluateError::NoMain) => println!("Huh, there's no main method"), Err(EvaluateError::MainHasArgs) => println!("Your main method has args, but that's not allowed"), Err(EvaluateError::IncompleteConditional) => println!("Uh oh, a conditional somewhere isn't complete!"), } } Err(e) => println!("Oh noes! {e:?}"), } Ok(()) } pub fn cons(mut v: Vec, e: T) -> Vec { v.push(e); v } pub fn cons_ll(mut v: LinkedList, e: T) -> LinkedList { v.push_back(e); v } pub fn join(mut a: LinkedList, mut b: LinkedList) -> LinkedList { a.append(&mut b); a } pub fn join_vec(mut a: Vec, mut b: Vec) -> Vec { a.append(&mut b); a }