Commit 04a9d9f8 authored by Jeff Smits's avatar Jeff Smits

Refactored primitive definition into a macro, simplifies making changes to the format

parent e86aa5f3
use context::MutContext;
use error::{Error, Result};
use factory::{Blob, HashTable, ATermRef};
use preprocess::StrategyDef;
use error::Error;
use factory::{Blob, HashTable};
use interpreter::eval_sdef;
use aterm::{ATermFactory as ATF, ATerm as A};
......@@ -26,23 +24,13 @@ impl<'f> HashTableState<'f> {
}
}
pub fn table_hashtable<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(table_hashtable, (context, _current) => {
Ok(context.factory.blob(Blob::HashTable(
context.ssl_state.borrow().hash_table.global_table.clone(),
)))
}
});
pub fn dynamic_rules_hashtable<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(dynamic_rules_hashtable, (context, _current) => {
Ok(
context.factory.blob(Blob::HashTable(
context
......@@ -53,20 +41,9 @@ pub fn dynamic_rules_hashtable<'d, 'f: 'd>(
.clone(),
)),
)
}
});
pub fn hashtable_create<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_create called with wrong argument \
count",
));
}
primitive!(hashtable_create, 2, (context, targs, _current) => {
let capacity = targs[0].get_int().ok_or(Error::StrategyFailed)?;
// We don't have a concept of load_factor, so we check the type and then ignore it
let _load_factor = targs[1].get_int().ok_or(Error::StrategyFailed)?;
......@@ -85,21 +62,10 @@ pub fn hashtable_create<'d, 'f: 'd>(
),
)
}
}
});
pub fn hashtable_reset<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(hashtable_reset, 1, (_context, targs, current) => {
use try_from::TryInto;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_reset called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[0]
.get_blob()
.cloned()
......@@ -111,30 +77,12 @@ pub fn hashtable_reset<'d, 'f: 'd>(
table.borrow_mut().clear();
Ok(current)
}
});
pub fn hashtable_destroy<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
hashtable_reset(context, sargs, targs, current)
}
primitive!(hashtable_destroy = hashtable_reset);
pub fn hashtable_put<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(hashtable_put, 3, (_context, targs, _current) => {
use try_from::TryInto;
if targs.len() < 3 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_put called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[0]
.get_blob()
.cloned()
......@@ -149,21 +97,10 @@ pub fn hashtable_put<'d, 'f: 'd>(
let _ = table.borrow_mut().insert(key, value);
Ok(targs[0].clone())
}
});
pub fn hashtable_remove<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(hashtable_remove, 2, (_context, targs, _current) => {
use try_from::TryInto;
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_remove called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[0]
.get_blob()
.cloned()
......@@ -175,21 +112,10 @@ pub fn hashtable_remove<'d, 'f: 'd>(
let _ = table.borrow_mut().remove(&targs[1]);
Ok(targs[0].clone())
}
});
pub fn hashtable_get<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(hashtable_get, 2, (_context, targs, _current) => {
use try_from::TryInto;
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_get called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[0]
.get_blob()
.cloned()
......@@ -203,21 +129,10 @@ pub fn hashtable_get<'d, 'f: 'd>(
Error::StrategyFailed,
)?;
Ok(result)
}
});
pub fn hashtable_keys<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(hashtable_keys, 1, (context, targs, _current) => {
use try_from::TryInto;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive hashtable_keys called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[0]
.get_blob()
.cloned()
......@@ -229,22 +144,10 @@ pub fn hashtable_keys<'d, 'f: 'd>(
let result = context.factory.list(table.borrow().keys().cloned());
Ok(result)
}
});
pub fn table_fold<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(table_fold, 1, 2, (context, sargs, targs, _current) => {
use try_from::TryInto;
if sargs.len() < 1 || targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive table_fold called with wrong argument \
count",
));
}
let mut current = targs[0].clone();
let table: Rc<RefCell<HashTable<'f>>> = targs[1]
......@@ -267,22 +170,10 @@ pub fn table_fold<'d, 'f: 'd>(
}
Ok(current)
}
});
pub fn table_keys_fold<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(table_keys_fold, 1, 2, (context, sargs, targs, _current) => {
use try_from::TryInto;
if sargs.len() < 1 || targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive table_keys_fold called with wrong argument \
count",
));
}
let table: Rc<RefCell<HashTable<'f>>> = targs[1]
.get_blob()
.cloned()
......@@ -299,22 +190,10 @@ pub fn table_keys_fold<'d, 'f: 'd>(
}
Ok(current)
}
});
pub fn table_values_fold<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
primitive!(table_values_fold, 1, 2, (context, sargs, targs, _current) => {
use try_from::TryInto;
if sargs.len() < 1 || targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive table_values_fold called with wrong argument \
count",
));
}
let mut current = targs[0].clone();
let table: Rc<RefCell<HashTable<'f>>> = targs[1]
......@@ -331,4 +210,4 @@ pub fn table_values_fold<'d, 'f: 'd>(
}
Ok(current)
}
});
use context::MutContext;
use error::{Error, Result};
use factory::{IndexedSet, ATermRef};
use preprocess::StrategyDef;
use error::Error;
use factory::IndexedSet;
use interpreter::eval_sdef;
use aterm::{ATermFactory as ATF, ATerm as A};
......@@ -11,17 +9,7 @@ use std::cell::RefMut;
use std::rc::Rc;
use std::borrow::Borrow;
pub fn indexedSet_create<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_create called with wrong argument count",
));
}
primitive!(indexedSet_create, 2, (context, targs, current) => {
let capacity = targs[0].get_int().ok_or(Error::StrategyFailed)?;
// We don't have a concept of load_factor, so we check the type and then ignore it
let _load_factor = targs[1].get_int().ok_or(Error::StrategyFailed)?;
......@@ -35,20 +23,10 @@ pub fn indexedSet_create<'d, 'f: 'd>(
IndexedSet::with_capacity(capacity as usize).into(),
))
}
}
pub fn indexedSet_reset<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_reset, 1, (context, targs, current) => {
use try_from::TryInto;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_destroy called with wrong argument count",
));
}
let set: Rc<RefCell<IndexedSet>> = targs[0]
.get_blob()
.cloned()
......@@ -60,29 +38,12 @@ pub fn indexedSet_reset<'d, 'f: 'd>(
set.borrow_mut().clear();
Ok(current)
}
pub fn indexedSet_destroy<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
indexedSet_reset(context, sargs, targs, current)
}
pub fn indexedSet_put<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_destroy = indexedSet_reset);
primitive!(indexedSet_put, 1, 2, (context, sargs, targs, current) => {
use try_from::TryInto;
if sargs.len() < 1 || targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_put called with wrong argument count",
));
}
let set: Rc<RefCell<IndexedSet>> = targs[0]
.get_blob()
.cloned()
......@@ -106,20 +67,10 @@ pub fn indexedSet_put<'d, 'f: 'd>(
}
None => Ok(context.factory.int(set.insert(key.clone()) as i32)),
}
}
pub fn indexedSet_remove<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_remove, 2, (context, targs, current) => {
use try_from::TryInto;
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_remove called with wrong argument count",
));
}
let set: Rc<RefCell<IndexedSet>> = targs[0]
.get_blob()
.cloned()
......@@ -130,20 +81,10 @@ pub fn indexedSet_remove<'d, 'f: 'd>(
let set: &RefCell<IndexedSet> = set.borrow();
let _ = set.borrow_mut().remove(&targs[1]);
Ok(targs[0].clone())
}
pub fn indexedSet_getIndex<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_getIndex, 2, (context, targs, current) => {
use try_from::TryInto;
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_getIndex called with wrong argument count",
));
}
let set: Rc<RefCell<IndexedSet>> = targs[0]
.get_blob()
.cloned()
......@@ -156,30 +97,15 @@ pub fn indexedSet_getIndex<'d, 'f: 'd>(
Error::StrategyFailed,
)?;
Ok(context.factory.int(result as i32))
}
pub fn indexedSet_getElem<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_getElem, (_context, _current) => {
eprintln!("Not available in Java either!");
unimplemented!()
}
pub fn indexedSet_elements<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
});
primitive!(indexedSet_elements, 1, (context, targs, current) => {
use try_from::TryInto;
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive indexedSet_elements called with wrong argument count",
));
}
let set: Rc<RefCell<IndexedSet>> = targs[0]
.get_blob()
.cloned()
......@@ -192,4 +118,4 @@ pub fn indexedSet_elements<'d, 'f: 'd>(
let result = context.factory.list(keys.into_iter());
Ok(result)
}
});
use context::MutContext;
use error::{Error, Result};
use factory::ATermRef;
use preprocess::StrategyDef;
use error::Error;
use aterm::{ATermFactory as ATF, ATerm as A};
pub fn is_int<'d, 'f: 'd>(
_context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive is_int called with wrong argument count",
));
}
primitive!(is_int, 1, (context, targs, current) => {
targs[0].get_int().map(|_| current).ok_or(
Error::StrategyFailed,
)
}
});
pub fn int<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive int called with wrong argument count",
));
}
primitive!(int, 1, (context, targs, current) => {
targs[0]
.get_int()
.map(|_| targs[0].clone())
......@@ -39,131 +16,51 @@ pub fn int<'d, 'f: 'd>(
targs[0].get_real().map(|r| context.factory.int(r as i32))
})
.ok_or(Error::StrategyFailed)
}
});
pub fn iori<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive iori called with wrong argument count",
));
}
primitive!(iori, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 | i2))
}
});
pub fn xori<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive xori called with wrong argument count",
));
}
primitive!(xori, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 ^ i2))
}
});
pub fn andi<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive andi called with wrong argument count",
));
}
primitive!(andi, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 & i2))
}
});
pub fn shli<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive shli called with wrong argument count",
));
}
primitive!(shli, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 << i2))
}
});
pub fn shri<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive shri called with wrong argument count",
));
}
primitive!(shri, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 >> i2))
}
});
pub fn addi<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive addi called with wrong argument count",
));
}
primitive!(addi, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 + i2))
}
});
pub fn divi<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive divi called with wrong argument count",
));
}
primitive!(divi, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 / i2))
}
});
pub fn gti<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive gti called with wrong argument count",
));
}
primitive!(gti, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
if i1 > i2 {
......@@ -171,98 +68,41 @@ pub fn gti<'d, 'f: 'd>(
} else {
Err(Error::StrategyFailed)
}
}
});
pub fn muli<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive muli called with wrong argument count",
));
}
primitive!(muli, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 * i2))
}
});
pub fn modi<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive modi called with wrong argument count",
));
}
primitive!(modi, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 % i2))
}
});
pub fn subti<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 2 {
return Err(Error::UnknownBehaviour(
"Primitive subti called with wrong argument count",
));
}
primitive!(subti, 2, (context, targs, current) => {
let i1 = targs[0].get_int().ok_or(Error::StrategyFailed)?;
let i2 = targs[1].get_int().ok_or(Error::StrategyFailed)?;
Ok(context.factory.int(i1 - i2))
}
});
pub fn int_to_string<'d, 'f: 'd>(
context: &MutContext<'d, 'f>,
_sargs: &[StrategyDef<'d, 'f>],
targs: &[ATermRef<'f>],
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
if targs.len() < 1 {
return Err(Error::UnknownBehaviour(
"Primitive int_to_string called with wrong argument \
count",
));
}
primitive!(int_to_string, 1, (context, targs, current) => {
targs[0]
.get_int()