add top level declarative structure
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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)",
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
44
README.md
44
README.md
@@ -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*
|
||||||
```
|
```
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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."),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user