aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--samples/sample1.code7
-rw-r--r--src/builtins.rs100
-rw-r--r--src/runtime.rs10
3 files changed, 76 insertions, 41 deletions
diff --git a/samples/sample1.code b/samples/sample1.code
index 05904aa..bd6b558 100644
--- a/samples/sample1.code
+++ b/samples/sample1.code
@@ -1,2 +1,5 @@
-fn a b = b a;
-fn 10 int.add 20;
+f a b = a (int.add 10);
+f;
+f id;
+f id id;
+f id id -50; \ No newline at end of file
diff --git a/src/builtins.rs b/src/builtins.rs
index b8b789f..51ea699 100644
--- a/src/builtins.rs
+++ b/src/builtins.rs
@@ -1,7 +1,26 @@
use super::ast;
use super::runtime::{advance_v, Term, Value};
+use std::fmt;
use std::rc::Rc;
+#[derive(Debug, Clone, PartialEq)]
+pub struct Builtin {
+ identifier: &'static str,
+ repr_name: &'static str,
+ arguments: Vec<Value>,
+}
+
+impl fmt::Display for Builtin {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut arg_str = String::new();
+ for argument in &self.arguments {
+ arg_str.push_str(format!(" {}", argument).as_str());
+ }
+
+ write!(f, "Builtin({}){}", self.repr_name, arg_str)
+ }
+}
+
pub const B_INTEGER_EQ0: &str = "int.eq0?";
pub const B_INTEGER_INCREMENT: &str = "int.increment";
pub const B_INTEGER_ADD: &str = "int.add";
@@ -25,23 +44,33 @@ pub fn make_identity_function() -> Term {
}
pub fn try_ast_symbol_to_builtin_term(symbol: &ast::Symbol) -> Option<Term> {
- match symbol.as_str() {
- "true" => Some(make_boolean_true_function()),
- "false" => Some(make_boolean_false_function()),
- "id" => Some(make_identity_function()),
- B_INTEGER_EQ0 => Some(Term::Builtin(String::from(B_INTEGER_EQ0), vec![])),
- B_INTEGER_INCREMENT => Some(Term::Builtin(String::from(B_INTEGER_INCREMENT), vec![])),
- B_INTEGER_ADD => Some(Term::Builtin(String::from(B_INTEGER_ADD), vec![])),
- _ => None,
- }
+ let builtin = match symbol.as_str() {
+ "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,
+ arguments: vec![],
+ },
+ B_INTEGER_INCREMENT => Builtin {
+ identifier: B_INTEGER_INCREMENT,
+ repr_name: B_INTEGER_INCREMENT,
+ arguments: vec![],
+ },
+ B_INTEGER_ADD => Builtin {
+ identifier: B_INTEGER_ADD,
+ repr_name: B_INTEGER_ADD,
+ arguments: vec![],
+ },
+ _ => return None,
+ };
+
+ Some(Term::Builtin(builtin))
}
-pub fn evaluate_builtin(
- symbol: &String,
- bound_arguments: &Vec<Value>,
- rhs: Rc<Term>,
-) -> Result<(Rc<Term>, usize), String> {
- let result_term = match symbol.as_str() {
+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 {
Term::Primitive(primitive) => match primitive {
Value::Integer(value) => {
@@ -54,11 +83,11 @@ pub fn evaluate_builtin(
other => {
return Err(format!(
"[runtime] cannot apply builtin {} to argument {}",
- symbol, other
+ builtin.identifier, other
))
}
},
- _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)),
+ _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)),
},
B_INTEGER_INCREMENT => match &*rhs {
Term::Primitive(primitive) => match primitive {
@@ -66,31 +95,36 @@ pub fn evaluate_builtin(
other => {
return Err(format!(
"[runtime] cannot apply builtin {} to argument {}",
- symbol, other
+ builtin.identifier, other
))
}
},
- _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)),
+ _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)),
},
B_INTEGER_ADD => match &*rhs {
Term::Primitive(primitive) => match primitive {
Value::Integer(_) => {
- Term::Builtin(String::from(B_INTEGER_ADD_1), vec![primitive.clone()])
+ let new_builtin = Builtin {
+ identifier: B_INTEGER_ADD_1,
+ repr_name: builtin.identifier,
+ arguments: vec![primitive.clone()],
+ };
+ Term::Builtin(new_builtin)
}
other => {
return Err(format!(
"[runtime] cannot apply builtin {} to argument {}",
- symbol, other
+ builtin.identifier, other
))
}
},
- _ => return Ok((Rc::new(Term::Builtin(symbol.clone(), vec![])), 0)),
+ _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)),
},
B_INTEGER_ADD_1 => match &*rhs {
Term::Primitive(primitive) => match primitive {
Value::Integer(value) => {
- assert_eq!(bound_arguments.len(), 1);
- let summand = &bound_arguments[0];
+ assert_eq!(builtin.arguments.len(), 1);
+ let summand = &builtin.arguments[0];
match summand {
Value::Integer(summand_value) => {
Term::Primitive(Value::Integer(summand_value + value))
@@ -98,7 +132,7 @@ pub fn evaluate_builtin(
other => {
return Err(format!(
"[runtime] cannot apply builtin {} to argument {}",
- symbol, other
+ builtin.identifier, other
))
}
}
@@ -106,18 +140,18 @@ pub fn evaluate_builtin(
other => {
return Err(format!(
"[runtime] cannot apply builtin {} to argument {}",
- symbol, other
+ builtin.identifier, other
))
}
},
- _ => {
- return Ok((
- Rc::new(Term::Builtin(symbol.clone(), bound_arguments.clone())),
- 0,
- ))
- }
+ _ => return Ok((Rc::new(Term::Builtin(builtin.clone())), 0)),
},
- _ => return Err(format!("[runtime] invalid builtin evaluated: {}", symbol)),
+ _ => {
+ return Err(format!(
+ "[runtime] invalid builtin evaluated: {}",
+ builtin.identifier
+ ))
+ }
};
Ok((Rc::new(result_term), 1))
diff --git a/src/runtime.rs b/src/runtime.rs
index 84f1820..9612659 100644
--- a/src/runtime.rs
+++ b/src/runtime.rs
@@ -27,7 +27,7 @@ pub enum Term {
Application(Rc<Term>, Rc<Term>),
Primitive(Value),
Lazy(String),
- Builtin(String, Vec<Value>),
+ Builtin(builtins::Builtin),
}
impl Term {
@@ -40,7 +40,7 @@ impl Term {
Value::Integer(int_val) => format!("{}Integer({})", indent_str, int_val),
Value::String(str_val) => format!("{}String({})", indent_str, str_val),
},
- Term::Builtin(symbol, _) => format!("{}Builtin({})", indent_str, symbol),
+ Term::Builtin(builtin) => format!("{}{}", indent_str, builtin),
Term::Abstraction(v, body) => format!(
"{}Abstraction({})\n{}",
indent_str,
@@ -137,9 +137,7 @@ pub fn reduce_term(
&Some((*abs_v, subst_rhs_rc)),
resolve_lazy,
),
- Term::Builtin(symbol, bound_arguments) => {
- builtins::evaluate_builtin(symbol, bound_arguments, subst_rhs_rc)
- }
+ Term::Builtin(builtin) => builtins::evaluate_builtin(builtin, subst_rhs_rc),
_ => Ok((
Rc::new(Term::Application(subst_lhs_rc, subst_rhs_rc)),
subst_n,
@@ -157,7 +155,7 @@ pub fn reduce_term(
)?;
Ok((Rc::new(Term::Abstraction(*abs_v, subst_body)), subst_n))
}
- Term::Builtin(_, _) => Ok((term_rc, 0)),
+ Term::Builtin(_) => Ok((term_rc, 0)),
// Term::Lazy(symbol) => {
// if resolve_lazy {
// let table_lookup_value = symbol_table.get(symbol);