...
 
Commits (3)
......@@ -318,30 +318,52 @@ fn gen_strc_tests() {
for entry in read_dir("tests/strc_tests").unwrap() {
let path = entry.unwrap().path();
if path.is_file() && Some("ctree".as_ref()) == path.extension() {
// Should we sanitise file_stem so it's likely to be a valid test name?
use std::io::Read;
// Should we sanitise file_stem more than this?
let test_name = path.file_stem().unwrap().to_str().unwrap().replace(
'-',
"_",
);
let path_string = path.to_str().unwrap();
let source = path.with_extension("str");
let mut source_file = File::open(source).unwrap();
let mut source = String::new();
source_file.read_to_string(&mut source).unwrap();
let libs_string = if source.contains("libstratego-lib") {
r#"
let str_path = io::find_str_path(None);
let libraries = iter::once(String::from("libstratego-lib"))
.map(|lib_path| io::read_lib(&f, str_path.as_ref(), &lib_path))
.collect::<Result<_>>();
assert!(libraries.is_ok());
let libraries = libraries.unwrap();
"#
} else {
r#"
let libraries = Libraries::default();
"#
};
write!(
file,
r#"
#[test]
fn {}() {{
let str_path = io::find_str_path(None);
fn {test}() {{
let handler = thread::Builder::new()
.name("Main execution thread".into())
.stack_size(STACK_SIZE * 1024 * 1024)
.spawn(move || {{
let f = ATermFactory::new();
let libraries = iter::once(String::from("libstratego-lib"))
.map(|lib_path| io::read_lib(&f, str_path.as_ref(), &lib_path))
.collect::<Result<_>>();
assert!(libraries.is_ok());
let program = io::read_aterm(&f, &"{}");
{libraries}
let program = io::read_aterm(&f, &"{path}");
assert!(program.is_ok());
let term = interpret_main(&f, program.unwrap(), libraries.unwrap());
let program = program.unwrap();
let term = interpret_main(&f, program, libraries);
match term {{
Ok(term) => {{
let mut result = String::new();
......@@ -357,8 +379,9 @@ fn {}() {{
assert!(result.is_ok());
}}
"#,
test_name,
path_string
test = test_name,
path = path_string,
libraries = libs_string,
).unwrap();
}
}
......
......@@ -792,7 +792,7 @@ fn all_vars_bound<'s>(bt: &ir_v1::BuildTerm<'s>, m: &Scopes<'s>) -> bool {
impl<'s> CTreeOptimize for ir_v1::MatchTerm<'s> {
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(self, mut c: &mut Self::Context) -> Self {
fn optimize(self, c: &mut Self::Context) -> Self {
use ir_v1::MatchTerm::*;
match self {
......@@ -830,7 +830,7 @@ impl<'s> CTreeOptimize for ir_v1::MatchTerm<'s> {
impl<'s> CTreeOptimize for ir_v1::BuildTerm<'s> {
type Context = (Option<InternedString<'s>>, Scopes<'s>);
fn optimize(self, mut c: &mut Self::Context) -> Self {
fn optimize(self, c: &mut Self::Context) -> Self {
use ir_v1::BuildTerm::*;
match self {
......
......@@ -9,7 +9,7 @@ use fnv::FnvHashMap;
use aterm::string_share::InternedString;
use std::fmt;
use std::cell::{Cell, RefCell};
use std::cell::RefCell;
/// This context is internally mutable in `RefCell` fields. This is just for convenience as we don't
/// want to pass around the mutable fields separately. But the internal mutability is not a hidden
......@@ -19,8 +19,8 @@ pub struct MutContext<'d, 'f: 'd> {
pub term: RefCell<Vec<Option<ATermRef<'f>>>>,
pub overlays: RefCell<Vec<(usize, FnvHashMap<usize, ATermRef<'f>>)>>,
pub strategy: RefCell<Vec<StrategyDef<'d, 'f>>>,
pub strategy_clos_offset: Cell<usize>,
pub term_clos_offset: Cell<usize>,
pub strategy_clos_offsets: RefCell<Vec<usize>>,
pub term_clos_offsets: RefCell<Vec<usize>>,
pub factory: &'f ATermFactory,
pub primitives: Vec<&'static Primitives>,
pub ssl_state: RefCell<State<'f>>,
......@@ -34,13 +34,13 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
) -> MutContext<'d, 'f> {
MutContext {
stack_tracer: RefCell::new(StackTracer::default()),
factory: factory,
primitives: primitives,
factory,
primitives,
term: RefCell::new(Vec::new()),
overlays: RefCell::new(Vec::new()),
strategy: RefCell::new(strat_scope),
strategy_clos_offset: Cell::new(0),
term_clos_offset: Cell::new(0),
strategy_clos_offsets: RefCell::new(Vec::new()),
term_clos_offsets: RefCell::new(Vec::new()),
ssl_state: RefCell::new(State::new()),
}
}
......@@ -68,32 +68,45 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
result
}
pub fn make_clos_offsets(&self) -> (Vec<usize>, Vec<usize>) {
let mut term_clos_offsets = self.term_clos_offsets.borrow().clone();
let mut strategy_clos_offsets = self.strategy_clos_offsets.borrow().clone();
term_clos_offsets.push(self.term.borrow().len());
strategy_clos_offsets.push(self.strategy.borrow().len());
(term_clos_offsets, strategy_clos_offsets)
}
pub fn make_let_clos_offsets(&self, let_scope_size: usize) -> (Vec<usize>, Vec<usize>) {
let mut term_clos_offsets = self.term_clos_offsets.borrow().clone();
let mut strategy_clos_offsets = self.strategy_clos_offsets.borrow().clone();
term_clos_offsets.push(self.term.borrow().len());
strategy_clos_offsets.push(self.strategy.borrow().len());
// note the extra scope, because `let`s allow recursive definitions
strategy_clos_offsets.push(self.strategy.borrow().len() + let_scope_size);
(term_clos_offsets, strategy_clos_offsets)
}
pub fn get_strategy(&self, strat_ref: StrategyRef) -> Result<StrategyDef<'d, 'f>> {
Ok(
match strat_ref {
StrategyRef::Local(offset_from_end) => {
eprintln!("Looking up at end, {} - {} = {}", self.strategy.borrow().len(), offset_from_end, self.strategy.borrow().len() - offset_from_end);
self.strategy.borrow()[self.strategy.borrow().len() - offset_from_end].clone()
}
StrategyRef::Closure(offset_from_clos_end) => {
eprintln!("Looking up at closure_end, {} - {} = {}", self.strategy_clos_offset.get(), offset_from_clos_end, self.strategy_clos_offset.get() - offset_from_clos_end);
self.strategy.borrow()[self.strategy_clos_offset.get() - offset_from_clos_end].clone()
}
}
)
let offset = if strat_ref.scope_offset > 0 {
self.strategy_clos_offsets.borrow()[self.strategy_clos_offsets.borrow().len() -
strat_ref.scope_offset] -
strat_ref.ref_offset
} else {
self.strategy.borrow().len() - strat_ref.ref_offset
};
Ok(self.strategy.borrow()[offset].clone())
}
pub fn get_term(&self, term_ref: TermRef) -> Result<ATermRef<'f>> {
let offset = match term_ref {
TermRef::Local(offset_from_end) => {
self.term.borrow().len() - offset_from_end
}
TermRef::Closure(offset_from_clos_end) => {
self.term_clos_offset.get() - offset_from_clos_end
}
let offset = if term_ref.scope_offset > 0 {
self.term_clos_offsets.borrow()[self.term_clos_offsets.borrow().len() -
term_ref.scope_offset] -
term_ref.ref_offset
} else {
self.term.borrow().len() - term_ref.ref_offset
};
for &(n, ref map) in self.overlays.borrow().iter().rev() {
if n < offset {
if n <= offset {
break;
}
if let Some(binding) = map.get(&offset) {
......@@ -106,13 +119,12 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
}
pub fn match_term(&self, term_ref: TermRef, current: &ATermRef<'f>) -> Result<()> {
let offset = match term_ref {
TermRef::Local(offset_from_end) => {
self.term.borrow().len() - offset_from_end
}
TermRef::Closure(offset_from_clos_end) => {
self.term_clos_offset.get() - offset_from_clos_end
}
let offset = if term_ref.scope_offset > 0 {
self.term_clos_offsets.borrow()[self.term_clos_offsets.borrow().len() -
term_ref.scope_offset] -
term_ref.ref_offset
} else {
self.term.borrow().len() - term_ref.ref_offset
};
self.match_term_offset(offset, current)
}
......@@ -121,7 +133,7 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
let mut overlay_active = false;
for &(n, ref map) in self.overlays.borrow().iter().rev() {
if n < offset {
if n <= offset {
break;
}
overlay_active = true;
......@@ -163,12 +175,9 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
{
let term_len = self.term.borrow().len();
let strat_len = self.strategy.borrow().len();
if !term_scope.is_empty() {
self.term.borrow_mut().extend_from_slice(&term_scope);
}
if !strat_scope.is_empty() {
self.strategy.borrow_mut().extend_from_slice(&strat_scope);
}
self.term.borrow_mut().extend_from_slice(&term_scope);
self.strategy.borrow_mut().extend_from_slice(&strat_scope);
let result = body();
......@@ -183,9 +192,8 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
F: FnOnce() -> Result<ATermRef<'f>>,
{
let term_len = self.term.borrow().len();
if !term_scope.is_empty() {
self.term.borrow_mut().extend_from_slice(&term_scope);
}
self.term.borrow_mut().extend_from_slice(&term_scope);
let result = body();
......@@ -203,9 +211,8 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
F: FnOnce() -> Result<ATermRef<'f>>,
{
let strat_len = self.strategy.borrow().len();
if !strat_scope.is_empty() {
self.strategy.borrow_mut().extend_from_slice(&strat_scope);
}
self.strategy.borrow_mut().extend_from_slice(&strat_scope);
let result = body();
......@@ -236,7 +243,8 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
"apply_overlay: Interpreter bug, unexpected end of stack",
);
debug_assert_eq!(
self.term.borrow().len(), offset,
self.term.borrow().len(),
offset,
"apply_overlay: Interpreter bug, unexpected normal scope"
);
self.apply_overlay_internal(map);
......@@ -247,7 +255,8 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
"drop_overlay: Interpreter bug, unexpected end of stack",
);
debug_assert_eq!(
self.term.borrow().len(), offset,
self.term.borrow().len(),
offset,
"drop_overlay: Interpreter bug, unexpected normal scope"
);
}
......@@ -258,7 +267,8 @@ impl<'d, 'f: 'd> MutContext<'d, 'f> {
"clear_overlay: Interpreter bug, unexpected end of stack",
);
debug_assert_eq!(
self.term.borrow().len(), *offset,
self.term.borrow().len(),
*offset,
"clear_overlay: Interpreter bug, unexpected normal scope"
);
map.clear();
......@@ -321,8 +331,8 @@ pub mod Scope {
}
pub fn from_let_defs<'d, 'f: 'd, I>(
term_scope_offset: usize,
strat_scope_offset: usize,
term_scope_offset: Vec<usize>,
strat_scope_offset: Vec<usize>,
defs: I,
) -> StrategyScope<'d, 'f>
where
......@@ -330,7 +340,11 @@ pub mod Scope {
{
defs.into_iter()
.map(|def| {
StrategyDef::from_let_def(def, term_scope_offset, strat_scope_offset)
StrategyDef::from_let_def(
def,
term_scope_offset.clone(),
strat_scope_offset.clone(),
)
})
.collect()
}
......
......@@ -159,7 +159,7 @@ impl<'s> TermList<'s> {
pub fn with_tail(&self, tail: Rc<Self>) -> Rc<Self> {
match *self {
TermList::Nil => tail,
TermList::Cons(ref h, ref t) => Rc::new(TermList::Cons(h.clone(), t.with_tail(tail)))
TermList::Cons(ref h, ref t) => Rc::new(TermList::Cons(h.clone(), t.with_tail(tail))),
}
}
}
......@@ -493,7 +493,7 @@ impl<'s> ATermFactory {
{
use aterm::utils::extend_lifetime_mut;
let mut string_cache = unsafe { extend_lifetime_mut(&mut self.string_cache.borrow_mut()) };
let string_cache = unsafe { extend_lifetime_mut(&mut self.string_cache.borrow_mut()) };
string_cache.insert(string.into().as_ref())
}
}
......
......@@ -5,6 +5,7 @@ use preprocess::ir_v1;
use preprocess::ir_v2;
use preprocess::ir_v2::StrategyDef;
use primitives::Primitives;
use io::StaticInfoTuple;
use aterm::{ATerm as A, ATermFactory as ATF};
use aterm::BrokenF32;
......@@ -18,6 +19,7 @@ use std::result;
#[derive(Debug)]
pub struct TracedError(pub Error, pub String);
#[derive(Default)]
pub struct Libraries<'f> {
libs: Vec<ATermRef<'f>>,
prims: Vec<&'static Primitives>,
......@@ -42,10 +44,10 @@ impl From<::std::fmt::Error> for TracedError {
}
}
impl<'f> iter::FromIterator<(ATermRef<'f>, Option<&'static Primitives>, Option<Vec<ir_v1::Def<'f>>>)> for Libraries<'f> {
impl<'f> iter::FromIterator<StaticInfoTuple<'f>> for Libraries<'f> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = (ATermRef<'f>, Option<&'static Primitives>, Option<Vec<ir_v1::Def<'f>>>)>,
T: IntoIterator<Item = StaticInfoTuple<'f>>,
{
let mut libs = Libraries {
libs: Vec::new(),
......@@ -93,27 +95,30 @@ pub fn interpret<'f>(
use ctree::match_;
use std::iter;
let program = match match_(&program).and_then(ir_v1::preprocess) {
Ok(v) => v,
Err(e) => return Err(TracedError(e, String::new())),
};
let defs = match libraries
.libs
.into_iter()
.chain(iter::once(program))
.map(|l| match_(&l).and_then(ir_v1::preprocess))
.chain(iter::once(Ok(program)))
.collect::<Result<Vec<_>>>() {
Ok(v) => v,
Err(e) => return Err(TracedError(e, String::new())),
};
let flat_defs: Vec<_> = defs.into_iter().flat_map(|v| v).chain(libraries.overrides).collect();
let flat_defs: Vec<_> = defs.into_iter()
.flat_map(|v| v)
.chain(libraries.overrides)
.collect();
let (flat_defs, strat_ref) = ir_v2::from_v1(flat_defs, strategy);
let context = MutContext::new(factory, Scope::from_defs(&flat_defs), libraries.prims);
let main = match context.get_strategy(strat_ref) {
Ok(v) => {
debug_assert_eq!(v.name(), "main_0_0", "Interpreter bug, main strategy lookup failed");
debug_assert_eq!(
v.name(),
"main_0_0",
"Interpreter bug, main strategy lookup failed"
);
v
},
}
Err(e) => {
return Err(TracedError(
e,
......@@ -139,30 +144,20 @@ impl<'d, 'f: 'd> Eval<'d, 'f> for ir_v2::Strategy<'f> {
fn eval(&'d self, context: &MutContext<'d, 'f>, current: ATermRef<'f>) -> Result<ATermRef<'f>> {
use preprocess::ir_v2::Strategy::*;
// eprintln!("Current: {:?}", self);
match *self {
Let(ref defs, ref body) => {
use context::Scope;
let term_scope_offset = context.term.borrow().len();
// note the + 1, because `let`s allow recursive definitions
let strat_scope_offset = context.strategy.borrow().len() + 1;
let (term_scope_offsets, strat_scope_offsets) = context.make_let_clos_offsets(defs.len());
let scope =
Scope::from_let_defs(term_scope_offset, strat_scope_offset, defs.iter());
Scope::from_let_defs(term_scope_offsets, strat_scope_offsets, defs.iter());
context.in_strategy_scope(scope, || body.eval(context, current))
}
CallT(strat_name, strat_ref, ref sargs, ref targs) => {
CallT(strat_ref, ref sargs, ref targs) => {
let sdeft = context.get_strategy(strat_ref)?;
if let Option::Some(sdeft_name) = sdeft.real_name() {
eprintln!("Calling: {}", sdeft_name);
debug_assert_eq!(sdeft_name, strat_name, "Interpreter bug, get_strategy fail (got us left)");
} else {
eprintln!("Calling: {}", strat_name);
}
// TODO: convert to name with name map once added
let strat_name = context.factory.intern_string(strat_name);
let strat_name = context.factory.intern_string(sdeft.name());
let sargs = sargs
.into_iter()
.enumerate()
......@@ -174,9 +169,7 @@ impl<'d, 'f: 'd> Eval<'d, 'f> for ir_v2::Strategy<'f> {
.into_iter()
.map(|term| build_term::build(term, context))
.collect::<Result<_>>()?;
let result = eval_sdef(&sdeft, context, sargs, targs, current);
eprintln!("Returning");
result
eval_sdef(&sdeft, context, sargs, targs, current)
}
CallDynamic(term_ref, ref _sargs, ref _targs) => {
let strategy_name = context.get_term(term_ref)?;
......@@ -702,25 +695,34 @@ pub fn eval_sdef<'d, 'f: 'd>(
actual_targs: Vec<ATermRef<'f>>,
current: ATermRef<'f>,
) -> Result<ATermRef<'f>> {
use std::mem;
let name = strategy_def.name();
if !strategy_def.matching_counts(actual_sargs.len(), actual_targs.len()) {
Err(Error::UndefinedStrategy(format!("Strategy {} was called with wrong number of arguments {},{}", name, actual_sargs.len(), actual_targs.len())))
Err(Error::UndefinedStrategy(format!(
"Strategy {} was called with wrong number of arguments {},{}",
name,
actual_sargs.len(),
actual_targs.len()
)))
} else {
eprintln!("SDef scope offsets: {:?}", strategy_def.scope_offsets());
context.stack_tracer.borrow_mut().push(name);
let result = context.in_scope(strategy_def.build_scope(actual_sargs, actual_targs), || {
let old_term_clos_offset = context.term_clos_offset.get();
let old_strategy_clos_offset = context.strategy_clos_offset.get();
let (term_clos_offset, strategy_clos_offset) = strategy_def.scope_offsets();
context.term_clos_offset.set(term_clos_offset);
context.strategy_clos_offset.set(strategy_clos_offset);
let (mut term_clos_offsets, mut strategy_clos_offsets) = strategy_def.scope_offsets();
mem::swap(
&mut term_clos_offsets,
&mut *context.term_clos_offsets.borrow_mut(),
);
mem::swap(
&mut strategy_clos_offsets,
&mut *context.strategy_clos_offsets.borrow_mut(),
);
let result = strategy_def.body().eval(context, current);
context.term_clos_offset.set(old_term_clos_offset);
context.strategy_clos_offset.set(old_strategy_clos_offset);
*context.term_clos_offsets.borrow_mut() = term_clos_offsets;
*context.strategy_clos_offsets.borrow_mut() = strategy_clos_offsets;
result
});
......@@ -741,16 +743,14 @@ pub fn strategy_def_from_strategy<'d, 'f: 'd>(
body: &'d ir_v2::Strategy<'f>,
) -> Result<StrategyDef<'d, 'f>> {
use preprocess::ir_v2::Strategy;
let term_scope_offset = context.term.borrow().len();
let strat_scope_offset = context.strategy.borrow().len();
// NOTE: this is not an optimisation but a necessary semantic distinction to allow
// strategies that take arguments to be passed as strategy arguments!
let (term_scope_offsets, strat_scope_offsets) = context.make_clos_offsets();
match *body {
Strategy::CallT(strat_name, strat_ref, ref sargs, ref targs) if sargs.is_empty() && targs.is_empty() => {
// NOTE: this is not an optimisation but a necessary semantic distinction to allow
// strategies that take arguments to be passed as strategy arguments!
Strategy::CallT(strat_ref, ref sargs, ref targs)
if sargs.is_empty() && targs.is_empty() =>
{
let sdeft = context.get_strategy(strat_ref)?;
if let Some(sdeft_name) = sdeft.real_name() {
debug_assert_eq!(sdeft_name, strat_name, "Interpreter bug, get_strategy fail (got us left)");
}
Ok(sdeft)
}
_ => {
......@@ -758,10 +758,10 @@ pub fn strategy_def_from_strategy<'d, 'f: 'd>(
format!("{}.{}", name, number),
);
Ok(StrategyDef::Anonymous {
artificial_name: artificial_name,
body: body,
term_scope_offset: term_scope_offset,
strat_scope_offset: strat_scope_offset,
artificial_name,
body,
term_scope_offsets,
strat_scope_offsets,
})
}
}
......
......@@ -12,6 +12,8 @@ use primitives::Primitives;
use preprocess::ir_v1::Def;
use overrides;
pub type StaticInfoTuple<'f> = (ATermRef<'f>, Option<&'static Primitives>, Option<Vec<Def<'f>>>);
pub fn read_input<P: AsRef<Path>>(path: &P) -> io::Result<String> {
let mut ctree = String::new();
let path = path.as_ref();
......@@ -33,10 +35,14 @@ pub fn read_lib<'f>(
f: &'f ATermFactory,
str_path: &Path,
path: &str,
) -> Result<(ATermRef<'f>, Option<&'static Primitives>, Option<Vec<Def<'f>>>)> {
) -> Result<StaticInfoTuple<'f>> {
let defs = overrides::get(path, f);
if let Some(&(path, prim)) = primitives::LIBS.get(path) {
Ok((read_aterm(f, &Path::new(&str_path).join(path))?, prim, defs))
Ok((
read_aterm(f, &Path::new(&str_path).join(path))?,
prim,
defs,
))
} else {
Ok((read_aterm(f, &Path::new(path))?, None, defs))
}
......
......@@ -16,20 +16,28 @@ const SRTS_EXT_NAMES: [(&'static str, usize, usize); 10] = [
pub fn get<'f>(path: &str, f: &'f ATermFactory) -> Option<Vec<Def<'f>>> {
if path == "libstratego-lib" {
Some(SRTS_EXT_NAMES.iter().map(|&(n, s, t)| {
let n = f.intern_string(n);
let sargs: Vec<_> = (0..s).map(|n| f.intern_string(n.to_string())).collect();
let targs: Vec<_> = (0..t).map(|n| f.intern_string(n.to_string())).collect();
let prim_sargs = sargs.iter().map(|&n| Strategy::CallT(n, Vec::new(), Vec::new())).collect();
let prim_targs = targs.iter().map(|&n| BuildTerm::Var(n)).collect();
Def {
name: n,
sargs: sargs,
targs: targs,
body: Strategy::PrimT(n, prim_sargs, prim_targs),
}
}).collect())
Some(
SRTS_EXT_NAMES
.iter()
.map(|&(n, s, t)| {
let n = f.intern_string(n);
let sargs: Vec<_> = (0..s).map(|n| f.intern_string(n.to_string())).collect();
let targs: Vec<_> = (0..t).map(|n| f.intern_string(n.to_string())).collect();
let prim_sargs = sargs
.iter()
.map(|&n| Strategy::CallT(n, Vec::new(), Vec::new()))
.collect();
let prim_targs = targs.iter().map(|&n| BuildTerm::Var(n)).collect();
Def {
name: n,
sargs: sargs,
targs: targs,
body: Strategy::PrimT(n, prim_sargs, prim_targs),
}
})
.collect(),
)
} else {
None
}
}
\ No newline at end of file
}
......@@ -49,10 +49,10 @@ impl<'a> TryFrom<ctree::Def<'a>> for Def<'a> {
ctree::Def::SDefT(name, sargs, targs, body) => {
body.try_into().map(|body| {
Def {
name: name,
name,
sargs: sargs.into_iter().map(|vardec| vardec.0).collect(),
targs: targs.into_iter().map(|vardec| vardec.0).collect(),
body: body,
body,
}
})
}
......
This diff is collapsed.
......@@ -9,9 +9,7 @@ pub struct SrtsExtState {
impl SrtsExtState {
pub fn new() -> Self {
SrtsExtState {
new_counter: 0,
}
SrtsExtState { new_counter: 0 }
}
}
......@@ -67,4 +65,4 @@ primitive!(SRTS_EXT_repeat_1_0, 1, 0, (context, sargs, current) => {
primitive!(SRTS_EXT_string_replace_0_2, 2, (context, targs, current) => {
unimplemented!()
});
\ No newline at end of file
});
......@@ -8,13 +8,6 @@ use aterm::string_share::InternedString;
use fnv::FnvHashMap;
macro_rules! eprintln {
($($tt:tt)*) => {{
use std::io::{Write, stderr};
writeln!(&mut stderr(), $($tt)*).unwrap();
}}
}
pub struct StringState<'s> {
new_alphacounter: u8,
new_counter: u16,
......@@ -121,7 +114,7 @@ primitive!(newname, 1, (context, targs, current) => {
Term::String(s) |
Term::Application(s, _) => {
let mut ssl_state = context.ssl_state.borrow_mut();
let mut counter = ssl_state.string.newname_counters.entry(s).or_insert(0);
let counter = ssl_state.string.newname_counters.entry(s).or_insert(0);
let result = format!("{}{}", s, counter);
*counter += 1;
// TODO: extend factory to provide unique_string which fails if the string was built before.
......
......@@ -12,13 +12,6 @@ use std::io;
use std::fmt;
use std::error::Error as StdError;
macro_rules! eprintln {
($($tt:tt)*) => {{
use std::io::{Write, stderr};
writeln!(&mut stderr(), $($tt)*).unwrap();
}}
}
pub struct SysState {
working_dir: PathBuf,
open_files: Vec<Option<File>>,
......
......@@ -4,7 +4,7 @@ extern crate aterm;
use strs::io;
use strs::error::{Error, Result};
use strs::factory::ATermFactory;
use strs::interpreter::{TracedError, interpret_main};
use strs::interpreter::{TracedError, Libraries, interpret_main};
use aterm::print::ATermWrite;
......