]> Repositorios git - scryer-prolog.git/commitdiff
add provisional functor and arg support, and give ';' and '->' their true semantics
authorMark Thom <[email protected]>
Tue, 9 Jan 2018 04:14:19 +0000 (21:14 -0700)
committerMark Thom <[email protected]>
Tue, 9 Jan 2018 04:14:19 +0000 (21:14 -0700)
12 files changed:
Cargo.lock
Cargo.toml
README.md
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/heapview.rs
src/prolog/io.rs
src/prolog/iterators.rs
src/prolog/machine.rs
src/prolog/macros.rs
src/prolog/parser

index 56e97a19c5c4c431f71771f8bdf2ea84ff2dbd02..e6566fffecdc0753e4317da1a488b41eefbce0d8 100644 (file)
@@ -1,20 +1,20 @@
 [root]
 name = "rusty-wam"
-version = "0.7.4"
+version = "0.7.5"
 dependencies = [
- "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "aho-corasick"
-version = "0.6.3"
+version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -40,52 +40,57 @@ dependencies = [
 
 [[package]]
 name = "lazy_static"
-version = "0.2.10"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "lazy_static"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.33"
+version = "0.2.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "memchr"
-version = "1.0.2"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num"
-version = "0.1.40"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-bigint"
-version = "0.1.40"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-complex"
-version = "0.1.40"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -94,7 +99,7 @@ name = "num-integer"
 version = "0.1.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -103,7 +108,7 @@ version = "0.1.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -111,15 +116,15 @@ name = "num-rational"
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.1.40"
+version = "0.1.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -127,7 +132,7 @@ name = "ordered-float"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -137,12 +142,12 @@ version = "0.3.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.31"
+version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -150,18 +155,18 @@ name = "redox_termios"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "regex"
-version = "0.2.2"
+version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -180,17 +185,17 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "thread_local"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -221,29 +226,30 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
-"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
+"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
 "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
-"checksum lazy_static 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "236eb37a62591d4a41a89b7763d7de3e06ca02d5ab2815446a8bae5d2f8c2d57"
-"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2"
-"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
-"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525"
-"checksum num-bigint 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "8fd0f8dbb4c0960998958a796281d88c16fbe68d87b1baa6f31e2979e81fd0bd"
-"checksum num-complex 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "503e668405c5492d67cf662a81e05be40efe2e6bcf10f7794a07bd9865e704e6"
+"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
+"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
+"checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
+"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
+"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca"
+"checksum num-bigint 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "bdc1494b5912f088f260b775799468d9b9209ac60885d8186a547a0476289e23"
+"checksum num-complex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "58de7b4bf7cf5dbecb635a5797d489864eadd03b107930cbccf9e0fd7428b47c"
 "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
 "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
 "checksum num-rational 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "0c7cb72a95250d8a370105c828f388932373e0e94414919891a0f945222310fe"
-"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
+"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070"
 "checksum ordered-float 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58d25b6c0e47b20d05226d288ff434940296e7e2f8b877975da32f862152241f"
 "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
-"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
+"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
+"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322"
 "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
-"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
+"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
index 7d3168db86f572121a8bd875856661079669473f..08e048a785cb5b936bd1883c5febcef0abc47910 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "rusty-wam"
-version = "0.7.4"
+version = "0.7.5"
 authors = ["Mark Thom"]
 
 [dependencies]
index 3e972087be86076518030da72c6f96a563a1302d..b43ed20ac3df7dbc841874eba73ab9a0c859c189 100644 (file)
--- a/README.md
+++ b/README.md
@@ -76,13 +76,14 @@ The following predicates are built-in to rusty-wam.
     * `is/2` works for `(+)/2`, `(-)/{1,2}`, `(*)/2`, `(//)/2`, `(div)/2`, `(/)/2`, `(rdiv)/2`,
       `(xor)/2`, `(rem)/2`, `(mod)/2`, `(/\)/2`, `(\/)/2`, `(>>)/2`, `(<<)/2`.
     * Comparison operators: `>`, `<`, `=<`, `>=`, `=:=`, `=\=`.
+* `(\+)/1`
+* `(=)/2`    
 * `atomic/1`
 * `call/N` (1 <= N <= 63)
 * `catch/3`
 * `duplicate_term/2`
 * `false/0`
-* `(\+)/1`
-* `(=)/2`
+* `integer/1`
 * `throw/1`
 * `true/0`
 * `var/1`
index 12d8bf95d2f25bfbe55ff5130b3e80f1fca3112d..2a570a1dad5495cbab8b3975031ea6f54d49ce49 100644 (file)
@@ -324,6 +324,7 @@ pub enum InlinedQueryTerm {
     CompareNumber(CompareNumberQT, Vec<Box<Term>>),
     IsAtomic(Vec<Box<Term>>),
     IsVar(Vec<Box<Term>>),
+    IsInteger(Vec<Box<Term>>)
 }
 
 impl InlinedQueryTerm {
@@ -331,6 +332,7 @@ impl InlinedQueryTerm {
         match self {
             &InlinedQueryTerm::CompareNumber(_, _) => 2,
             &InlinedQueryTerm::IsAtomic(_) => 1,
+            &InlinedQueryTerm::IsInteger(_) => 1,
             &InlinedQueryTerm::IsVar(_) => 1,
         }
     }
@@ -347,9 +349,11 @@ pub enum CompareNumberQT {
 }
 
 pub enum QueryTerm {
+    Arg(Vec<Box<Term>>),
     CallN(Vec<Box<Term>>),
     Catch(Vec<Box<Term>>),
     Cut,
+    Functor(Vec<Box<Term>>),
     Inlined(InlinedQueryTerm),
     Is(Vec<Box<Term>>),
     Term(Term),
@@ -359,8 +363,10 @@ pub enum QueryTerm {
 impl QueryTerm {
     pub fn arity(&self) -> usize {
         match self {
+            &QueryTerm::Arg(_) => 3,
             &QueryTerm::Catch(_) => 3,
             &QueryTerm::Throw(_) => 1,
+            &QueryTerm::Functor(_) => 3,
             &QueryTerm::Inlined(ref term) => term.arity(),
             &QueryTerm::Is(_) => 2,
             &QueryTerm::CallN(ref terms) => terms.len(),
@@ -715,12 +721,14 @@ pub enum BuiltInInstruction {
     DuplicateTerm,
     EraseBall,
     Fail,
+    GetArg,
     GetBall,
     GetCurrentBlock,
     GetCutPoint(RegType),
     InstallNewBlock,
     InternalCallN,
     IsAtomic(RegType),
+    IsInteger(RegType),
     IsVar(RegType),
     ResetBlock,
     SetBall,
@@ -732,6 +740,8 @@ pub enum BuiltInInstruction {
 
 pub enum ControlInstruction {
     Allocate(usize), // num_frames.
+    ArgCall,
+    ArgExecute,
     Call(Atom, usize, usize), // name, arity, perm_vars after threshold.
     CallN(usize), // arity.
     CatchCall,
@@ -739,6 +749,8 @@ pub enum ControlInstruction {
     Deallocate,
     Execute(Atom, usize),
     ExecuteN(usize),
+    FunctorCall,
+    FunctorExecute,
     Goto(usize, usize), // p, arity.
     IsCall(RegType, ArithmeticTerm),
     IsExecute(RegType, ArithmeticTerm),
@@ -750,12 +762,16 @@ pub enum ControlInstruction {
 impl ControlInstruction {
     pub fn is_jump_instr(&self) -> bool {
         match self {
+            &ControlInstruction::ArgCall => true,
+            &ControlInstruction::ArgExecute => true,
             &ControlInstruction::Call(_, _, _)  => true,
             &ControlInstruction::CatchCall => true,
             &ControlInstruction::CatchExecute => true,
             &ControlInstruction::Execute(_, _)  => true,
             &ControlInstruction::CallN(_) => true,
             &ControlInstruction::ExecuteN(_) => true,
+            &ControlInstruction::FunctorCall => true,
+            &ControlInstruction::FunctorExecute => true,
             &ControlInstruction::ThrowCall => true,
             &ControlInstruction::ThrowExecute => true,
             &ControlInstruction::Goto(_, _) => true,
index 2b99e3f84dd7be08c1337f5a479078b0da4e94b8..34fa430e4cab83e9b176ef09a1306f82b4905145 100644 (file)
@@ -1,4 +1,5 @@
 use prolog::ast::*;
+use prolog::num::bigint::{BigInt};
 
 use std::collections::HashMap;
 
@@ -105,14 +106,8 @@ fn get_builtins() -> Code {
          fact![get_value!(temp_v!(1), 2)], // =/2, 73.
          proceed!(),
          proceed!(), // true/0, 75.
-         try_me_else!(2), // ';'/2, 76.
-         execute_n!(1),
-         trust_me!(),
-         query![put_value!(temp_v!(2), 1)],
-         execute_n!(1),
-         get_cp!(temp_v!(3)), // ','/2, 81
-         goto!(83, 3),
-         try_me_else!(18), // ','/3, 83.
+         get_cp!(temp_v!(3)), // ','/2, 76
+         try_me_else!(18), // ','/3, 77.
          switch_on_term!(4, 1, 0, 0),
          indexed_try!(4),
          retry!(7),
@@ -165,14 +160,116 @@ fn get_builtins() -> Code {
          query![put_value!(perm_v!(1), 1)],
          deallocate!(),
          execute_n!(1),
-         allocate!(2), // (->)/2, 126.
-         get_level!(),
-         fact![get_var_in_fact!(perm_v!(2), 2)],
+         get_cp!(temp_v!(3)), // ';'/2, 120.
+         try_me_else!(12),
+         switch_on_term!(4, 0, 0, 1),
+         indexed_try!(3),
+         trust!(5),
+         try_me_else!(3),
+         fact![get_structure!(String::from("->"), 2, temp_v!(1)),
+               unify_variable!(temp_v!(1)),
+               unify_variable!(temp_v!(2))],
+         goto!(139, 3),
+         trust_me!(),
+         fact![get_structure!(String::from("->"), 2, temp_v!(1)),
+               unify_void!(2)],
+         query![put_value!(temp_v!(2), 1)],
+         neck_cut!(),
+         execute_n!(1),
+         retry_me_else!(2),
+         execute_n!(1),
+         trust_me!(),
+         query![put_value!(temp_v!(2), 1)],
+         execute_n!(1),
+         get_cp!(temp_v!(3)), // '->'/2, 138.
+         allocate!(2), // '->'/3, 139.
+         fact![get_var_in_fact!(perm_v!(1), 2),
+               get_var_in_fact!(perm_v!(2), 3)], // cut point.
          call_n!(1),
-         cut!(),
-         query![put_value!(perm_v!(2), 1)],
+         set_cp!(perm_v!(2)),
+         query![put_unsafe_value!(1, 1)],
          deallocate!(),
-         execute_n!(1)
+         execute_n!(1),
+         functor_execute!(), // functor/3, 146.
+         is_integer!(temp_v!(1)), // integer/1, 147.
+         proceed!(),
+         get_arg!(), // get_arg/3, 149.
+         try_me_else!(10), // arg/3, 150.
+         allocate!(4),
+         fact![get_var_in_fact!(perm_v!(1), 1),
+               get_var_in_fact!(perm_v!(2), 2),
+               get_var_in_fact!(perm_v!(4), 3)],
+         is_var!(perm_v!(1)),
+         neck_cut!(),
+         query![put_value!(perm_v!(2), 1),
+                put_var!(temp_v!(4), 2),
+                put_var!(perm_v!(3), 3)],
+         functor_call!(),
+         query![put_value!(perm_v!(1), 1),
+                put_constant!(Level::Shallow, integer!(1), temp_v!(2)),
+                put_unsafe_value!(3, 3),
+                put_value!(perm_v!(2), 4),
+                put_value!(perm_v!(4), 5)],
+         deallocate!(),
+         goto!(173, 5), // goto arg_/3.
+         retry_me_else!(10),
+         allocate!(3),
+         fact![get_var_in_fact!(perm_v!(1), 1),
+               get_var_in_fact!(perm_v!(2), 2),
+               get_var_in_fact!(perm_v!(3), 3)],
+         is_integer!(perm_v!(1)),
+         neck_cut!(),
+         query![put_value!(perm_v!(2), 1),
+                put_var!(temp_v!(4), 2),
+                put_var!(temp_v!(3), 3)],
+         functor_call!(),
+         query![put_value!(perm_v!(1), 1),
+                put_value!(perm_v!(2), 2),
+                put_value!(perm_v!(3), 3)],
+         deallocate!(),
+         goto!(149, 3), // goto get_arg/3.
+         trust_me!(),
+         query![get_var_in_query!(temp_v!(4), 1),
+                put_structure!(Level::Shallow,
+                               String::from("type_error"),
+                               1,
+                               temp_v!(1)),
+                set_constant!(Constant::Atom(String::from("integer_expected")))],
+         goto!(59, 1), // goto throw/1.
+         try_me_else!(5), // arg_/3, 173.
+         fact![get_value!(temp_v!(1), 2),
+               get_value!(temp_v!(1), 3)],
+         neck_cut!(),
+         query![put_value!(temp_v!(4), 2),
+                put_value!(temp_v!(5), 3)],
+         goto!(149, 3), // goto get_arg/3.
+         retry_me_else!(4),
+         fact![get_value!(temp_v!(1), 2)],
+         query![put_value!(temp_v!(4), 2),
+                get_var_in_query!(temp_v!(6), 3),
+                put_value!(temp_v!(5), 3)],
+         goto!(149, 3), // goto get_arg/3
+         trust_me!(),
+         allocate!(5),
+         fact![get_var_in_fact!(perm_v!(2), 1),
+               get_var_in_fact!(perm_v!(4), 3),
+               get_var_in_fact!(perm_v!(3), 4),
+               get_var_in_fact!(perm_v!(5), 5)],
+         compare_number_instr!(CompareNumberQT::LessThan,
+                               ArithmeticTerm::Reg(temp_v!(2)),
+                               ArithmeticTerm::Reg(perm_v!(4))),
+         add!(ArithmeticTerm::Reg(temp_v!(2)),
+              ArithmeticTerm::Integer(BigInt::from(1)),
+              1),
+         query![put_var!(perm_v!(1), 1)],
+         is_call!(perm_v!(1), interm!(1)),
+         query![put_value!(perm_v!(2), 1),
+                put_unsafe_value!(1, 2),
+                put_value!(perm_v!(4), 3),
+                put_value!(perm_v!(3), 4),
+                put_value!(perm_v!(5), 5)],
+         deallocate!(),
+         goto!(173, 3) // goto arg_/3.
     ]
 }
 
@@ -237,9 +334,13 @@ pub fn build_code_dir() -> (Code, CodeDir, OpDir)
     code_dir.insert((String::from("="), 2), (PredicateKeyType::BuiltIn, 73));
     code_dir.insert((String::from("true"), 0), (PredicateKeyType::BuiltIn, 75));
 
-    code_dir.insert((String::from(";"), 2), (PredicateKeyType::BuiltIn, 76));
-    code_dir.insert((String::from(","), 2), (PredicateKeyType::BuiltIn, 81));
-    code_dir.insert((String::from("->"), 2), (PredicateKeyType::BuiltIn, 126));
+    code_dir.insert((String::from(","), 2), (PredicateKeyType::BuiltIn, 76));
+    code_dir.insert((String::from(";"), 2), (PredicateKeyType::BuiltIn, 120));
+    code_dir.insert((String::from("->"), 2), (PredicateKeyType::BuiltIn, 138));
+
+    code_dir.insert((String::from("functor"), 3), (PredicateKeyType::BuiltIn, 146));
+    code_dir.insert((String::from("arg"), 3), (PredicateKeyType::BuiltIn, 150));
+    code_dir.insert((String::from("integer"), 1), (PredicateKeyType::BuiltIn, 147));
 
     (builtin_code, code_dir, op_dir)
 }
index 1a8bc30b851552163e7367be7c1a9c14574d2e43..d3eeab24d32687b99d2d0320296b1929445dfa5d 100644 (file)
@@ -236,12 +236,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
     fn add_conditional_call(code: &mut Code, qt: &QueryTerm, pvs: usize)
     {
         match qt {
+            &QueryTerm::Arg(_) => {
+                let call = ControlInstruction::ArgCall;
+                code.push(Line::Control(call));
+            },
             &QueryTerm::CallN(ref terms) => {
                 let call = ControlInstruction::CallN(terms.len());
                 code.push(Line::Control(call));
             },
             &QueryTerm::Catch(_) =>
                 code.push(Line::Control(ControlInstruction::CatchCall)),
+            &QueryTerm::Functor(_) =>
+                code.push(Line::Control(ControlInstruction::FunctorCall)),            
             &QueryTerm::Inlined(_) =>
                 code.push(proceed!()),
             &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref atom))) => {
@@ -268,10 +274,14 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                 swap(ctrl, &mut instr);
 
                 match instr {
+                    ControlInstruction::ArgCall =>
+                        *ctrl = ControlInstruction::ArgExecute,
                     ControlInstruction::Call(name, arity, _) =>
                         *ctrl = ControlInstruction::Execute(name, arity),
                     ControlInstruction::CallN(arity) =>
                         *ctrl = ControlInstruction::ExecuteN(arity),
+                    ControlInstruction::FunctorCall =>
+                        *ctrl = ControlInstruction::FunctorExecute,
                     ControlInstruction::CatchCall =>
                         *ctrl = ControlInstruction::CatchExecute,
                     ControlInstruction::ThrowCall =>
@@ -304,7 +314,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                 code.push(compare_number_instr!(cmp,
                                                 at_1.unwrap_or(interm!(1)),
                                                 at_2.unwrap_or(interm!(2))));
-            },
+            },            
             &InlinedQueryTerm::IsAtomic(ref inner_term) =>
                 match inner_term[0].as_ref() {
                     &Term::AnonVar | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
@@ -318,6 +328,19 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         code.push(is_atomic!(r));
                     }
                 },
+            &InlinedQueryTerm::IsInteger(ref inner_term) =>
+                match inner_term[0].as_ref() {                    
+                    &Term::Constant(_, Constant::Integer(_)) => {
+                        code.push(succeed!());
+                    },
+                    &Term::Var(ref vr, ref name) => {
+                        let r = self.mark_non_callable(name, 1, term_loc, vr, code);
+                        code.push(is_integer!(r));
+                    },
+                    _ => {
+                        code.push(fail!());
+                    },
+                },
             &InlinedQueryTerm::IsVar(ref inner_term) =>
                 match inner_term[0].as_ref() {
                     &Term::Constant(_, _) | &Term::Clause(_, _, _) | &Term::Cons(_, _, _) => {
@@ -330,7 +353,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                         let r = self.mark_non_callable(name, 1, term_loc, vr, code);
                         code.push(is_var!(r));
                     }
-                }
+                }        
         }
 
         Ok(())
index c11103db4ab23396d34c6326482d76013450870d..52ed0747231046db24d8ae53c11d10a139df2fe5 100644 (file)
@@ -51,8 +51,26 @@ pub struct HeapCellViewer<'a> {
     state_stack: Vec<CellRef<'a>>
 }
 
-impl<'a> HeapCellViewer<'a> {
-    fn cell_ref_from_addr(&self, mut focus: &'a Addr) -> CellRef<'a> {
+impl<'a> HeapCellViewer<'a>
+{
+    pub fn new(heap: &'a Heap, and_stack: &'a AndStack, addr: &'a Addr) -> Self
+    {
+        let mut viewer = HeapCellViewer {
+            heap: heap,
+            and_stack: and_stack,
+            state_stack: vec![]
+        };
+
+        let cell_ref = viewer.deref_cell(addr);
+        let view = viewer.follow(cell_ref);
+
+        viewer.state_stack.push(CellRef::View(view));
+
+        viewer
+    }
+
+    fn deref_cell(&self, mut focus: &'a Addr) -> CellRef<'a>
+    {
         loop {
             match focus {
                 &Addr::Con(ref c) =>
@@ -75,22 +93,6 @@ impl<'a> HeapCellViewer<'a> {
         }
     }
 
-    pub fn new(heap: &'a Heap, and_stack: &'a AndStack, addr: &'a Addr) -> Self
-    {
-        let mut viewer = HeapCellViewer {
-            heap: heap,
-            and_stack: and_stack,
-            state_stack: vec![]
-        };
-
-        let cell_ref = viewer.cell_ref_from_addr(addr);
-        let view = viewer.follow(cell_ref);
-
-        viewer.state_stack.push(CellRef::View(view));
-
-        viewer
-    }
-
     pub fn remove_token(&mut self, loc: usize) {
         self.state_stack[loc] = CellRef::TToken(TToken::Nothing);
     }
@@ -143,21 +145,19 @@ impl<'a> HeapCellViewer<'a> {
 
                     return CellView::Str(arity, name);
                 },
-                &HeapCellValue::Ref(Ref::HeapCell(hc)) => {
+                &HeapCellValue::Ref(Ref::HeapCell(hc)) =>
                     if focus == hc {
                         return CellView::HeapVar(hc);
                     } else {
                         focus = hc;
-                    }
-                },
-                &HeapCellValue::Ref(Ref::StackCell(fr, sc)) => {
-                    match self.cell_ref_from_addr(&self.and_stack[fr][sc]) {
+                    },                
+                &HeapCellValue::Ref(Ref::StackCell(fr, sc)) =>
+                    match self.deref_cell(&self.and_stack[fr][sc]) {
                         CellRef::Lis(hc)         => return self.handle_list(hc),
                         CellRef::View(cell_view) => return cell_view,
                         CellRef::Redirect(hc)    => focus = hc,
                         CellRef::TToken(token)   => return CellView::TToken(token)
-                    };
-                },
+                    },                
                 &HeapCellValue::Str(cell_num) =>
                     focus = cell_num,
             }
@@ -179,7 +179,6 @@ impl<'a> HeapCellViewer<'a> {
     }
 }
 
-
 impl<'a> Iterator for HeapCellViewer<'a> {
     type Item = CellView<'a>;
 
index 3774520f1ebfac425a77288f10a6adb7625c18ec..e1a6915c2f546686381df4dfc8a9dd7dd298b2a1 100644 (file)
@@ -98,6 +98,10 @@ impl fmt::Display for ControlInstruction {
         match self {
             &ControlInstruction::Allocate(num_cells) =>
                 write!(f, "allocate {}", num_cells),
+            &ControlInstruction::ArgCall =>
+                write!(f, "arg_call"),
+            &ControlInstruction::ArgExecute =>
+                write!(f, "arg_execute"),
             &ControlInstruction::Call(ref name, arity, pvs) =>
                 write!(f, "call {}/{}, {}", name, arity, pvs),
             &ControlInstruction::CallN(arity) =>
@@ -108,6 +112,10 @@ impl fmt::Display for ControlInstruction {
                 write!(f, "execute_catch"),            
             &ControlInstruction::ExecuteN(arity) =>
                 write!(f, "execute_N {}", arity),
+            &ControlInstruction::FunctorCall =>
+                write!(f, "functor_call"),
+            &ControlInstruction::FunctorExecute =>
+                write!(f, "functor_execute"),
             &ControlInstruction::Deallocate =>
                 write!(f, "deallocate"),
             &ControlInstruction::Execute(ref name, arity) =>
@@ -154,6 +162,8 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "erase_ball"),
             &BuiltInInstruction::Fail =>
                 write!(f, "false"),
+            &BuiltInInstruction::GetArg =>
+                write!(f, "get_arg X1, X2, X3"),
             &BuiltInInstruction::GetBall =>
                 write!(f, "get_ball X1"),
             &BuiltInInstruction::GetCurrentBlock =>
@@ -166,6 +176,8 @@ impl fmt::Display for BuiltInInstruction {
                 write!(f, "internal_call_N"),
             &BuiltInInstruction::IsAtomic(r) =>
                 write!(f, "is_atomic {}", r),
+            &BuiltInInstruction::IsInteger(r) =>
+                write!(f, "is_integer {}", r),
             &BuiltInInstruction::IsVar(r) =>
                 write!(f, "is_var {}", r),            
             &BuiltInInstruction::ResetBlock =>
@@ -386,7 +398,7 @@ pub fn eval<'a, 'b: 'a>(wam: &'a mut Machine, tl: &'b TopLevel) -> EvalSession<'
                 Ok(rule) => rule,
                 Err(e) => return EvalSession::ParserError(e)                
             };
-            
+
             wam.add_rule(rule, compiled_rule)
         },
         &TopLevel::Query(ref query) => {
index 62002207483f4b7e21068115211bbd5b88b174cf..e5cf2d3511bec544def43bb127089071d545d87e 100644 (file)
@@ -40,12 +40,18 @@ impl<'a> QueryIterator<'a> {
                 let state = IteratorState::Clause(0, ClauseType::Catch, terms);
                 QueryIterator { state_stack: vec![state] }
             },
+            &QueryTerm::Arg(ref terms)
+          | &QueryTerm::Functor(ref terms) => {
+                let state = IteratorState::Clause(0, ClauseType::Root, terms);
+                QueryIterator { state_stack: vec![state] }
+            },
             &QueryTerm::Inlined(InlinedQueryTerm::CompareNumber(_, ref terms))
           | &QueryTerm::Is(ref terms) => {
-              let state = IteratorState::Clause(0, ClauseType::Is, terms);
-              QueryIterator { state_stack: vec![state] }
-            },
+                    let state = IteratorState::Clause(0, ClauseType::Is, terms);
+                    QueryIterator { state_stack: vec![state] }
+                },
             &QueryTerm::Inlined(InlinedQueryTerm::IsAtomic(ref terms))
+          | &QueryTerm::Inlined(InlinedQueryTerm::IsInteger(ref terms))
           | &QueryTerm::Inlined(InlinedQueryTerm::IsVar(ref terms)) =>
                 Self::from_term(terms[0].as_ref()),
             &QueryTerm::Term(ref term) =>
@@ -271,6 +277,12 @@ impl<'a> ChunkedIterator<'a>
                     arity = child_terms.len();
                     break;
                 },
+                &QueryTerm::Arg(_)
+              | &QueryTerm::Functor(_) => {
+                    result.push(term);
+                    arity = 3;
+                    break;
+                },
                 &QueryTerm::Is(_) => {
                     result.push(term);
                     arity = 2;
index 014d20786dd13ef9c7002d9abb83b308e03de5f9..35a36276b3f300bf7e352266dee9405e124a4fa8 100644 (file)
@@ -1498,7 +1498,8 @@ impl MachineState {
         self.p  = CodePtr::DirEntry(59);
     }
 
-    fn throw_exception(&mut self, hcv: Vec<HeapCellValue>) {
+    fn throw_exception
+        (&mut self, hcv: Vec<HeapCellValue>) {
         let h = self.heap.h;
 
         self.registers[1] = Addr::HeapCell(h);
@@ -1569,6 +1570,35 @@ impl MachineState {
         }
     }
 
+    fn try_get_arg(&mut self) -> Result<(), Vec<HeapCellValue>>
+    {
+        let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
+        
+        if let Addr::Con(Constant::Integer(i)) = a1 {
+            let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
+
+            if let Addr::Str(o) = a2 {
+                match self.heap[o].clone() {
+                    HeapCellValue::NamedStr(arity, _) =>
+                        match i.to_usize() {
+                            Some(i) if 1 <= i && i <= arity => {
+                                let a3  = self[temp_v!(3)].clone();
+                                let h_a = Addr::HeapCell(o + i);
+                                
+                                self.unify(a3, h_a);
+                            },
+                            _ => self.fail = true
+                        },
+                    _ => self.fail = true
+                };                         
+            } else {
+                return Err(functor!("type_error", 1, [atom!("compound_expected")]));
+            }
+        }
+
+        Ok(())
+    }
+    
     fn execute_built_in_instr(&mut self, code_dir: &CodeDir, instr: &BuiltInInstruction)
     {
         match instr {
@@ -1605,6 +1635,12 @@ impl MachineState {
 
                 self.p += 1;
             },
+            &BuiltInInstruction::GetArg => 
+                try_or_fail!(self, {
+                    let val = self.try_get_arg();
+                    self.p = self.cp;
+                    val
+                }),
             &BuiltInInstruction::GetCurrentBlock => {
                 let c = Constant::Usize(self.block);
                 let addr = self[temp_v!(1)].clone();
@@ -1720,6 +1756,14 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
+            &BuiltInInstruction::IsInteger(r) => {
+                let d = self.store(self.deref(self[r].clone()));
+
+                match d {
+                    Addr::Con(Constant::Integer(_)) => self.p += 1,
+                    _ => self.fail = true
+                };
+            },
             &BuiltInInstruction::IsVar(r) => {
                 let d = self.store(self.deref(self[r].clone()));
 
@@ -1747,6 +1791,70 @@ impl MachineState {
         };
     }
 
+    fn try_functor(&mut self) -> Result<(), Vec<HeapCellValue>> {
+        let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
+
+        match a1.clone() {
+            Addr::Str(o) =>
+                match self.heap[o].clone() {
+                    HeapCellValue::NamedStr(arity, name) => {                    
+                        let name  = Addr::Con(Constant::Atom(name)); // A2
+                        let arity = Addr::Con(Constant::Integer(BigInt::from(arity))); // A3
+
+                        let a2 = self[temp_v!(2)].clone();
+                        self.unify(a2, name);
+                        
+                        if !self.fail {
+                            let a3 = self[temp_v!(3)].clone();
+                            self.unify(a3, arity);
+                        }
+                    },
+                    _ => self.fail = true
+                },
+            Addr::HeapCell(_) | Addr::StackCell(_, _) => {
+                let name  = self.store(self.deref(self[temp_v!(2)].clone()));
+                let arity = self.store(self.deref(self[temp_v!(3)].clone()));
+
+                if let Addr::Con(Constant::Atom(name)) = name {
+                    if let Addr::Con(Constant::Integer(arity)) = arity {
+                        let f_a = Addr::Str(self.heap.h);
+                        let arity = match arity.to_usize() {
+                            Some(arity) => arity,
+                            None => {
+                                self.fail = true;
+                                return Ok(());
+                            }
+                        };
+                        
+                        self.heap.push(HeapCellValue::NamedStr(arity, name));
+
+                        for _ in 0 .. arity {
+                            let h = self.heap.h;
+                            self.heap.push(HeapCellValue::Ref(Ref::HeapCell(h)));
+                        }
+                                                
+                        self.unify(a1, f_a);                                                
+                    } else {
+                        return Err(functor!("instantiation_error", 0, []));
+                    }
+                } else {
+                    return Err(functor!("instantiation_error", 0, []));
+                }                
+            },
+            _ => {
+                let a2 = self[temp_v!(2)].clone();
+                self.unify(a1, a2);
+                
+                if !self.fail {
+                    let a3 = self[temp_v!(3)].clone();
+                    self.unify(a3, Addr::Con(Constant::Integer(BigInt::from(0))));
+                }
+            }
+        };
+
+        Ok(())
+    }
+    
     fn execute_ctrl_instr(&mut self, code_dir: &CodeDir, instr: &ControlInstruction)
     {
         match instr {
@@ -1779,6 +1887,17 @@ impl MachineState {
                 self.and_stack.push(gi, self.e, self.cp, num_cells);
                 self.e = self.and_stack.len() - 1;
             },
+            &ControlInstruction::ArgCall => {
+                self.cp = self.p + 1;
+                self.num_of_args = 3;
+                self.b0 = self.b;
+                self.p  = CodePtr::DirEntry(150);
+            },
+            &ControlInstruction::ArgExecute => {
+                self.num_of_args = 3;
+                self.b0 = self.b;
+                self.p  = CodePtr::DirEntry(150);
+            },
             &ControlInstruction::Call(ref name, arity, _) =>
                 self.try_call_predicate(code_dir, name.clone(), arity),
             &ControlInstruction::CatchCall => {
@@ -1810,6 +1929,18 @@ impl MachineState {
                 if let Some((name, arity)) = self.setup_call_n(arity) {
                     self.try_execute_predicate(code_dir, name, arity);
                 },
+            &ControlInstruction::FunctorCall =>
+                try_or_fail!(self, {
+                    let val = self.try_functor();
+                    self.p += 1;
+                    val
+                }),
+            &ControlInstruction::FunctorExecute =>
+                try_or_fail!(self, {
+                    let val = self.try_functor();
+                    self.p = self.cp;
+                    val
+                }),
             &ControlInstruction::Goto(p, arity) => {
                 self.num_of_args = arity;
                 self.b0 = self.b;
index 4474dd620cd10a17343b6edd9e9439e823cb5b0d..0cad85ccb45dacf007bdb5702888c4bcaa9e70dc 100644 (file)
@@ -1,3 +1,4 @@
+
 macro_rules! internal_call_n {
     () => (
         Line::BuiltIn(BuiltInInstruction::InternalCallN)
@@ -99,12 +100,24 @@ macro_rules! put_var {
     )
 }
 
+macro_rules! put_structure {
+    ($lvl:expr, $name:expr, $arity:expr, $r:expr) => (
+        QueryInstruction::PutStructure($lvl, $name, $arity, $r)
+    )
+}
+
 macro_rules! put_constant {
     ($lvl:expr, $cons:expr, $r:expr) => (
         QueryInstruction::PutConstant($lvl, $cons, $r)
     )
 }
 
+macro_rules! set_constant {
+    ($cons:expr) => (
+        QueryInstruction::SetConstant($cons)
+    )
+}
+
 macro_rules! put_value {
     ($r:expr, $arg:expr) => (
         QueryInstruction::PutValue($r, $arg)
@@ -135,6 +148,12 @@ macro_rules! is_atomic {
     )
 }
 
+macro_rules! is_integer {
+    ($reg:expr) => (
+        Line::BuiltIn(BuiltInInstruction::IsInteger($reg))
+    )
+}
+
 macro_rules! is_var {
     ($reg:expr) => (
         Line::BuiltIn(BuiltInInstruction::IsVar($reg))
@@ -303,12 +322,30 @@ macro_rules! get_structure {
     )
 }
 
+macro_rules! functor_call {
+    () => (
+        Line::Control(ControlInstruction::FunctorCall)
+    )
+}
+
+macro_rules! functor_execute {
+    () => (
+        Line::Control(ControlInstruction::FunctorExecute)
+    )
+}
+
 macro_rules! unify_variable {
     ($r:expr) => (
         FactInstruction::UnifyVariable($r)
     )
 }
 
+macro_rules! unify_void {
+    ($n:expr) => (
+        FactInstruction::UnifyVoid($n)
+    )
+}
+
 macro_rules! set_cp {
     ($r:expr) => (
         Line::BuiltIn(BuiltInInstruction::SetCutPoint($r))
@@ -321,4 +358,20 @@ macro_rules! get_cp {
     )
 }
 
+macro_rules! integer {
+    ($i:expr) => (
+        Constant::Integer(BigInt::from($i))
+    )
+}
+
+macro_rules! add {
+    ($at_1:expr, $at_2:expr, $o:expr) => (
+        Line::Arithmetic(ArithmeticInstruction::Add($at_1, $at_2, $o))
+    )
+}
 
+macro_rules! get_arg {
+    () => (
+        Line::BuiltIn(BuiltInInstruction::GetArg)
+    )
+}
index 87230857805adcfff30c8f0257179e87c531fb21..f51fc401fa86fa90136c05e83dee5a5b85e579be 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 87230857805adcfff30c8f0257179e87c531fb21
+Subproject commit f51fc401fa86fa90136c05e83dee5a5b85e579be