correct module bugs
This commit is contained in:
11
README.md
11
README.md
@@ -251,4 +251,15 @@ been exported to the toplevel. To export them, write
|
|||||||
```
|
```
|
||||||
prolog> :- use_module(library(lists)).
|
prolog> :- use_module(library(lists)).
|
||||||
prolog> :- use_module(library(control)).
|
prolog> :- use_module(library(control)).
|
||||||
|
```
|
||||||
|
|
||||||
|
To define modules inline at the REPL, use the ":{{"\"}}:" delimiters:
|
||||||
|
|
||||||
|
```
|
||||||
|
prolog> :{{
|
||||||
|
:- module(test, [local_member/2]).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
|
||||||
|
local_member(X, Xs) :- member(X, Xs).
|
||||||
|
}}:
|
||||||
```
|
```
|
||||||
24
src/main.rs
24
src/main.rs
@@ -15,7 +15,7 @@ mod tests;
|
|||||||
pub static LISTS: &str = include_str!("./prolog/lib/lists.pl");
|
pub static LISTS: &str = include_str!("./prolog/lib/lists.pl");
|
||||||
pub static CONTROL: &str = include_str!("./prolog/lib/control.pl");
|
pub static CONTROL: &str = include_str!("./prolog/lib/control.pl");
|
||||||
|
|
||||||
fn process_buffer(wam: &mut Machine, buffer: &str)
|
fn parse_and_compile_line(wam: &mut Machine, buffer: &str)
|
||||||
{
|
{
|
||||||
match parse_code(wam, buffer) {
|
match parse_code(wam, buffer) {
|
||||||
Ok(packet) => {
|
Ok(packet) => {
|
||||||
@@ -39,20 +39,22 @@ fn prolog_repl() {
|
|||||||
|
|
||||||
load_init_str(&mut wam, LISTS);
|
load_init_str(&mut wam, LISTS);
|
||||||
load_init_str(&mut wam, CONTROL);
|
load_init_str(&mut wam, CONTROL);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
print!("prolog> ");
|
print!("prolog> ");
|
||||||
|
|
||||||
let buffer = read();
|
match read() {
|
||||||
|
Input::Line(line) => parse_and_compile_line(&mut wam, line.as_str()),
|
||||||
|
Input::Batch(batch) => {
|
||||||
|
compile_listing(&mut wam, batch.as_str());
|
||||||
|
},
|
||||||
|
Input::Quit => break,
|
||||||
|
Input::Clear => {
|
||||||
|
wam.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if buffer == "quit\n" {
|
|
||||||
break;
|
|
||||||
} else if buffer == "clear\n" {
|
|
||||||
wam.clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
process_buffer(&mut wam, buffer.as_str());
|
|
||||||
wam.reset();
|
wam.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,18 +133,12 @@ impl PredicateClause {
|
|||||||
|
|
||||||
pub type OpDirKey = (ClauseName, Fixity);
|
pub type OpDirKey = (ClauseName, Fixity);
|
||||||
// name and fixity -> operator type and precedence.
|
// name and fixity -> operator type and precedence.
|
||||||
pub type OpDir = HashMap<OpDirKey, (Specifier, usize)>;
|
pub type OpDir = HashMap<OpDirKey, (Specifier, usize, ClauseName)>;
|
||||||
|
|
||||||
pub type CodeDir = HashMap<PredicateKey, (PredicateKeyType, usize, ClauseName)>;
|
pub type CodeDir = HashMap<PredicateKey, (usize, ClauseName)>;
|
||||||
|
|
||||||
pub type PredicateKey = (ClauseName, usize); // name, arity.
|
pub type PredicateKey = (ClauseName, usize); // name, arity.
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
|
||||||
pub enum PredicateKeyType {
|
|
||||||
BuiltIn,
|
|
||||||
User
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ModuleDecl {
|
pub struct ModuleDecl {
|
||||||
pub name: ClauseName,
|
pub name: ClauseName,
|
||||||
pub exports: Vec<PredicateKey>
|
pub exports: Vec<PredicateKey>
|
||||||
@@ -377,7 +371,7 @@ impl From<ParserError> for EvalSession {
|
|||||||
pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
|
pub struct OpDecl(pub usize, pub Specifier, pub ClauseName);
|
||||||
|
|
||||||
impl OpDecl {
|
impl OpDecl {
|
||||||
pub fn submit(&self, op_dir: &mut OpDir) -> Result<(), EvalError>
|
pub fn submit(&self, module: ClauseName, op_dir: &mut OpDir) -> Result<(), EvalError>
|
||||||
{
|
{
|
||||||
let (prec, spec, name) = (self.0, self.1, self.2.clone());
|
let (prec, spec, name) = (self.0, self.1, self.2.clone());
|
||||||
|
|
||||||
@@ -398,9 +392,9 @@ impl OpDecl {
|
|||||||
if prec > 0 {
|
if prec > 0 {
|
||||||
match spec {
|
match spec {
|
||||||
XFY | XFX | YFX => op_dir.insert((name.clone(), Fixity::In),
|
XFY | XFX | YFX => op_dir.insert((name.clone(), Fixity::In),
|
||||||
(spec, prec)),
|
(spec, prec, module.clone())),
|
||||||
XF | YF => op_dir.insert((name.clone(), Fixity::Post), (spec, prec)),
|
XF | YF => op_dir.insert((name.clone(), Fixity::Post), (spec, prec, module.clone())),
|
||||||
FX | FY => op_dir.insert((name.clone(), Fixity::Pre), (spec,prec)),
|
FX | FY => op_dir.insert((name.clone(), Fixity::Pre), (spec, prec, module.clone())),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -628,154 +628,150 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
|
|||||||
{
|
{
|
||||||
let mut code_dir = HashMap::new();
|
let mut code_dir = HashMap::new();
|
||||||
let mut op_dir = HashMap::new();
|
let mut op_dir = HashMap::new();
|
||||||
|
|
||||||
op_dir.insert((clause_name!(":-"), Fixity::In), (XFX, 1200));
|
let builtin = ClauseName::BuiltIn("builtin");
|
||||||
op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX, 1200));
|
|
||||||
op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX, 1200));
|
op_dir.insert((clause_name!(":-"), Fixity::In), (XFX, 1200, builtin.clone()));
|
||||||
|
op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX, 1200, builtin.clone()));
|
||||||
|
op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX, 1200, builtin.clone()));
|
||||||
|
|
||||||
// control operators.
|
// control operators.
|
||||||
op_dir.insert((clause_name!("\\+"), Fixity::Pre), (FY, 900));
|
op_dir.insert((clause_name!("\\+"), Fixity::Pre), (FY, 900, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
|
|
||||||
// arithmetic operators.
|
// arithmetic operators.
|
||||||
op_dir.insert((clause_name!("is"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("is"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("+"), Fixity::In), (YFX, 500));
|
op_dir.insert((clause_name!("+"), Fixity::In), (YFX, 500, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("-"), Fixity::In), (YFX, 500));
|
op_dir.insert((clause_name!("-"), Fixity::In), (YFX, 500, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("/\\"), Fixity::In), (YFX, 500));
|
op_dir.insert((clause_name!("/\\"), Fixity::In), (YFX, 500, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("\\/"), Fixity::In), (YFX, 500));
|
op_dir.insert((clause_name!("\\/"), Fixity::In), (YFX, 500, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("xor"), Fixity::In), (YFX, 500));
|
op_dir.insert((clause_name!("xor"), Fixity::In), (YFX, 500, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("div"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("div"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("*"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("*"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("-"), Fixity::Pre), (FY, 200));
|
op_dir.insert((clause_name!("-"), Fixity::Pre), (FY, 200, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("rdiv"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("rdiv"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("<<"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("<<"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!(">>"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!(">>"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("mod"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("mod"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("rem"), Fixity::In), (YFX, 400));
|
op_dir.insert((clause_name!("rem"), Fixity::In), (YFX, 400, builtin.clone()));
|
||||||
|
|
||||||
// arithmetic comparison operators.
|
// arithmetic comparison operators.
|
||||||
op_dir.insert((clause_name!(">"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!(">"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("<"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("<"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("=\\="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=\\="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("=:="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=:="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!(">="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!(">="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("=<"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=<"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
|
|
||||||
// control operators.
|
// control operators.
|
||||||
op_dir.insert((clause_name!(";"), Fixity::In), (XFY, 1100));
|
op_dir.insert((clause_name!(";"), Fixity::In), (XFY, 1100, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("->"), Fixity::In), (XFY, 1050));
|
op_dir.insert((clause_name!("->"), Fixity::In), (XFY, 1050, builtin.clone()));
|
||||||
|
|
||||||
op_dir.insert((clause_name!("=.."), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=.."), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("=="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("\\=="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("\\=="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("@=<"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("@=<"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("@>="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("@>="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("@<"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("@<"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("@>"), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("@>"), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("=@="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("=@="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
op_dir.insert((clause_name!("\\=@="), Fixity::In), (XFX, 700));
|
op_dir.insert((clause_name!("\\=@="), Fixity::In), (XFX, 700, builtin.clone()));
|
||||||
|
|
||||||
let builtin = ClauseName::BuiltIn("builtin");
|
|
||||||
|
|
||||||
// there are 63 registers in the VM, so call/N is defined for all 0 <= N <= 62
|
// there are 63 registers in the VM, so call/N is defined for all 0 <= N <= 62
|
||||||
// (an extra register is needed for the predicate name)
|
// (an extra register is needed for the predicate name)
|
||||||
for arity in 0 .. 63 {
|
for arity in 0 .. 63 {
|
||||||
code_dir.insert((clause_name!("call"), arity),
|
code_dir.insert((clause_name!("call"), arity), (0, builtin.clone()));
|
||||||
(PredicateKeyType::BuiltIn, 0, builtin.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
code_dir.insert((clause_name!("atomic"), 1),
|
code_dir.insert((clause_name!("atomic"), 1), (1, builtin.clone()));
|
||||||
(PredicateKeyType::BuiltIn, 1, builtin.clone()));
|
code_dir.insert((clause_name!("var"), 1), (3, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("var"), 1),
|
code_dir.insert((clause_name!("false"), 0), (61, builtin.clone()));
|
||||||
(PredicateKeyType::BuiltIn, 3, builtin.clone()));
|
|
||||||
code_dir.insert((clause_name!("false"), 0),
|
|
||||||
(PredicateKeyType::BuiltIn, 61, builtin.clone()));
|
|
||||||
code_dir.insert((clause_name!("\\+"), 1),
|
code_dir.insert((clause_name!("\\+"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 62, builtin.clone()));
|
(62, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("duplicate_term"), 2),
|
code_dir.insert((clause_name!("duplicate_term"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 71, builtin.clone()));
|
(71, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("catch"), 3),
|
code_dir.insert((clause_name!("catch"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 5, builtin.clone()));
|
(5, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("throw"), 1),
|
code_dir.insert((clause_name!("throw"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 59, builtin.clone()));
|
(59, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("="), 2),
|
code_dir.insert((clause_name!("="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 73, builtin.clone()));
|
(73, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("true"), 0),
|
code_dir.insert((clause_name!("true"), 0),
|
||||||
(PredicateKeyType::BuiltIn, 75, builtin.clone()));
|
(75, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!(","), 2),
|
code_dir.insert((clause_name!(","), 2),
|
||||||
(PredicateKeyType::BuiltIn, 76, builtin.clone()));
|
(76, builtin.clone()));
|
||||||
code_dir.insert((clause_name!(";"), 2),
|
code_dir.insert((clause_name!(";"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 120, builtin.clone()));
|
(120, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("->"), 2),
|
code_dir.insert((clause_name!("->"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 138, builtin.clone()));
|
(138, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!("functor"), 3),
|
code_dir.insert((clause_name!("functor"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 146, builtin.clone()));
|
(146, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("arg"), 3),
|
code_dir.insert((clause_name!("arg"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 150, builtin.clone()));
|
(150, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("integer"), 1),
|
code_dir.insert((clause_name!("integer"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 147, builtin.clone()));
|
(147, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("display"), 1),
|
code_dir.insert((clause_name!("display"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 192, builtin.clone()));
|
(192, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!("is"), 2),
|
code_dir.insert((clause_name!("is"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 194, builtin.clone()));
|
(194, builtin.clone()));
|
||||||
code_dir.insert((clause_name!(">"), 2),
|
code_dir.insert((clause_name!(">"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 196, builtin.clone()));
|
(196, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("<"), 2),
|
code_dir.insert((clause_name!("<"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 198, builtin.clone()));
|
(198, builtin.clone()));
|
||||||
code_dir.insert((clause_name!(">="), 2),
|
code_dir.insert((clause_name!(">="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 200, builtin.clone()));
|
(200, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=<"), 2),
|
code_dir.insert((clause_name!("=<"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 202, builtin.clone()));
|
(202, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=\\="), 2),
|
code_dir.insert((clause_name!("=\\="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 204, builtin.clone()));
|
(204, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=:="), 2),
|
code_dir.insert((clause_name!("=:="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 206, builtin.clone()));
|
(206, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=.."), 2),
|
code_dir.insert((clause_name!("=.."), 2),
|
||||||
(PredicateKeyType::BuiltIn, 208, builtin.clone()));
|
(208, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!("length"), 2),
|
code_dir.insert((clause_name!("length"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 261, builtin.clone()));
|
(261, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("setup_call_cleanup"), 3),
|
code_dir.insert((clause_name!("setup_call_cleanup"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 294, builtin.clone()));
|
(294, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("call_with_inference_limit"), 3),
|
code_dir.insert((clause_name!("call_with_inference_limit"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 393, builtin.clone()));
|
(393, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!("compound"), 1),
|
code_dir.insert((clause_name!("compound"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 372, builtin.clone()));
|
(372, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("rational"), 1),
|
code_dir.insert((clause_name!("rational"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 374, builtin.clone()));
|
(374, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("string"), 1),
|
code_dir.insert((clause_name!("string"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 376, builtin.clone()));
|
(376, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("float"), 1),
|
code_dir.insert((clause_name!("float"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 378, builtin.clone()));
|
(378, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("nonvar"), 1),
|
code_dir.insert((clause_name!("nonvar"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 380, builtin.clone()));
|
(380, builtin.clone()));
|
||||||
|
|
||||||
code_dir.insert((clause_name!("ground"), 1),
|
code_dir.insert((clause_name!("ground"), 1),
|
||||||
(PredicateKeyType::BuiltIn, 384, builtin.clone()));
|
(384, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=="), 2),
|
code_dir.insert((clause_name!("=="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 385, builtin.clone()));
|
(385, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("\\=="), 2),
|
code_dir.insert((clause_name!("\\=="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 386, builtin.clone()));
|
(386, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("@>="), 2),
|
code_dir.insert((clause_name!("@>="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 387, builtin.clone()));
|
(387, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("@=<"), 2),
|
code_dir.insert((clause_name!("@=<"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 388, builtin.clone()));
|
(388, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("@>"), 2),
|
code_dir.insert((clause_name!("@>"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 389, builtin.clone()));
|
(389, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("@<"), 2),
|
code_dir.insert((clause_name!("@<"), 2),
|
||||||
(PredicateKeyType::BuiltIn, 390, builtin.clone()));
|
(390, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("=@="), 2),
|
code_dir.insert((clause_name!("=@="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 391, builtin.clone()));
|
(391, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("\\=@="), 2),
|
code_dir.insert((clause_name!("\\=@="), 2),
|
||||||
(PredicateKeyType::BuiltIn, 392, builtin.clone()));
|
(392, builtin.clone()));
|
||||||
code_dir.insert((clause_name!("compare"), 3),
|
code_dir.insert((clause_name!("compare"), 3),
|
||||||
(PredicateKeyType::BuiltIn, 464, builtin.clone()));
|
(464, builtin.clone()));
|
||||||
|
|
||||||
(code_dir, op_dir)
|
(code_dir, op_dir)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -446,30 +446,43 @@ pub fn parse_code(wam: &Machine, buffer: &str) -> Result<TopLevelPacket, ParserE
|
|||||||
worker.parse_code(&wam.op_dir)
|
worker.parse_code(&wam.op_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read() -> String {
|
pub enum Input {
|
||||||
let _ = stdout().flush();
|
Quit,
|
||||||
|
Clear,
|
||||||
|
Line(String),
|
||||||
|
Batch(String)
|
||||||
|
}
|
||||||
|
|
||||||
let mut buffer = String::new();
|
fn read_lines(buffer: &mut String, end_delim: &str) -> String {
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
|
let stdin = stdin();
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
stdin.read_line(buffer).unwrap();
|
||||||
|
|
||||||
|
while &*buffer.trim() != end_delim {
|
||||||
|
result += buffer.as_str();
|
||||||
|
buffer.clear();
|
||||||
|
stdin.read_line(buffer).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read() -> Input {
|
||||||
|
let _ = stdout().flush();
|
||||||
|
let mut buffer = String::new();
|
||||||
|
|
||||||
let stdin = stdin();
|
let stdin = stdin();
|
||||||
stdin.read_line(&mut buffer).unwrap();
|
stdin.read_line(&mut buffer).unwrap();
|
||||||
|
|
||||||
if &*buffer.trim() == ":{" {
|
match &*buffer.trim() {
|
||||||
buffer.clear();
|
":{" => Input::Line(read_lines(&mut buffer, "}:")),
|
||||||
|
":{{" => Input::Batch(read_lines(&mut buffer, "}}:")),
|
||||||
stdin.read_line(&mut buffer).unwrap();
|
"quit" => Input::Quit,
|
||||||
|
"clear" => Input::Clear,
|
||||||
while &*buffer.trim() != "}:" {
|
_ => Input::Line(buffer)
|
||||||
result += buffer.as_str();
|
|
||||||
buffer.clear();
|
|
||||||
stdin.read_line(&mut buffer).unwrap();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// throw errors if declaration or query found.
|
// throw errors if declaration or query found.
|
||||||
@@ -533,7 +546,7 @@ fn compile_decl(wam: &mut Machine, tl: TopLevel, queue: Vec<TopLevel>) -> EvalSe
|
|||||||
{
|
{
|
||||||
match tl {
|
match tl {
|
||||||
TopLevel::Declaration(Declaration::Op(op_decl)) => {
|
TopLevel::Declaration(Declaration::Op(op_decl)) => {
|
||||||
try_eval_session!(op_decl.submit(&mut wam.op_dir));
|
try_eval_session!(op_decl.submit(clause_name!("user"), &mut wam.op_dir));
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
},
|
},
|
||||||
TopLevel::Declaration(Declaration::UseModule(name)) =>
|
TopLevel::Declaration(Declaration::UseModule(name)) =>
|
||||||
@@ -585,8 +598,10 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
|
|||||||
let mut code = Vec::new();
|
let mut code = Vec::new();
|
||||||
|
|
||||||
let mut worker = TopLevelWorker::new(src_str.as_bytes(), wam.atom_tbl());
|
let mut worker = TopLevelWorker::new(src_str.as_bytes(), wam.atom_tbl());
|
||||||
let tls = try_eval_session!(worker.parse_batch(&mut op_dir));
|
|
||||||
|
|
||||||
|
let tls = try_eval_session!(worker.parse_batch(&mut op_dir));
|
||||||
|
|
||||||
for tl in tls {
|
for tl in tls {
|
||||||
match tl {
|
match tl {
|
||||||
TopLevelPacket::Query(..) =>
|
TopLevelPacket::Query(..) =>
|
||||||
@@ -622,15 +637,14 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession
|
|||||||
try_eval_session!(compile_appendix(&mut decl_code, queue));
|
try_eval_session!(compile_appendix(&mut decl_code, queue));
|
||||||
|
|
||||||
code.extend(decl_code.into_iter());
|
code.extend(decl_code.into_iter());
|
||||||
code_dir.insert((decl.name().unwrap(), decl.arity()),
|
code_dir.insert((decl.name().unwrap(), decl.arity()), (p, get_module_name(&module)));
|
||||||
(PredicateKeyType::User, p, get_module_name(&module)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut module) = module {
|
if let Some(mut module) = module {
|
||||||
module.code_dir = code_dir;
|
module.code_dir.extend(code_dir.into_iter());
|
||||||
module.op_dir = op_dir;
|
module.op_dir.extend(op_dir.into_iter());
|
||||||
|
|
||||||
wam.add_module(module, code);
|
wam.add_module(module, code);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ impl<'a> CodeDirs<'a> {
|
|||||||
-> Option<(usize, ClauseName)>
|
-> Option<(usize, ClauseName)>
|
||||||
{
|
{
|
||||||
let code_dir = self.get_current_code_dir(p);
|
let code_dir = self.get_current_code_dir(p);
|
||||||
code_dir.get(&(name, arity)).map(|idx| (idx.1, idx.2.clone()))
|
code_dir.get(&(name, arity)).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
struct MachineCodeIndex<'a> {
|
struct MachineCodeIndex<'a> {
|
||||||
code_dir: &'a mut CodeDir,
|
code_dir: &'a mut CodeDir,
|
||||||
op_dir: &'a mut OpDir
|
op_dir: &'a mut OpDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
@@ -54,7 +54,7 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> {
|
|||||||
|
|
||||||
fn code_dir(&mut self) -> &mut CodeDir {
|
fn code_dir(&mut self) -> &mut CodeDir {
|
||||||
self.code_dir
|
self.code_dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
@@ -73,7 +73,50 @@ impl Machine {
|
|||||||
cached_query: None
|
cached_query: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_module(&mut self, module_name: ClauseName) {
|
||||||
|
let iter = if let Some(submodule) = self.modules.get(&module_name) {
|
||||||
|
submodule.module_decl.exports.iter().cloned()
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (name, arity) in iter {
|
||||||
|
let name = name.defrock_brackets();
|
||||||
|
|
||||||
|
match self.code_dir.get(&(name.clone(), arity)).cloned() {
|
||||||
|
Some((_, ref mod_name)) if mod_name == &module_name => {
|
||||||
|
self.code_dir.remove(&(name.clone(), arity));
|
||||||
|
|
||||||
|
// remove or respecify ops.
|
||||||
|
if arity == 2 {
|
||||||
|
if let Some((_, _, mod_name)) = self.op_dir.get(&(name.clone(), Fixity::In)).cloned()
|
||||||
|
{
|
||||||
|
if mod_name == module_name {
|
||||||
|
self.op_dir.remove(&(name.clone(), Fixity::In));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if arity == 1 {
|
||||||
|
if let Some((_, _, mod_name)) = self.op_dir.get(&(name.clone(), Fixity::Pre)).cloned()
|
||||||
|
{
|
||||||
|
if mod_name == module_name {
|
||||||
|
self.op_dir.remove(&(name.clone(), Fixity::Pre));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((_, _, mod_name)) = self.op_dir.get(&(name.clone(), Fixity::Post)).cloned()
|
||||||
|
{
|
||||||
|
if mod_name == module_name {
|
||||||
|
self.op_dir.remove(&(name.clone(), Fixity::Post));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn failed(&self) -> bool {
|
pub fn failed(&self) -> bool {
|
||||||
self.ms.fail
|
self.ms.fail
|
||||||
}
|
}
|
||||||
@@ -83,10 +126,13 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_module_in_toplevel(&mut self, name: ClauseName) -> EvalSession {
|
pub fn use_module_in_toplevel(&mut self, name: ClauseName) -> EvalSession {
|
||||||
|
self.remove_module(name.clone());
|
||||||
|
|
||||||
match self.modules.get(&name) {
|
match self.modules.get(&name) {
|
||||||
Some(ref module) => {
|
Some(ref module) => {
|
||||||
let mut indices = MachineCodeIndex { code_dir: &mut self.code_dir,
|
let mut indices = MachineCodeIndex { code_dir: &mut self.code_dir,
|
||||||
op_dir: &mut self.op_dir };
|
op_dir: &mut self.op_dir };
|
||||||
|
|
||||||
indices.use_module(module)
|
indices.use_module(module)
|
||||||
},
|
},
|
||||||
None => EvalSession::from(EvalError::ModuleNotFound)
|
None => EvalSession::from(EvalError::ModuleNotFound)
|
||||||
@@ -114,7 +160,7 @@ impl Machine {
|
|||||||
pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code) -> EvalSession
|
pub fn add_user_code(&mut self, name: ClauseName, arity: usize, code: Code) -> EvalSession
|
||||||
{
|
{
|
||||||
match self.code_dir.get(&(name.clone(), arity)) {
|
match self.code_dir.get(&(name.clone(), arity)) {
|
||||||
Some(&(PredicateKeyType::BuiltIn, _, _)) =>
|
Some(&(_, ref mod_name)) if mod_name == &clause_name!("builtin") =>
|
||||||
return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", name, arity))),
|
return EvalSession::from(EvalError::ImpermissibleEntry(format!("{}/{}", name, arity))),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@@ -122,7 +168,7 @@ impl Machine {
|
|||||||
let offset = self.code.len();
|
let offset = self.code.len();
|
||||||
|
|
||||||
self.code.extend(code.into_iter());
|
self.code.extend(code.into_iter());
|
||||||
self.code_dir.insert((name, arity), (PredicateKeyType::User, offset, clause_name!("user")));
|
self.code_dir.insert((name, arity), (offset, clause_name!("user")));
|
||||||
|
|
||||||
EvalSession::EntrySuccess
|
EvalSession::EntrySuccess
|
||||||
}
|
}
|
||||||
|
|||||||
Submodule src/prolog/parser updated: efb52afa2c...e95c45f411
Reference in New Issue
Block a user