Skip to content

Commit

Permalink
Add type checker
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamRagstad committed Nov 3, 2024
1 parent 0d70876 commit 087dd42
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 22 deletions.
38 changes: 24 additions & 14 deletions src/commands/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,40 @@ use colorful::Colorful;
use lento_core::{
interpreter::{environment::global_env, interpreter::interpret_ast, value::Value},
parser::parser::from_string,
type_checker::types::GetType,
type_checker::{checker::TypeChecker, types::GetType},
};

use crate::error::print_error;
use crate::error::{print_error, print_type_error};

pub fn handle_command_eval(args: &ArgMatches, _arg_parser: &mut Command) {
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) => match interpret_ast(&ast, &mut env) {
Ok(value) => {
if value != Value::Unit {
println!("{}", value);
println!(
"{}{}{}",
"(type: ".dark_gray(),
value.get_type().to_string().dark_gray(),
")".dark_gray()
);
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()
);
}
}
Err(err) => print_error(err.message),
}
Err(err) => print_error(err.message),
},
}
Err(err) => print_error(err.message),
}
}
18 changes: 13 additions & 5 deletions src/commands/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ use std::{path::Path, process::exit};
use clap::{parser::ValuesRef, Command};
use colorful::Colorful;

use lento_core::interpreter::interpreter::interpret_module;
use lento_core::interpreter::value::Value;
use lento_core::parser::ast::Module;
use lento_core::parser::parser::parse_path_all;
use lento_core::{
interpreter::{
environment::global_env,
error::{runtime_error, RuntimeError},
interpreter::interpret_module,
value::Value,
},
parser::{ast::Module, parser::parse_path_all},
type_checker::checker::TypeChecker,
util::failable::Failable,
};

Expand Down Expand Up @@ -84,13 +84,21 @@ fn parse_files<'a>(files: &Vec<&'a Path>) -> Vec<(&'a Path, Module)> {
fn interpret_parse_results(parse_results: Vec<(&Path, Module)>) -> Failable<Vec<RuntimeError>> {
// Interpret all files in order. Unwrap is safe because we already checked for errors in the parse_results function
let mut errors: Vec<RuntimeError> = vec![];
let mut checker = TypeChecker::default();
for (file_path, module) in parse_results {
println!(
"{} '{}'...",
"Interpreting".light_cyan(),
file_path.display()
);
match interpret_module(&module, &mut global_env()) {
let checked_module = match checker.check_module(&module) {
Ok(module) => module,
Err(err) => {
errors.push(runtime_error(err.message));
continue;
}
};
match interpret_module(&checked_module, &mut global_env()) {
Ok(val) => {
println!("{} executed program!", "Successfully".light_green());
if val != Value::Unit {
Expand Down
14 changes: 11 additions & 3 deletions src/commands/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use colorful::Colorful;
use lento_core::{
interpreter::{environment::global_env, interpreter::interpret_ast, value::Value},
parser::parser,
type_checker::types::GetType,
type_checker::{checker::type_checker_with_stdlib, types::GetType},
};

use crate::{
error::{print_parse_error, print_runtime_error},
error::{print_parse_error, print_runtime_error, print_type_error},
CLI_VERSION,
};

Expand Down Expand Up @@ -41,14 +41,22 @@ pub fn handle_command_repl(args: &ArgMatches, _arg_parser: &mut Command) {
// this prevents another prompt appearing after the
// user has entered an expression.
parser.lexer().set_read_only_once(true);
let mut checker = type_checker_with_stdlib();
let mut env = global_env();
loop {
print!("> ");
std::io::stdout().flush().unwrap();
match parser.parse_all() {
Ok(asts) => {
'exprs: for (i, ast) in asts.iter().enumerate() {
match interpret_ast(ast, &mut env) {
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());
Expand Down
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub fn print_runtime_error(msg: String) {
println!("{}: {}\n", "runtime error".light_red(), msg);
}

pub fn print_type_error(msg: String) {
println!("{}: {}\n", "type error".light_red(), msg);
}

pub fn print_error(msg: String) {
println!("{}: {}\n", "error".light_red(), msg);
}
Expand Down

0 comments on commit 087dd42

Please sign in to comment.