add an atom table.

This commit is contained in:
Mark Thom
2018-01-16 23:26:59 -07:00
parent 38cd9e5db7
commit d8be7b5b49
14 changed files with 276 additions and 181 deletions

View File

@@ -1,10 +1,11 @@
use prolog::ast::*;
use prolog::num::bigint::{BigInt};
use prolog::tabled_rc::*;
use std::collections::HashMap;
use std::rc::Rc;
pub type PredicateKey = (Rc<Atom>, usize); // name, arity, type.
pub type PredicateKey = (TabledRc<Atom>, usize); // name, arity, type.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub enum PredicateKeyType {
@@ -12,13 +13,13 @@ pub enum PredicateKeyType {
User
}
pub type OpDirKey = (Rc<Atom>, Fixity);
pub type OpDirKey = (TabledRc<Atom>, Fixity);
// name and fixity -> operator type and precedence.
pub type OpDir = HashMap<OpDirKey, (Specifier, usize)>;
pub type CodeDir = HashMap<PredicateKey, (PredicateKeyType, usize)>;
fn get_builtins() -> Code {
fn get_builtins(atom_tbl: TabledData<Atom>) -> Code {
vec![internal_call_n!(), // callN/N, 0.
is_atomic!(temp_v!(1)), // atomic/1, 1.
proceed!(),
@@ -114,25 +115,25 @@ fn get_builtins() -> Code {
retry!(7),
trust!(10),
try_me_else!(4),
fact![get_constant!(Constant::from("!"), temp_v!(1)),
get_structure!(String::from(","), 2, temp_v!(2), Some(infix!())),
fact![get_constant!(atom!("!", atom_tbl), temp_v!(1)),
get_structure!(atom_tbl, ",", 2, temp_v!(2), Some(infix!())),
unify_variable!(temp_v!(1)),
unify_variable!(temp_v!(2))],
set_cp!(temp_v!(3)),
goto!(83, 3),
retry_me_else!(4),
fact![get_constant!(Constant::from("!"), temp_v!(1)),
get_constant!(Constant::from("!"), temp_v!(2))],
fact![get_constant!(atom!("!", atom_tbl), temp_v!(1)),
get_constant!(atom!("!", atom_tbl), temp_v!(2))],
set_cp!(temp_v!(3)),
proceed!(),
trust_me!(),
fact![get_constant!(Constant::from("!"), temp_v!(1))],
fact![get_constant!(atom!("!", atom_tbl), temp_v!(1))],
set_cp!(temp_v!(3)),
query![put_value!(temp_v!(2), 1)],
execute_n!(1),
retry_me_else!(8),
allocate!(3),
fact![get_structure!(String::from(","), 2, temp_v!(2), Some(infix!())),
fact![get_structure!(atom_tbl, ",", 2, temp_v!(2), Some(infix!())),
unify_variable!(perm_v!(2)),
unify_variable!(perm_v!(1)),
get_var_in_fact!(perm_v!(3), 3)],
@@ -146,7 +147,7 @@ fn get_builtins() -> Code {
retry_me_else!(10),
allocate!(1),
get_level!(),
fact![get_constant!(Constant::from("!"), temp_v!(2)),
fact![get_constant!(atom!("!", atom_tbl), temp_v!(2)),
get_var_in_fact!(perm_v!(1), 3)],
neck_cut!(),
call_n!(1),
@@ -167,12 +168,12 @@ fn get_builtins() -> Code {
indexed_try!(3),
trust!(5),
try_me_else!(3),
fact![get_structure!(String::from("->"), 2, temp_v!(1), Some(infix!())),
fact![get_structure!(atom_tbl, "->", 2, temp_v!(1), Some(infix!())),
unify_variable!(temp_v!(1)),
unify_variable!(temp_v!(2))],
goto!(139, 3),
trust_me!(),
fact![get_structure!(String::from("->"), 2, temp_v!(1), Some(infix!())),
fact![get_structure!(atom_tbl, "->", 2, temp_v!(1), Some(infix!())),
unify_void!(2)],
query![put_value!(temp_v!(2), 1)],
neck_cut!(),
@@ -231,12 +232,13 @@ fn get_builtins() -> Code {
goto!(149, 3), // goto get_arg/3.
trust_me!(),
query![get_var_in_query!(temp_v!(4), 1),
put_structure!(Level::Shallow,
put_structure!(atom_tbl,
Level::Shallow,
String::from("type_error"),
1,
temp_v!(1),
None),
set_constant!(Constant::Atom(rc_atom!("integer_expected")))],
set_constant!(atom!("integer_expected", atom_tbl))],
goto!(59, 1), // goto throw/1.
try_me_else!(5), // arg_/3, 173.
fact![get_value!(temp_v!(1), 2),
@@ -277,76 +279,76 @@ fn get_builtins() -> Code {
]
}
pub fn build_code_dir() -> (Code, CodeDir, OpDir)
pub fn build_code_dir(atom_tbl: TabledData<Atom>) -> (Code, CodeDir, OpDir)
{
let mut code_dir = HashMap::new();
let mut op_dir = HashMap::new();
let builtin_code = get_builtins();
let builtin_code = get_builtins(atom_tbl.clone());
op_dir.insert((rc_atom!(":-"), Fixity::In), (XFX, 1200));
op_dir.insert((rc_atom!(":-"), Fixity::Pre), (FX, 1200));
op_dir.insert((rc_atom!("?-"), Fixity::Pre), (FX, 1200));
op_dir.insert((tabled_rc!(":-", atom_tbl), Fixity::In), (XFX, 1200));
op_dir.insert((tabled_rc!(":-", atom_tbl), Fixity::Pre), (FX, 1200));
op_dir.insert((tabled_rc!("?-", atom_tbl), Fixity::Pre), (FX, 1200));
// control operators.
op_dir.insert((rc_atom!("\\+"), Fixity::Pre), (FY, 900));
op_dir.insert((rc_atom!("="), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("\\+", atom_tbl), Fixity::Pre), (FY, 900));
op_dir.insert((tabled_rc!("=", atom_tbl), Fixity::In), (XFX, 700));
// arithmetic operators.
op_dir.insert((rc_atom!("is"), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!("+"), Fixity::In), (YFX, 500));
op_dir.insert((rc_atom!("-"), Fixity::In), (YFX, 500));
op_dir.insert((rc_atom!("/\\"), Fixity::In), (YFX, 500));
op_dir.insert((rc_atom!("\\/"), Fixity::In), (YFX, 500));
op_dir.insert((rc_atom!("xor"), Fixity::In), (YFX, 500));
op_dir.insert((rc_atom!("//"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("/"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("div"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("*"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("-"), Fixity::Pre), (FY, 200));
op_dir.insert((rc_atom!("rdiv"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("<<"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!(">>"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("mod"), Fixity::In), (YFX, 400));
op_dir.insert((rc_atom!("rem"), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("is", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("+", atom_tbl), Fixity::In), (YFX, 500));
op_dir.insert((tabled_rc!("-", atom_tbl), Fixity::In), (YFX, 500));
op_dir.insert((tabled_rc!("/\\", atom_tbl), Fixity::In), (YFX, 500));
op_dir.insert((tabled_rc!("\\/", atom_tbl), Fixity::In), (YFX, 500));
op_dir.insert((tabled_rc!("xor", atom_tbl), Fixity::In), (YFX, 500));
op_dir.insert((tabled_rc!("//", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("/", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("div", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("*", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("-", atom_tbl), Fixity::Pre), (FY, 200));
op_dir.insert((tabled_rc!("rdiv", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("<<", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!(">>", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("mod", atom_tbl), Fixity::In), (YFX, 400));
op_dir.insert((tabled_rc!("rem", atom_tbl), Fixity::In), (YFX, 400));
// arithmetic comparison operators.
op_dir.insert((rc_atom!(">"), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!("<"), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!("=\\="), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!("=:="), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!(">="), Fixity::In), (XFX, 700));
op_dir.insert((rc_atom!("=<"), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!(">", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("<", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("=\\=", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("=:=", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!(">=", atom_tbl), Fixity::In), (XFX, 700));
op_dir.insert((tabled_rc!("=<", atom_tbl), Fixity::In), (XFX, 700));
// control operators.
op_dir.insert((rc_atom!(";"), Fixity::In), (XFY, 1100));
op_dir.insert((rc_atom!("->"), Fixity::In), (XFY, 1050));
op_dir.insert((tabled_rc!(";", atom_tbl), Fixity::In), (XFY, 1100));
op_dir.insert((tabled_rc!("->", atom_tbl), Fixity::In), (XFY, 1050));
// 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)
for arity in 0 .. 63 {
code_dir.insert((rc_atom!("call"), arity), (PredicateKeyType::BuiltIn, 0));
code_dir.insert((tabled_rc!("call", atom_tbl), arity), (PredicateKeyType::BuiltIn, 0));
}
code_dir.insert((rc_atom!("atomic"), 1), (PredicateKeyType::BuiltIn, 1));
code_dir.insert((rc_atom!("var"), 1), (PredicateKeyType::BuiltIn, 3));
code_dir.insert((rc_atom!("false"), 0), (PredicateKeyType::BuiltIn, 61));
code_dir.insert((rc_atom!("\\+"), 1), (PredicateKeyType::BuiltIn, 62));
code_dir.insert((rc_atom!("duplicate_term"), 2), (PredicateKeyType::BuiltIn, 71));
code_dir.insert((rc_atom!("catch"), 3), (PredicateKeyType::BuiltIn, 5));
code_dir.insert((rc_atom!("throw"), 1), (PredicateKeyType::BuiltIn, 59));
code_dir.insert((rc_atom!("="), 2), (PredicateKeyType::BuiltIn, 73));
code_dir.insert((rc_atom!("true"), 0), (PredicateKeyType::BuiltIn, 75));
code_dir.insert((tabled_rc!("atomic", atom_tbl), 1), (PredicateKeyType::BuiltIn, 1));
code_dir.insert((tabled_rc!("var", atom_tbl), 1), (PredicateKeyType::BuiltIn, 3));
code_dir.insert((tabled_rc!("false", atom_tbl), 0), (PredicateKeyType::BuiltIn, 61));
code_dir.insert((tabled_rc!("\\+", atom_tbl), 1), (PredicateKeyType::BuiltIn, 62));
code_dir.insert((tabled_rc!("duplicate_term", atom_tbl), 2), (PredicateKeyType::BuiltIn, 71));
code_dir.insert((tabled_rc!("catch", atom_tbl), 3), (PredicateKeyType::BuiltIn, 5));
code_dir.insert((tabled_rc!("throw", atom_tbl), 1), (PredicateKeyType::BuiltIn, 59));
code_dir.insert((tabled_rc!("=", atom_tbl), 2), (PredicateKeyType::BuiltIn, 73));
code_dir.insert((tabled_rc!("true", atom_tbl), 0), (PredicateKeyType::BuiltIn, 75));
code_dir.insert((rc_atom!(","), 2), (PredicateKeyType::BuiltIn, 76));
code_dir.insert((rc_atom!(";"), 2), (PredicateKeyType::BuiltIn, 120));
code_dir.insert((rc_atom!("->"), 2), (PredicateKeyType::BuiltIn, 138));
code_dir.insert((tabled_rc!(",", atom_tbl), 2), (PredicateKeyType::BuiltIn, 76));
code_dir.insert((tabled_rc!(";", atom_tbl), 2), (PredicateKeyType::BuiltIn, 120));
code_dir.insert((tabled_rc!("->", atom_tbl), 2), (PredicateKeyType::BuiltIn, 138));
code_dir.insert((rc_atom!("functor"), 3), (PredicateKeyType::BuiltIn, 146));
code_dir.insert((rc_atom!("arg"), 3), (PredicateKeyType::BuiltIn, 150));
code_dir.insert((rc_atom!("integer"), 1), (PredicateKeyType::BuiltIn, 147));
code_dir.insert((tabled_rc!("functor", atom_tbl), 3), (PredicateKeyType::BuiltIn, 146));
code_dir.insert((tabled_rc!("arg", atom_tbl), 3), (PredicateKeyType::BuiltIn, 150));
code_dir.insert((tabled_rc!("integer", atom_tbl), 1), (PredicateKeyType::BuiltIn, 147));
code_dir.insert((rc_atom!("display"), 1), (PredicateKeyType::BuiltIn, 192));
code_dir.insert((tabled_rc!("display", atom_tbl), 1), (PredicateKeyType::BuiltIn, 192));
(builtin_code, code_dir, op_dir)
}