Skip to content

Commit acaa546

Browse files
committed
error messages
proposal for discussion
1 parent 0406b9d commit acaa546

File tree

4 files changed

+58
-39
lines changed

4 files changed

+58
-39
lines changed

src/error_message.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::type_tag::TypeTag;
2+
use crate::value::Value;
3+
4+
pub fn type_mismatch(expected: TypeTag, got: Option<&&Value>) -> Value {
5+
let received_type = if got.is_some() { got.unwrap().type_tag() } else { TypeTag::Nil };
6+
Value::Condition(format!(
7+
"Type mismatch; Expected instance of {}, Recieved type {}",
8+
TypeTag::Integer,
9+
received_type
10+
))
11+
}
12+
13+
pub fn wrong_arg_count(expected: usize, got: usize) -> Value {
14+
Value::Condition(format!(
15+
"Wrong number of arguments given to function (Given: {}, Expected: {})",
16+
got,
17+
expected
18+
))
19+
}
20+
21+
pub fn wrong_varg_count(expected: &[usize], got: usize) -> Value {
22+
Value::Condition(format!(
23+
"Wrong number of arguments given to function (Given: {}, Expected: {:?})",
24+
got,
25+
expected
26+
))
27+
}
28+
29+
pub fn index_out_of_bounds(ind: usize, count: usize) -> Value {
30+
Value::Condition(format!(
31+
"Index out of bounds: Index ({}), Length: ({})",
32+
ind, count
33+
))
34+
}
35+
36+
pub fn index_cannot_be_negative(ind: usize) -> Value {
37+
Value::Condition(format!("Index cannot be negative; Index ({})", ind))
38+
}

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod rust_core;
1515
mod symbol;
1616
mod type_tag;
1717
mod value;
18+
mod error_message;
1819

