diff options
| -rw-r--r-- | samples/sample1.code | 12 | ||||
| -rw-r--r-- | src/builtins.rs | 50 | ||||
| -rw-r--r-- | src/test.rs | 41 |
3 files changed, 89 insertions, 14 deletions
diff --git a/samples/sample1.code b/samples/sample1.code index bd6b558..1af3984 100644 --- a/samples/sample1.code +++ b/samples/sample1.code @@ -1,5 +1,7 @@ -f a b = a (int.add 10); -f; -f id; -f id id; -f id id -50;
\ No newline at end of file +int.eq? 10 20 + "true" + "false"; + +int.eq? 30 30 + "true" + "false"; diff --git a/src/builtins.rs b/src/builtins.rs index a24db52..20ea19d 100644 --- a/src/builtins.rs +++ b/src/builtins.rs @@ -21,7 +21,8 @@ impl fmt::Display for Builtin { } } -pub const B_INTEGER_EQ0: &str = "int.eq0?"; +pub const B_INTEGER_EQ: &str = "int.eq?"; +pub const B_INTEGER_EQ_1: &str = "##int.eq?_1"; pub const B_INTEGER_INCREMENT: &str = "int.increment"; pub const B_INTEGER_ADD: &str = "int.add"; pub const B_INTEGER_ADD_1: &str = "##int.add_1"; @@ -48,9 +49,9 @@ pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> { "true" => return Some(make_boolean_true_function()), "false" => return Some(make_boolean_false_function()), "id" => return Some(make_identity_function()), - B_INTEGER_EQ0 => Builtin { - identifier: B_INTEGER_EQ0, - repr_name: B_INTEGER_EQ0, + B_INTEGER_EQ => Builtin { + identifier: B_INTEGER_EQ, + repr_name: B_INTEGER_EQ, arguments: vec![], }, B_INTEGER_INCREMENT => Builtin { @@ -71,13 +72,44 @@ pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> { pub fn evaluate_builtin(builtin: &Builtin, rhs: Rc<Term>) -> Result<(Rc<Term>, usize), String> { let result_term = match builtin.identifier { - B_INTEGER_EQ0 => match &*rhs { + B_INTEGER_EQ => match &*rhs { + Term::Primitive(primitive) => match primitive { + Value::Integer(_) => { + let new_builtin = Builtin { + identifier: B_INTEGER_EQ_1, + repr_name: builtin.identifier, + arguments: vec![primitive.clone()], + }; + Term::Builtin(new_builtin) + } + other => { + return Err(format!( + "[runtime] cannot apply builtin {} to argument {}", + builtin.identifier, other + )) + } + }, + _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)), + }, + B_INTEGER_EQ_1 => match &*rhs { Term::Primitive(primitive) => match primitive { Value::Integer(value) => { - if *value == 0 { - make_boolean_true_function() - } else { - make_boolean_false_function() + assert_eq!(builtin.arguments.len(), 1); + let other = &builtin.arguments[0]; + match other { + Value::Integer(other_value) => { + if value == other_value { + make_boolean_true_function() + } else { + make_boolean_false_function() + } + } + other => { + return Err(format!( + "[runtime] cannot apply builtin {} to argument {}", + builtin.identifier, other + )) + } } } other => { diff --git a/src/test.rs b/src/test.rs index 10d907c..70bfd49 100644 --- a/src/test.rs +++ b/src/test.rs @@ -195,3 +195,44 @@ fn reduce_builtin_int_add() -> Result<(), String> { Ok(()) } + +#[test] +#[serial] +fn reduce_builtin_int_eq() -> Result<(), String> { + initialize_before_test(); + let source = " + int.eq? 10 20 + \"true\" + \"false\"; + int.eq? 30 30 + \"true\" + \"false\"; + "; + + let (terms, symbol_table) = evaluate_from_source(String::from(source), None)?; + assert_eq!(terms.len(), 2); + let term1 = &terms[0]; + let term2 = &terms[1]; + + // First expression + let (result_term1, _) = repeatedly_reduce_term(&symbol_table, Rc::clone(term1), &None, false)?; + let expected1_string = Value::String(String::from("false")); + let result_builtin1 = match &*result_term1 { + Term::Primitive(p) => p, + _ => return Err(format!("{} is not a primitive", result_term1)), + }; + + assert_eq!(*result_builtin1, expected1_string); + + // Second expression + let (result_term2, _) = repeatedly_reduce_term(&symbol_table, Rc::clone(term2), &None, false)?; + let expected2_string = Value::String(String::from("true")); + let result_builtin2 = match &*result_term2 { + Term::Primitive(p) => p, + _ => return Err(format!("{} is not a primitive", result_term2)), + }; + + assert_eq!(*result_builtin2, expected2_string); + + Ok(()) +} |
