}
}
+impl fmt::Display for EvalError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ &EvalError::QueryFailure => write!(f, "false."),
+ &EvalError::QueryFailureWithException(ref e) => write!(f, "{}", error_string(e)),
+ &EvalError::ImpermissibleEntry(ref msg) => write!(f, "cannot overwrite builtin {}", msg),
+ &EvalError::OpIsInfixAndPostFix =>
+ write!(f, "cannot define an op to be both postfix and infix."),
+ &EvalError::NamelessEntry => write!(f, "the predicate head is not an atom or clause."),
+ &EvalError::ParserError(ref e) => write!(f, "{:?}", e)
+ }
+ }
+}
+
impl fmt::Display for ArithmeticTerm {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
worker.parse_code(buffer)
}
+pub fn parse_batch(wam: &mut Machine, buffer: &str) -> Result<Vec<TopLevelPacket>, ParserError>
+{
+ let mut worker = TopLevelWorker::new(wam.atom_tbl(), wam.op_dir());
+ worker.parse_batch(buffer)
+}
+
pub fn read() -> String {
let _ = stdout().flush();
fn set_first_index(code: &mut Code)
{
let code_len = code.len();
-
+
for (idx, line) in code.iter_mut().enumerate() {
match line {
&mut Line::Control(ControlInstruction::JmpByExecute(_, ref mut offset))
-> Result<(Code, AllocVarDict<'a>), ParserError>
{
let mut cg = CodeGenerator::<DebrayAllocator>::new();
- let mut code = try!(cg.compile_query(terms));
-
+ let mut code = try!(cg.compile_query(terms));
+
compile_appendix(&mut code, queue)?;
Ok((code, cg.take_vars()))
}
-pub fn compile<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevelPacket) -> EvalSession<'b>
+fn compile_decl<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel, queue: &'b Vec<TopLevel>)
+ -> EvalSession<'b>
{
match tl {
- &TopLevelPacket::Query(ref terms, ref queue) =>
- match compile_query(terms, queue) {
- Ok((code, vars)) => wam.submit_query(code, vars),
- Err(e) => EvalSession::from(e)
- },
- &TopLevelPacket::Decl(TopLevel::Declaration(ref decl), _) =>
- wam.submit_decl(decl),
- &TopLevelPacket::Decl(ref tl, ref queue) => {
+ &TopLevel::Declaration(ref decl) => wam.submit_decl(decl),
+ _ => {
let mut code = match compile_relation(tl) {
Ok(code) => code,
- Err(e) => return EvalSession::ParserError(e)
+ Err(e) => return EvalSession::from(EvalError::ParserError(e))
};
if let Err(e) = compile_appendix(&mut code, queue) {
if let Some(name) = tl.name() {
wam.add_user_code(name, tl.arity(), code)
} else {
- EvalSession::NamelessEntry
+ EvalSession::from(EvalError::NamelessEntry)
}
} else {
- EvalSession::ImpermissibleEntry(String::from("no code generated."))
+ EvalSession::from(EvalError::ImpermissibleEntry(String::from("no code generated.")))
}
}
}
}
+pub fn compile<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevelPacket) -> EvalSession<'b>
+{
+ match tl {
+ &TopLevelPacket::Query(ref terms, ref queue) =>
+ match compile_query(terms, queue) {
+ Ok((code, vars)) => wam.submit_query(code, vars),
+ Err(e) => EvalSession::from(e)
+ },
+ &TopLevelPacket::Decl(ref tl, ref queue) =>
+ compile_decl(wam, tl, queue)
+ }
+}
+
+pub fn compile_batch<'a, 'b: 'a>(wam: &'a mut Machine, tls: &'b Vec<TopLevelPacket>)
+ -> EvalSession<'b>
+{
+ for tl in tls {
+ match tl {
+ &TopLevelPacket::Query(..) =>
+ return EvalSession::from(ParserError::ExpectedRel),
+ &TopLevelPacket::Decl(ref tl, ref queue) => {
+ let result = compile_decl(wam, tl, queue);
+
+ if let &EvalSession::Error(_) = &result {
+ return result;
+ }
+ }
+ }
+ }
+
+ EvalSession::EntrySuccess
+}
+
fn error_string(e: &String) -> String {
format!("error: exception thrown: {}", e)
}
}
loop {
- let mut result = EvalSession::QueryFailure;
+ let mut result = EvalSession::from(EvalError::QueryFailure);
let mut output = PrinterOutputter::new();
let bindings = wam.heap_view(&heap_locs, output).result();
}
}
- if let &EvalSession::QueryFailure = &result {
+ if let &EvalSession::Error(EvalError::QueryFailure) = &result
+ {
write!(stdout, "false.\n\r").unwrap();
stdout.flush().unwrap();
return;
}
- if let &EvalSession::QueryFailureWithException(ref e) = &result {
+ if let &EvalSession::Error(EvalError::QueryFailureWithException(ref e)) = &result
+ {
write!(stdout, "{}\n\r", error_string(e)).unwrap();
stdout.flush().unwrap();
return;
write!(stdout(), ".\n").unwrap();
},
- EvalSession::QueryFailure => println!("false."),
- EvalSession::QueryFailureWithException(e) => println!("{}", error_string(&e)),
- EvalSession::ImpermissibleEntry(msg) => println!("cannot overwrite builtin {}", msg),
- EvalSession::OpIsInfixAndPostFix => println!("cannot define an op to be both postfix and infix."),
- EvalSession::NamelessEntry => println!("the predicate head is not an atom or clause."),
- EvalSession::ParserError(e) => println!("{:?}", e),
+ EvalSession::Error(e) => println!("{}", e),
_ => {}
};
}
impl Machine {
pub fn new() -> Self {
- let atom_tbl = Rc::new(RefCell::new(HashSet::new()));
+ let atom_tbl = Rc::new(RefCell::new(HashSet::new()));
let (code, code_dir, op_dir) = build_code_dir(atom_tbl.clone());
-
+
+
Machine {
ms: machine_state::MachineState::new(atom_tbl),
code,
{
match self.code_dir.get(&(name.clone(), arity)) {
Some(&(PredicateKeyType::BuiltIn, _)) =>
- return EvalSession::ImpermissibleEntry(format!("{}/{}", name, arity)),
+ return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", name, arity))),
_ => {}
};
self.code.append(&mut code);
self.code_dir.insert((name, arity), (PredicateKeyType::User, offset));
-
+
EvalSession::EntrySuccess
}
},
_ => {}
}
-
+
self.ms.p = CodePtr::TopLevel(cn, p);
}
TermFormatter {},
PrinterOutputter::new())
.result();
-
- EvalSession::QueryFailureWithException(msg)
+
+ EvalSession::from(EvalError::QueryFailureWithException(msg))
} else {
- EvalSession::QueryFailure
+ EvalSession::from(EvalError::QueryFailure)
}
}
&Declaration::Op(prec, spec, ref name) => {
if is_infix!(spec) {
match self.op_dir.get(&(name.clone(), Fixity::Post)) {
- Some(_) => return EvalSession::OpIsInfixAndPostFix,
+ Some(_) => return EvalSession::from(EvalError::OpIsInfixAndPostFix),
_ => {}
};
}
if is_postfix!(spec) {
match self.op_dir.get(&(name.clone(), Fixity::In)) {
- Some(_) => return EvalSession::OpIsInfixAndPostFix,
+ Some(_) => return EvalSession::from(EvalError::OpIsInfixAndPostFix),
_ => {}
};
}
self.ms.p = self.ms.or_stack[b].bp;
if let CodePtr::TopLevel(_, 0) = self.ms.p {
- return EvalSession::QueryFailure;
+ return EvalSession::from(EvalError::QueryFailure);
}
self.run_query(alloc_l, heap_l);
EvalSession::SubsequentQuerySuccess
}
} else {
- EvalSession::QueryFailure
+ EvalSession::from(EvalError::QueryFailure)
}
}
{
for (var, addr) in var_dir {
output.begin_new_var();
-
+
output.append(var.as_str());
output.append(" = ");
-
+
output = self.ms.print_term(addr.clone(), TermFormatter {}, output);
}