1920
fn main() {
2021
//

src/rust_core.rs

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use crate::persistent_vector::{PersistentVector, ToPersistentVectorIter};
1212
use crate::symbol::Symbol;
1313
use crate::value::{Evaluable, ToValue};
1414

15+
use crate::error_message;
16+
use crate::type_tag::TypeTag;
17+
1518
//
1619
// This module will hold the core functions and macros that Clojure will
1720
// hook into; Functions / Macros like "+", "fn*", "let", "cond", etc
@@ -72,12 +75,12 @@ impl IFn for AddFn {
7275
args.into_iter().fold(0_i32.to_value(), |a, b| match a {
7376
Value::I32(a_) => match b {
7477
Value::I32(b_) => Value::I32(a_ + b_),
75-
_ => Value::Condition(format!(
78+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
7679
"Type mismatch; Expecting: (i32 | i64 | f32 | f64), Found: {}",
7780
b.type_tag()
7881
)),
7982
},
80-
_ => Value::Condition(format!(
83+
_ => Value::Condition(format!( // TODO: what error message should be returned regarding using typetags?
8184
"Type mismatch: Expecting: (i32 | i64 | f32 | f64), Found: {}",
8285
a.type_tag()
8386
)),
@@ -105,11 +108,7 @@ impl IFn for EvalFn {
105108
fn invoke(&self, args: Vec<&Value>) -> Value {
106109
// @TODO generalize arity exceptions, and other exceptions
107110
if args.len() != 1 {
108-
return Value::Condition(format!(
109-
"Wrong number of arguments given to function (Given: {}, Expected: {})",
110-
args.len(),
111-
args.len()
112-
));
111+
return error_message::wrong_arg_count(1, args.len())
113112
}
114113
let arg = args.get(0).unwrap();
115114
arg.eval(Rc::clone(&self.enclosing_environment))
@@ -178,58 +177,39 @@ impl IFn for NthFn {
178177
fn invoke(&self, args: Vec<&Value>) -> Value {
179178
// @TODO generalize arity exceptions, and other exceptions
180179
if args.len() != 2 {
181-
return Value::Condition(format!(
182-
"Wrong number of arguments (Given: {}, Expected: 1-2)",
183-
args.len()
184-
));
180+
return error_message::wrong_arg_count(2, args.len())
185181
}
186182
// @TODO change iteration to work with Value references, or even change invoke to work on Rc<..>
187183
// as we do everything else; surely we don't want to clone just to read from a collection
188184
if let Some(Value::I32(ind)) = args.get(1) {
189185
if *ind < 0 {
190-
return Value::Condition(format!("Index cannot be negative; Index ({})", ind));
186+
return error_message::index_cannot_be_negative(*ind as usize)
191187
}
192188
let ind = *ind as usize;
193189

194190
match args.get(0).unwrap() {
195191
Value::PersistentList(Cons(head, tail, count)) => {
196192
let count = *count as usize;
197193
if ind >= count {
198-
Value::Condition(format!(
199-
"Index out of bounds: Index ({}), Length: ({})",
200-
ind, count
201-
))
194+
error_message::index_out_of_bounds(ind, count)
202195
} else if ind == 0 {
203196
head.to_value()
204197
} else {
205198
tail.iter().nth(ind - 1).unwrap().to_value()
206199
}
207200
}
208-
Value::PersistentList(Empty) => Value::Condition(format!(
209-
"Index out of bounds: Index ({}), Length: ({})",
210-
ind, 0
211-
)),
201+
Value::PersistentList(Empty) => error_message::index_out_of_bounds(ind, 0),
212202
Value::PersistentVector(PersistentVector { vals }) => {
213203
if ind >= vals.len() {
214-
Value::Condition(format!(
215-
"Index out of bounds: Index ({}), Length: ({})",
216-
ind,
217-
vals.len()
218-
))
204+
error_message::index_out_of_bounds(ind, vals.len())
219205
} else {
220206
vals.get(ind).unwrap().to_value()
221207
}
222208
}
223-
_ => Value::Condition(format!(
224-
"Type mismatch; Expected instance of clojure.lang.ISeq, Recieved type {}",
225-
args.get(0).unwrap().type_tag()
226-
)),
209+
_ => error_message::type_mismatch(TypeTag::ISeq, args.get(0)),
227210
}
228211
} else {
229-
Value::Condition(format!(
230-
"Type mismatch; Expected instance of clojure.lang.Integer, Recieved type {}",
231-
args.get(1).unwrap().type_tag()
232-
))
212+
error_message::type_mismatch(TypeTag::Integer, args.get(0))
233213
}
234214
}
235215
}
@@ -273,11 +253,7 @@ impl ToValue for PrintStringFn {
273253
impl IFn for PrintStringFn {
274254
fn invoke(&self, args: Vec<&Value>) -> Value {
275255
if args.len() != 1 {
276-
return Value::Condition(format!(
277-
"Wrong number of arguments given to function (Given: {}, Expected: {})",
278-
args.len(),
279-
args.len()
280-
));
256+
return error_message::wrong_arg_count(1, args.len())
281257
}
282258
println!("{}", args.get(0).unwrap().to_string());
283259
Value::Nil

src/type_tag.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ pub enum TypeTag {
1212
// Experimental; may make no sense at runtime, as we will likely be unable to take the value of a macro
1313
Macro,
1414
String,
15-
Nil,
15+
Integer,
16+
ISeq,
17+
Nil
1618
}
1719
use TypeTag::*;
1820
impl fmt::Display for TypeTag {
@@ -28,6 +30,8 @@ impl fmt::Display for TypeTag {
2830
PersistentListMap => std::string::String::from("clojure.lang.PersistentListMap"),
2931
Macro => std::string::String::from("clojure.lang.Macro"),
3032
TypeTag::String => std::string::String::from("rust.std.string.String"),
33+
TypeTag::Integer => std::string::String::from("clojure.lang.Integer"),
34+
ISeq => std::string::String::from("clojure.lang.ISeq"),
3135
Nil => std::string::String::from("clojure.lang.Nil"),
3236
};
3337
write!(f, "{}", str)

0 commit comments

Comments
 (0)