add top level declarative structure

This commit is contained in:
Mark Thom
2017-05-09 16:26:17 -06:00
parent 9c72177b60
commit 6fa5bad5bf
6 changed files with 34 additions and 46 deletions

2
Cargo.lock generated
View File

@@ -1,6 +1,6 @@
[root] [root]
name = "rusty-wam" name = "rusty-wam"
version = "0.6.2" version = "0.6.3"
dependencies = [ dependencies = [
"lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-util 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "rusty-wam" name = "rusty-wam"
version = "0.6.2" version = "0.6.3"
authors = ["Mark Thom"] authors = ["Mark Thom"]
build = "build.rs" build = "build.rs"

View File

@@ -46,11 +46,10 @@ prolog> ?- p(X, Y, Z).
Given the above work, the result of the query will be Given the above work, the result of the query will be
``` ```
prolog> ?- p(X, Y, Z). prolog> ?- p(X, Y, Z).
yes true
X = _0
Y = x Y = x
X = _0
Z = _2 Z = _2
Press ; to continue or . to abort.
``` ```
Pressing ; will backtrack through other possible answers, if any exist. Pressing ; will backtrack through other possible answers, if any exist.
@@ -63,40 +62,29 @@ prolog> :{
member(X, [X|_]). member(X, [X|_]).
member(X, [_|Xs]) :- member(X, Xs). member(X, [_|Xs]) :- member(X, Xs).
}: }:
prolog> ?- member(X, [a, b, c]). prolog> ?- member(X, [a, b, c]).
yes true
X = a X = a ;
Press ; to continue or . to abort. X = b ;
; X = c ;
X = b false.
Press ; to continue or . to abort.
;
X = c
Press ; to continue or . to abort.
;
no
``` ```
and so do conjunctive queries: and so do conjunctive queries:
``` ```
prolog> ?- member([X,X],[a,b,c,[d,d],[e,d]]), member(X, [a,b,c,d,e,f,g]), member(Y, [X, a, b, c, d]). prolog> ?- member([X,X],[a,b,c,[d,d],[e,d]]), member(X, [a,b,c,d,e,f,g]), member(Y, [X, a, b, c, d]).
yes true
Y = d Y = d
X = d X = d ;
Press ; to continue or . to abort.
Y = a Y = a
X = d X = d ;
Press ; to continue or . to abort.
Y = b Y = b
X = d X = d ;
Press ; to continue or . to abort.
Y = c Y = c
X = d X = d ;
Press ; to continue or . to abort.
Y = d Y = d
X = d X = d ;
Press ; to continue or . to abort. false.
no
prolog> prolog>
``` ```
@@ -114,6 +102,6 @@ term to a string results in an infinite loop, ie.
``` ```
prolog> p(W, W). prolog> p(W, W).
prolog> ?- p(f(f(W)), W). prolog> ?- p(f(f(W)), W).
yes true
*loops to infinity* *loops to infinity*
``` ```

View File

@@ -24,7 +24,7 @@ pub enum VarStatus {
} }
// Perm: 0 initially, a stack register once processed. // Perm: 0 initially, a stack register once processed.
// Temp: labeled with chunk_num and temp offset (unassigned if 0), arg (0 if unassigned). // Temp: labeled with chunk_num and temp offset (unassigned if 0).
pub enum VarData { pub enum VarData {
Perm(usize), Temp(usize, usize, TempVarData) Perm(usize), Temp(usize, usize, TempVarData)
} }

View File

@@ -304,49 +304,53 @@ Each predicate must have the same name and arity.";
pub fn print(wam: &mut Machine, result: EvalSession) { pub fn print(wam: &mut Machine, result: EvalSession) {
match result { match result {
EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => { EvalSession::InitialQuerySuccess(alloc_locs, mut heap_locs) => {
println!("yes"); println!("true");
if heap_locs.is_empty() { if heap_locs.is_empty() {
return; return;
} }
'outer: loop { loop {
let mut result = EvalSession::QueryFailure; let mut result = EvalSession::QueryFailure;
let bindings = wam.heap_view(&heap_locs); let bindings = wam.heap_view(&heap_locs);
let stdin = stdin(); let stdin = stdin();
let mut stdout = stdout().into_raw_mode().unwrap(); let mut stdout = stdout().into_raw_mode().unwrap();
write!(stdout, "{}\n\r", bindings).unwrap(); write!(stdout, "{}", bindings).unwrap();
stdout.flush().unwrap(); stdout.flush().unwrap();
if !wam.or_stack_is_empty() { if !wam.or_stack_is_empty() {
write!(stdout, "Press ; to continue or . to abort.\n\r").unwrap();
stdout.flush().unwrap(); stdout.flush().unwrap();
for c in stdin.keys() { for c in stdin.keys() {
match c.unwrap() { match c.unwrap() {
Key::Char(';') => { Key::Char(';') => {
write!(stdout, " ;\n\r").unwrap();
result = wam.continue_query(&alloc_locs, &mut heap_locs); result = wam.continue_query(&alloc_locs, &mut heap_locs);
break; break;
}, },
Key::Char('.') => Key::Char('.') => {
break 'outer, write!(stdout, " .\n\r").unwrap();
return;
},
_ => {} _ => {}
} }
} }
if let &EvalSession::QueryFailure = &result { if let &EvalSession::QueryFailure = &result {
write!(stdout, "no\n\r").unwrap(); write!(stdout, "false.\n\r").unwrap();
stdout.flush().unwrap(); stdout.flush().unwrap();
break; return;
} }
} else { } else {
break; break;
} }
} }
write!(stdout(), ".\n").unwrap();
}, },
EvalSession::QueryFailure => println!("no"), EvalSession::QueryFailure => println!("false."),
_ => {} _ => {}
}; };
} }

View File

@@ -306,10 +306,6 @@ impl Machine {
-> EvalSession -> EvalSession
{ {
if !self.or_stack_is_empty() { if !self.or_stack_is_empty() {
if self.ms.b == 0 {
return EvalSession::QueryFailure;
}
let b = self.ms.b - 1; let b = self.ms.b - 1;
self.ms.p = self.ms.or_stack[b].bp; self.ms.p = self.ms.or_stack[b].bp;
@@ -386,7 +382,7 @@ impl Machine {
} }
pub fn or_stack_is_empty(&self) -> bool { pub fn or_stack_is_empty(&self) -> bool {
self.ms.or_stack.is_empty() self.ms.b == 0
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {