Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a31532c
Add tests
WilliamRagstad May 12, 2025
0944eb4
Add parser no parens and constructor args
WilliamRagstad May 12, 2025
f5a10db
Rewrite parser and the rest
WilliamRagstad May 13, 2025
ceea208
Refactor specialize
WilliamRagstad May 15, 2025
78f6843
Rename print_expr
WilliamRagstad May 15, 2025
cbc8465
Remove comma token, use op
WilliamRagstad May 15, 2025
828eddf
Utilize comma specialization in tuple
WilliamRagstad May 15, 2025
c155229
rename op precedences
WilliamRagstad May 18, 2025
93142f7
Fix function prec
WilliamRagstad May 18, 2025
6ef26f5
Parse list of min comma precedence
WilliamRagstad May 18, 2025
e4941ea
Implement binding pattern specializing
WilliamRagstad May 18, 2025
8b6962c
Implement assignment evaluation
WilliamRagstad May 18, 2025
09714e8
Fix warnings
WilliamRagstad May 18, 2025
d67062f
Fix print expr
WilliamRagstad May 18, 2025
d8b06ed
Fix comma precedence higher than assign
WilliamRagstad May 18, 2025
5c8cc8e
On error print expr
WilliamRagstad May 18, 2025
17c99df
Type check binding assignments
WilliamRagstad May 18, 2025
b7e3454
Temporary fix
WilliamRagstad May 18, 2025
590019a
Rename sexpr
WilliamRagstad May 18, 2025
c58a43a
Rename sexpr
WilliamRagstad May 18, 2025
3537853
Rename params
WilliamRagstad May 18, 2025
f8c0291
Rename sexpr
WilliamRagstad May 18, 2025
e1b4122
Rename params
WilliamRagstad May 21, 2025
ae63e06
refactor flatten
WilliamRagstad May 21, 2025
21d3e28
Add tests
WilliamRagstad May 21, 2025
8b6ef08
Refactoring tmp
WilliamRagstad May 24, 2025
6293695
remove is ok check from tests
WilliamRagstad May 24, 2025
4b977e1
Remove type annotation in bind patterns
WilliamRagstad May 24, 2025
e4afa3b
Refactor tests
WilliamRagstad May 24, 2025
53d7cbb
Add `Map` and `List` standard type
WilliamRagstad May 25, 2025
3e2c39b
Parse function definitions
WilliamRagstad May 25, 2025
448aae2
Fix comment tests
WilliamRagstad May 25, 2025
a88303c
Fix failing tests
WilliamRagstad May 25, 2025
e17394e
Fix definition bug and refactor
WilliamRagstad May 25, 2025
afc4356
Fix lots of tests
WilliamRagstad May 25, 2025
0ac93c4
Fix tests
WilliamRagstad May 30, 2025
aacbd29
Update parser.rs
WilliamRagstad May 30, 2025
f143240
fix function definition type checking
WilliamRagstad Jun 6, 2025
55cfff9
New arrow in REPL
WilliamRagstad Jun 6, 2025
9c32958
Update imports
WilliamRagstad Jun 6, 2025
7c7df95
Add already define check
WilliamRagstad Jun 6, 2025
784f30b
New arrow again
WilliamRagstad Jun 6, 2025
7c36722
Fix assignment info in error
WilliamRagstad Jun 6, 2025
c7e68a7
No extra eof message
WilliamRagstad Jun 6, 2025
f2f0b85
Fix tests
WilliamRagstad Jun 6, 2025
01046f1
Default to any for params
WilliamRagstad Jun 6, 2025
bb29465
Any type is intrinsic
WilliamRagstad Jun 6, 2025
31b08bb
Improve block def specialization
WilliamRagstad Jun 8, 2025
23d657a
Add TODO
WilliamRagstad Jun 11, 2025
55bfc0e
Fix some tests
WilliamRagstad Jul 25, 2025
363a0c0
Add support for unit type parsing and checking
WilliamRagstad Jul 25, 2025
f6d4230
Update tests.rs
WilliamRagstad Jul 25, 2025
d74db98
Fix record field parsing in parser
WilliamRagstad Jul 25, 2025
ba1efcb
Remove Newline from is_terminator
WilliamRagstad Jul 25, 2025
ddc9b77
Update checker.rs
WilliamRagstad Jul 25, 2025
386e2e7
Move specialize module to type_checker and refactor parser
WilliamRagstad Jul 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cli/src/commands/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ pub fn eval_all<R: Read>(
if asts.is_empty() {
return false;
}
log::debug!(
"Expressions ({}):\n\t{}",
asts.len(),
asts.iter()
.map(|ast| ast.print_expr())
.collect::<Vec<_>>()
.join("\n\t")
);
'exprs: for (i, ast) in asts.iter().enumerate() {
let checked_ast = match checker.check_expr(ast) {
Ok(ast) => ast,
Expand Down
10 changes: 5 additions & 5 deletions cli/src/commands/repl.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use core::str;
use std::io::{Read, Write};

use crate::{commands::eval::eval_all, logger::init_logger_str, CLI_VERSION};
use clap::{ArgMatches, Command};
use colorful::Colorful;
use core::str;
use lento_core::{
interpreter::env::global_env, lexer::lexer::InputSource, parser::parser, stdlib::init::stdlib,
type_checker::checker::TypeChecker,
};
use std::io::{Read, Write};

use crate::{commands::eval::eval_all, logger::init_logger_str, CLI_VERSION};
const PROMPT: &str = "►";

pub fn handle_command_repl(args: &ArgMatches, _arg_parser: &mut Command) {
// Set the Ctrl-C handler to exit the program
Expand Down Expand Up @@ -51,7 +51,7 @@ pub fn handle_command_repl(args: &ArgMatches, _arg_parser: &mut Command) {
let mut env = global_env();
std.init_environment(&mut env);
loop {
print!("> ");
print!("{} ", PROMPT);
std::io::stdout().flush().unwrap();
let found_expr = eval_all(
&mut parser,
Expand Down
8 changes: 0 additions & 8 deletions cli/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ pub fn print_error_report(kind: &str, base: BaseError, content: &str, source: &I
report = report.with_help(hint);
}

if base.info.end.eof {
report = report.with_label(
Label::new((source.name(), base.info.end.index..base.info.end.index))
.with_message(format!("end of {}", source.human_readable()))
.with_color(ariadne::Color::Yellow),
);
}

report
.finish()
.print((source.name(), Source::from(content)))
Expand Down
2 changes: 2 additions & 0 deletions core/src/compiler/backends/cranelift/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*
#[cfg(test)]
mod tests {
use std::io::Write;
Expand Down Expand Up @@ -103,3 +104,4 @@ mod tests {
assert!(!program_output.is_empty());
}
}
*/
93 changes: 81 additions & 12 deletions core/src/interpreter/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ use std::borrow::Borrow;

use crate::{
interpreter::value::NativeFunction,
parser::pattern::BindPattern,
type_checker::{
checked_ast::{CheckedAst, CheckedBindPattern},
checked_ast::CheckedAst,
types::{GetType, Type},
},
util::{error::LineInfo, str::Str},
util::{
error::{BaseErrorExt, LineInfo},
failable::Failable,
str::Str,
},
};

use super::{
Expand Down Expand Up @@ -44,16 +49,11 @@ pub fn eval_expr(ast: &CheckedAst, env: &mut Environment) -> InterpretResult {
CheckedAst::Identifier { name, .. } => match env.lookup_identifier(name) {
(Some(v), _) => v.clone(),
(_, Some(f)) => Value::Function(Box::new(f.clone())),
(_, _) => unreachable!("This should have been checked by the type checker"),
(_, _) => unreachable!("Undefined identifier: {}", name),
},
CheckedAst::Assignment { target, expr, .. } => {
let info = target.info();
let target = match target.to_owned() {
CheckedBindPattern::Variable { name, .. } => name,
_ => unreachable!("This should have been checked by the type checker"),
};
let value = eval_expr(expr, env)?;
env.add_value(Str::String(target), value.clone(), info)?;
eval_assignment(target, &value, env)?;
value
}
CheckedAst::List { exprs, ty, .. } => Value::List(
Expand Down Expand Up @@ -86,7 +86,7 @@ pub fn eval_expr(ast: &CheckedAst, env: &mut Environment) -> InterpretResult {
}
}
}
CheckedAst::FunctionDef {
CheckedAst::Lambda {
param,
body,
return_type,
Expand All @@ -109,7 +109,7 @@ pub fn eval_expr(ast: &CheckedAst, env: &mut Environment) -> InterpretResult {
if !matches!(ast, CheckedAst::Literal { .. }) {
log::trace!(
"Eval: {} -> {}",
ast.print_sexpr(),
ast.print_expr(),
result.pretty_print_color()
);
}
Expand Down Expand Up @@ -160,7 +160,10 @@ fn eval_call(
let arg = eval_expr(arg, env)?;
let mut closure = env.new_child(Str::Str("<closure>"));
// Bind the argument to the parameter of the function variation
closure.add_value(Str::String(param.name.clone()), arg.clone(), info)?;
let BindPattern::Variable { name, info } = &param.pattern else {
unreachable!("Other bind patterns are not supported yet");
};
closure.add_value(Str::String(name.clone()), arg.clone(), info)?;
eval_expr(body, &mut closure)
}
Function::Native { .. } => {
Expand Down Expand Up @@ -216,3 +219,69 @@ fn eval_tuple(exprs: &[CheckedAst], env: &mut Environment) -> InterpretResult {

Ok(Value::Tuple(values, Type::Tuple(types)))
}

/// Evaluate an assignment expression to a bind pattern
fn eval_assignment(
pattern: &BindPattern,
value: &Value,
env: &mut Environment,
) -> Failable<RuntimeError> {
match pattern {
// BindPattern::Function { name, params, .. } => {
// let mut closure = env.new_child(Str::Str("<closure>"));
// closure.add_value(name.clone(), value.clone(), pattern.info())?;
// for param in params {
// if let BindPattern::Variable { name, .. } = param {
// closure.add_value(name.clone(), value.clone(), pattern.info())?;
// }
// }
// }
BindPattern::Variable { name, .. } => {
env.add_value(Str::String(name.clone()), value.clone(), pattern.info())?
}
BindPattern::Tuple { elements, .. } => {
let Value::Tuple(values, _) = value else {
unreachable!("This should have been checked by the type checker");
};
for (pattern, value) in elements.iter().zip(values) {
eval_assignment(pattern, value, env)?;
}
}
BindPattern::Record { fields, .. } => {
let Value::Record(values, _) = value else {
unreachable!("This should have been checked by the type checker");
};
for (key, pattern) in fields {
let Some((_, value)) = values.iter().find(|(k, _)| k == key) else {
unreachable!("This should have been checked by the type checker");
};
eval_assignment(pattern, value, env)?;
}
}
BindPattern::List { elements, .. } => {
let Value::List(values, _) = value else {
unreachable!("This should have been checked by the type checker");
};
for (element, value) in elements.iter().zip(values) {
eval_assignment(element, value, env)?;
}
}
BindPattern::Wildcard => {}
BindPattern::Literal { value: lit, .. } => {
if *value != lit.as_value() {
return Err(RuntimeError::new(
format!(
"Literal pattern match failed: expected {}, found {}",
lit.as_value().pretty_print(),
value.pretty_print()
),
pattern.info().clone(),
));
}
}
BindPattern::Rest { .. } => {
// Handle rest pattern if needed
}
}
Ok(())
}
4 changes: 2 additions & 2 deletions core/src/interpreter/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ trait NumberMethods {
}

/// An unsigned integer number type that can be represented in 1, 8, 16, 32, 64, 128 bits or arbitrary precision.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum UnsignedInteger {
UInt1(u8), // Bit
UInt8(u8), // Byte
Expand Down Expand Up @@ -525,7 +525,7 @@ impl ArithmeticOperations<UnsignedInteger> for UnsignedInteger {
}

/// A signed integer number type that can be represented in 8, 16, 32, 64, 128 bits or arbitrary precision.
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum SignedInteger {
Int8(i8),
Int16(i16),
Expand Down
Loading
Loading