95 lines
2.5 KiB
Rust
95 lines
2.5 KiB
Rust
#![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::<String>(),
|
|
);
|
|
|
|
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<T>(mut v: Vec<T>, e: T) -> Vec<T> {
|
|
v.push(e);
|
|
v
|
|
}
|
|
|
|
pub fn cons_ll<T>(mut v: LinkedList<T>, e: T) -> LinkedList<T> {
|
|
v.push_back(e);
|
|
v
|
|
}
|
|
|
|
pub fn join<T>(mut a: LinkedList<T>, mut b: LinkedList<T>) -> LinkedList<T> {
|
|
a.append(&mut b);
|
|
a
|
|
}
|
|
|
|
pub fn join_vec<T>(mut a: Vec<T>, mut b: Vec<T>) -> Vec<T> {
|
|
a.append(&mut b);
|
|
a
|
|
}
|