Skip to content

Commit

Permalink
Extract eval all
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamRagstad committed Nov 7, 2024
1 parent 2fb581e commit 0a56486
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 66 deletions.
82 changes: 58 additions & 24 deletions src/commands/eval.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,80 @@
use std::io::Read;

use clap::{ArgMatches, Command};
use colorful::Colorful;
use lento_core::{
interpreter::{environment::global_env, interpreter::interpret_ast, value::Value},
parser::parser::from_string,
interpreter::{
environment::{global_env, Environment},
interpreter::interpret_ast,
value::Value,
},
parser::parser::{from_string, Parser},
type_checker::{checker::TypeChecker, types::GetType},
};

use crate::error::{print_error, print_type_error};
use crate::{
error::{print_parse_error, print_runtime_error, print_type_error},
logger::init_logger_str,
};

pub fn handle_command_eval(args: &ArgMatches, _arg_parser: &mut Command) {
// Get the flag for REPL
if let Some(debug_level) = args.get_one::<String>("debug") {
init_logger_str(debug_level);
}
let expr = args.get_one::<String>("expr").unwrap().to_owned();

let mut parser = from_string(expr);
let mut checker = TypeChecker::default();
let mut env = global_env();
match parser.parse_one() {
Ok(ast) => {
let checked_ast = match checker.check_expr(&ast) {
Ok(ast) => ast,
Err(err) => {
print_type_error(err.message);
return;
}
};
match interpret_ast(&checked_ast, &mut env) {
Ok(value) => {
if value != Value::Unit {
println!("{}", value);
println!(
"{}{}{}",
"(type: ".dark_gray(),
value.get_type().to_string().dark_gray(),
")".dark_gray()
);
eval_all(&mut parser, &mut checker, &mut env, false, false);
}

pub fn eval_all<R: Read>(
parser: &mut Parser<R>,
checker: &mut TypeChecker,
env: &mut Environment,
print_types: bool,
colors: bool,
) {
match parser.parse_all() {
Ok(asts) => {
'exprs: for (i, ast) in asts.iter().enumerate() {
let checked_ast = match checker.check_expr(ast) {
Ok(ast) => ast,
Err(err) => {
print_type_error(err.message);
break 'exprs; // Stop on error
}
};
match interpret_ast(&checked_ast, env) {
Ok(value) => {
if i == asts.len() - 1 && value != Value::Unit {
if colors {
println!("{}", value.pretty_print_color());
} else {
println!("{}", value.pretty_print());
}
if print_types {
if colors {
println!(
"{} {}",
"type:".dark_gray(),
value.get_type().pretty_print_color()
);
} else {
println!("{} {}", "type:".dark_gray(), value.get_type());
}
}
}
}
Err(err) => {
print_runtime_error(err.message);
break 'exprs; // Stop on error
}
}
Err(err) => print_error(err.message),
}
}
Err(err) => print_error(err.message),
Err(err) => print_parse_error(err.message),
}
}
47 changes: 5 additions & 42 deletions src/commands/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@ use std::io::{Read, Write};
use clap::{ArgMatches, Command};
use colorful::Colorful;
use lento_core::{
interpreter::{environment::global_env, interpreter::interpret_ast, value::Value},
parser::parser,
stdlib::init::stdlib,
type_checker::{checker::TypeChecker, types::GetType},
interpreter::environment::global_env, parser::parser, stdlib::init::stdlib,
type_checker::checker::TypeChecker,
};

use crate::{
error::{print_parse_error, print_runtime_error, print_type_error},
logger::init_logger_str,
CLI_VERSION,
};
use crate::{commands::eval::eval_all, logger::init_logger_str, CLI_VERSION};

pub fn handle_command_repl(args: &ArgMatches, _arg_parser: &mut Command) {
// Set the Ctrl-C handler to exit the program
ctrlc::set_handler(|| std::process::exit(0)).expect("Error setting Ctrl-C handler");

// Get the flag for REPL
// Get flags
let print_types = args.get_flag("types");
if let Some(debug_level) = args.get_one::<String>("debug") {
init_logger_str(debug_level);
Expand Down Expand Up @@ -56,38 +50,7 @@ pub fn handle_command_repl(args: &ArgMatches, _arg_parser: &mut Command) {
loop {
print!("> ");
std::io::stdout().flush().unwrap();
match parser.parse_all() {
Ok(asts) => {
'exprs: for (i, ast) in asts.iter().enumerate() {
let checked_ast = match checker.check_expr(ast) {
Ok(ast) => ast,
Err(err) => {
print_type_error(err.message);
break 'exprs; // Stop on error
}
};
match interpret_ast(&checked_ast, &mut env) {
Ok(value) => {
if i == asts.len() - 1 && value != Value::Unit {
println!("{}", value.pretty_print_color());
if print_types {
println!(
"{} {}",
"type:".dark_gray(),
value.get_type().pretty_print_color()
);
}
}
}
Err(err) => {
print_runtime_error(err.message);
break 'exprs; // Stop on error
}
}
}
}
Err(err) => print_parse_error(err.message),
}
eval_all(&mut parser, &mut checker, &mut env, print_types, true);
// Instead of creating a new parser, lexer, and reader, we simply reset them to save memory
parser.lexer().reset();
}
Expand Down

0 comments on commit 0a56486

Please sign in to comment.