]> Repositorios git - scryer-prolog.git/commitdiff
transition to reference counted constants
authorMark Thom <[email protected]>
Wed, 10 Jan 2018 05:38:17 +0000 (22:38 -0700)
committerMark Thom <[email protected]>
Wed, 10 Jan 2018 05:38:17 +0000 (22:38 -0700)
src/prolog/arithmetic.rs
src/prolog/ast.rs
src/prolog/builtins.rs
src/prolog/codegen.rs
src/prolog/indexing.rs
src/prolog/io.rs
src/prolog/machine.rs
src/prolog/macros.rs
src/prolog/parser
src/prolog/targets.rs

index b80ccedc3edf9cc0830b55d51ee15b2f8703be06..cba7415f5c219ac5ce79abafc97c6f716adf0a08 100644 (file)
@@ -2,6 +2,7 @@ use prolog::ast::*;
 use prolog::fixtures::*;
 
 use std::cmp::{min, max};
+use std::rc::Rc;
 use std::vec::Vec;
 
 pub struct ArithExprIterator<'a> {
@@ -170,10 +171,8 @@ impl<'a> ArithmeticEvaluator<'a> {
 
     fn push_constant(&mut self, c: &Constant) -> Result<(), ArithmeticError> {
         match c {
-            &Constant::Float(fl) =>
-                self.interm.push(ArithmeticTerm::Float(fl)),
-            &Constant::Integer(ref bi) =>
-                self.interm.push(ArithmeticTerm::Integer(bi.clone())),
+            &Constant::Number(ref n) =>
+                self.interm.push(ArithmeticTerm::Number(n.clone())),
             _ =>
                 return Err(ArithmeticError::InvalidAtom),
         }
@@ -202,11 +201,11 @@ impl<'a> ArithmeticEvaluator<'a> {
                     self.interm.push(ArithmeticTerm::Reg(r));
                 },
                 TermRef::Clause(ClauseType::Deep(_, _, name), terms) => {
-                    code.push(Line::Arithmetic(self.instr_from_clause(name, terms)?));
+                    code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
                 },
                 TermRef::Clause(ClauseType::Root, terms) => {
                     let name = term.name().unwrap();
-                    code.push(Line::Arithmetic(self.instr_from_clause(name, terms)?));
+                    code.push(Line::Arithmetic(self.instr_from_clause(&*name, terms)?));
                 },
                 _ =>
                     return Err(ArithmeticError::InvalidTerm)
index 2a570a1dad5495cbab8b3975031ea6f54d49ce49..7cc9ed0edb7a190ae3d41e6837b459354bac685e 100644 (file)
@@ -11,6 +11,7 @@ use std::fmt;
 use std::io::Error as IOError;
 use std::num::{ParseFloatError};
 use std::ops::{Add, AddAssign, Div, Index, IndexMut, Sub, Mul, Neg};
+use std::rc::Rc;
 use std::str::Utf8Error;
 use std::vec::Vec;
 
@@ -59,7 +60,7 @@ impl PredicateClause {
         }
     }
 
-    pub fn name(&self) -> Option<&Atom> {
+    pub fn name(&self) -> Option<Rc<Atom>> {
         match self {
             &PredicateClause::Fact(ref term) => term.name(),
             &PredicateClause::Rule(ref rule) =>
@@ -73,7 +74,7 @@ impl PredicateClause {
 }
 
 pub enum Declaration {
-    Op(usize, Specifier, Atom)
+    Op(usize, Specifier, Rc<Atom>)
 }
 
 pub enum TopLevel {
@@ -266,18 +267,16 @@ pub enum Fixity {
 
 #[derive(Clone, Eq, Hash, PartialEq)]
 pub enum Constant {
-    Atom(Atom),
-    Float(OrderedFloat<f64>),
-    Integer(BigInt),
-    Rational(Ratio<BigInt>),
-    String(String),
+    Atom(Rc<Atom>),
+    Number(Number),    
+    String(Rc<String>),
     Usize(usize),
     EmptyList
 }
 
 impl<'a> From<&'a str> for Constant {
     fn from(input: &str) -> Constant {
-        Constant::Atom(String::from(input))
+        Constant::Atom(Rc::new(String::from(input)))
     }
 }
 
@@ -288,12 +287,8 @@ impl fmt::Display for Constant {
                 write!(f, "{}", atom),
             &Constant::EmptyList =>
                 write!(f, "[]"),
-            &Constant::Float(fl) =>
-                write!(f, "{}", fl),
-            &Constant::Integer(ref i) =>
-                write!(f, "{}", i),
-            &Constant::Rational(ref r) =>
-                write!(f, "{}", r),
+            &Constant::Number(ref n) =>
+                write!(f, "{}", n),            
             &Constant::String(ref s) =>
                 write!(f, "{}", s),
             &Constant::Usize(integer) =>
@@ -302,22 +297,12 @@ impl fmt::Display for Constant {
     }
 }
 
-impl From<Number> for Constant {
-    fn from(n: Number) -> Self {
-        match n {
-            Number::Rational(r) => Constant::Rational(r),
-            Number::Integer(n) => Constant::Integer(n),
-            Number::Float(f) => Constant::Float(f)
-        }
-    }
-}
-
 pub enum Term {
     AnonVar,
-    Clause(Cell<RegType>, Atom, Vec<Box<Term>>),
+    Clause(Cell<RegType>, Rc<Atom>, Vec<Box<Term>>),
     Cons(Cell<RegType>, Box<Term>, Box<Term>),
     Constant(Cell<RegType>, Constant),
-    Var(Cell<VarReg>, Var)
+    Var(Cell<VarReg>, Rc<Var>)
 }
 
 pub enum InlinedQueryTerm {
@@ -385,7 +370,7 @@ pub struct Rule {
 pub enum ClauseType<'a> {
     CallN,
     Catch,
-    Deep(Level, &'a Cell<RegType>, &'a Atom),
+    Deep(Level, &'a Cell<RegType>, &'a Rc<Atom>),
     Is,
     Root,
     Throw,
@@ -456,11 +441,27 @@ impl IndexedChoiceInstruction {
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, PartialEq, Eq, Hash)]
 pub enum Number {
     Float(OrderedFloat<f64>),
-    Integer(BigInt),
-    Rational(Ratio<BigInt>)
+    Integer(Rc<BigInt>),
+    Rational(Rc<Ratio<BigInt>>)
+}
+
+impl fmt::Display for Number {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            &Number::Float(fl) => write!(f, "{}", fl),
+            &Number::Integer(ref bi) => write!(f, "{}", bi),
+            &Number::Rational(ref r) => write!(f, "{}", r)            
+        }
+    }
+}
+
+impl Default for Number {
+    fn default() -> Self {
+        Number::Float(OrderedFloat(0f64))
+    }
 }
 
 impl Number {
@@ -523,8 +524,8 @@ impl Number {
 
 enum NumberPair {
     Float(OrderedFloat<f64>, OrderedFloat<f64>),
-    Integer(BigInt, BigInt),
-    Rational(Ratio<BigInt>, Ratio<BigInt>)
+    Integer(Rc<BigInt>, Rc<BigInt>),
+    Rational(Rc<Ratio<BigInt>>, Rc<Ratio<BigInt>>)
 }
 
 impl NumberPair {
@@ -536,11 +537,12 @@ impl NumberPair {
         }
     }
 
-    fn integer_float_pair(n1: BigInt, n2: OrderedFloat<f64>) -> NumberPair {
+    fn integer_float_pair(n1: Rc<BigInt>, n2: OrderedFloat<f64>) -> NumberPair {
         match n1.to_f64() {
             Some(f1) => NumberPair::Float(OrderedFloat(f1), n2),
             None => if let Some(r) = Ratio::from_float(n2.into_inner()) {
-                NumberPair::Rational(Ratio::from_integer(n1), r)
+                NumberPair::Rational(Rc::new(Ratio::from_integer((*n1).clone())),
+                                     Rc::new(r))
             } else if n2.into_inner().is_sign_positive() {
                 NumberPair::Float(OrderedFloat(f64::infinity()),
                                   OrderedFloat(f64::infinity()))
@@ -551,12 +553,12 @@ impl NumberPair {
         }
     }
 
-    fn float_rational_pair(n1: OrderedFloat<f64>, n2: Ratio<BigInt>) -> NumberPair {
+    fn float_rational_pair(n1: OrderedFloat<f64>, n2: Rc<Ratio<BigInt>>) -> NumberPair {
         match (n2.numer().to_f64(), n2.denom().to_f64()) {
             (Some(num), Some(denom)) =>
                 NumberPair::Float(n1, OrderedFloat(num / denom)),
             _ => if let Some(r) = Ratio::from_float(n1.into_inner()) {
-                NumberPair::Rational(r, n2)
+                NumberPair::Rational(Rc::new(r), n2)
             } else if n1.into_inner().is_sign_positive() {
                 NumberPair::Float(OrderedFloat(f64::infinity()),
                                   OrderedFloat(f64::infinity()))
@@ -585,9 +587,9 @@ impl NumberPair {
             (Number::Rational(n1), Number::Float(n2)) =>
                 Self::float_rational_pair(n2, n1).flip(),
             (Number::Rational(n1), Number::Integer(n2)) =>
-                NumberPair::Rational(n1, Ratio::from_integer(n2)),
+                NumberPair::Rational(n1, Rc::new(Ratio::from_integer((*n2).clone()))),
             (Number::Integer(n1), Number::Rational(n2)) =>
-                NumberPair::Rational(Ratio::from_integer(n1), n2)
+                NumberPair::Rational(Rc::new(Ratio::from_integer((*n1).clone())), n2)
         }
     }
 }
@@ -600,9 +602,9 @@ impl Add<Number> for Number {
             NumberPair::Float(f1, f2) =>
                 Number::Float(OrderedFloat(f1.into_inner() + f2.into_inner())),
             NumberPair::Integer(n1, n2) =>
-                Number::Integer(n1 + n2),
+                Number::Integer(Rc::new(&*n1 + &*n2)),
             NumberPair::Rational(r1, r2) =>
-                Number::Rational(r1 + r2)
+                Number::Rational(Rc::new(&*r1 + &*r2))
         }
     }
 }
@@ -615,9 +617,9 @@ impl Sub<Number> for Number {
             NumberPair::Float(f1, f2) =>
                 Number::Float(OrderedFloat(f1.into_inner() - f2.into_inner())),
             NumberPair::Integer(n1, n2) =>
-                Number::Integer(n1 - n2),
+                Number::Integer(Rc::new(&*n1 - &*n2)),
             NumberPair::Rational(r1, r2) =>
-                Number::Rational(r1 - r2)
+                Number::Rational(Rc::new(&*r1 - &*r2))
         }
     }
 }
@@ -630,9 +632,9 @@ impl Mul<Number> for Number {
             NumberPair::Float(f1, f2) =>
                 Number::Float(OrderedFloat(f1.into_inner() * f2.into_inner())),
             NumberPair::Integer(n1, n2) =>
-                Number::Integer(n1 * n2),
+                Number::Integer(Rc::new(&*n1 * &*n2)),
             NumberPair::Rational(r1, r2) =>
-                Number::Rational(r1 * r2)
+                Number::Rational(Rc::new(&*r1 * &*r2))
         }        
     }
 }
@@ -649,20 +651,20 @@ impl Div<Number> for Number {
                     Some(f1) => if let Some(f2) = n2.to_f64() {
                         Number::Float(OrderedFloat(f1 / f2))
                     } else {
-                        let r1 = Ratio::from_integer(n1);
-                        let r2 = Ratio::from_integer(n2);
+                        let r1 = Ratio::from_integer((*n1).clone());
+                        let r2 = Ratio::from_integer((*n2).clone());
 
-                        Number::Rational(r1 / r2)
+                        Number::Rational(Rc::new(r1 / r2))
                     },
                     None => {
-                        let r1 = Ratio::from_integer(n1);
-                        let r2 = Ratio::from_integer(n2);
+                        let r1 = Ratio::from_integer((*n1).clone());
+                        let r2 = Ratio::from_integer((*n2).clone());
 
-                        Number::Rational(r1 / r2)
+                        Number::Rational(Rc::new(r1 / r2))
                     },
                 },
             NumberPair::Rational(r1, r2) =>
-                Number::Rational(r1 / r2)
+                Number::Rational(Rc::new(&*r1 / &*r2))
         }
     }
 }
@@ -672,9 +674,9 @@ impl Neg for Number {
 
     fn neg(self) -> Self::Output {
         match self {
-            Number::Integer(n) => Number::Integer(-n),
+            Number::Integer(n) => Number::Integer(Rc::new(-&*n)),
             Number::Float(f) => Number::Float(OrderedFloat(-1.0 * f.into_inner())),
-            Number::Rational(r) => Number::Rational(- r)
+            Number::Rational(r) => Number::Rational(Rc::new(- &*r))
         }
     }
 }
@@ -683,8 +685,7 @@ impl Neg for Number {
 pub enum ArithmeticTerm {
     Reg(RegType),
     Interm(usize),
-    Float(OrderedFloat<f64>),
-    Integer(BigInt)
+    Number(Number)
 }
 
 impl ArithmeticTerm {
@@ -742,12 +743,12 @@ pub enum ControlInstruction {
     Allocate(usize), // num_frames.
     ArgCall,
     ArgExecute,
-    Call(Atom, usize, usize), // name, arity, perm_vars after threshold.
+    Call(Rc<Atom>, usize, usize), // name, arity, perm_vars after threshold.
     CallN(usize), // arity.
     CatchCall,
     CatchExecute,
     Deallocate,
-    Execute(Atom, usize),
+    Execute(Rc<Atom>, usize),
     ExecuteN(usize),
     FunctorCall,
     FunctorExecute,
@@ -786,7 +787,7 @@ impl ControlInstruction {
 pub enum IndexingInstruction {
     SwitchOnTerm(usize, usize, usize, usize),
     SwitchOnConstant(usize, HashMap<Constant, usize>),
-    SwitchOnStructure(usize, HashMap<(Atom, usize), usize>)
+    SwitchOnStructure(usize, HashMap<(Rc<Atom>, usize), usize>)
 }
 
 impl From<IndexingInstruction> for Line {
@@ -798,7 +799,7 @@ impl From<IndexingInstruction> for Line {
 pub enum FactInstruction {
     GetConstant(Level, Constant, RegType),
     GetList(Level, RegType),
-    GetStructure(Level, Atom, usize, RegType),
+    GetStructure(Level, Rc<Atom>, usize, RegType),
     GetValue(RegType, usize),
     GetVariable(RegType, usize),
     UnifyConstant(Constant),
@@ -812,7 +813,7 @@ pub enum QueryInstruction {
     GetVariable(RegType, usize),
     PutConstant(Level, Constant, RegType),
     PutList(Level, RegType),
-    PutStructure(Level, Atom, usize, RegType),
+    PutStructure(Level, Rc<Atom>, usize, RegType),
     PutUnsafeValue(usize, usize),
     PutValue(RegType, usize),
     PutVariable(RegType, usize),
@@ -861,7 +862,7 @@ impl Addr {
             _ => false
         }
     }
-
+    
     pub fn as_ref(&self) -> Option<Ref> {
         match self {
             &Addr::HeapCell(hc) => Some(Ref::HeapCell(hc)),
@@ -897,7 +898,7 @@ pub enum Ref {
 pub enum HeapCellValue {
     Con(Constant),
     Lis(usize),
-    NamedStr(usize, Atom),
+    NamedStr(usize, Rc<Atom>),
     Ref(Ref),
     Str(usize)
 }
@@ -1047,10 +1048,10 @@ impl Term {
         }
     }
 
-    pub fn name(&self) -> Option<&Atom> {
+    pub fn name(&self) -> Option<Rc<Atom>> {
         match self {
             &Term::Constant(_, Constant::Atom(ref atom))
-          | &Term::Clause(_, ref atom, _) => Some(atom),
+          | &Term::Clause(_, ref atom, _) => Some(atom.clone()),
             _ => None
         }
     }
index 34fa430e4cab83e9b176ef09a1306f82b4905145..73cac026375169eaa760fd5df6140d47c8efdf3c 100644 (file)
@@ -2,8 +2,9 @@ use prolog::ast::*;
 use prolog::num::bigint::{BigInt};
 
 use std::collections::HashMap;
+use std::rc::Rc;
 
-pub type PredicateKey = (Atom, usize); // name, arity, type.
+pub type PredicateKey = (Rc<Atom>, usize); // name, arity, type.
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
 pub enum PredicateKeyType {
@@ -11,7 +12,7 @@ pub enum PredicateKeyType {
     User
 }
 
-pub type OpDirKey = (Atom, Fixity);
+pub type OpDirKey = (Rc<Atom>, Fixity);
 // name and fixity -> operator type and precedence.
 pub type OpDir = HashMap<OpDirKey, (Specifier, usize)>;
 
@@ -234,7 +235,7 @@ fn get_builtins() -> Code {
                                String::from("type_error"),
                                1,
                                temp_v!(1)),
-                set_constant!(Constant::Atom(String::from("integer_expected")))],
+                set_constant!(Constant::Atom(rc_atom!("integer_expected")))],
          goto!(59, 1), // goto throw/1.
          try_me_else!(5), // arg_/3, 173.
          fact![get_value!(temp_v!(1), 2),
@@ -259,7 +260,7 @@ fn get_builtins() -> Code {
                                ArithmeticTerm::Reg(temp_v!(2)),
                                ArithmeticTerm::Reg(perm_v!(4))),
          add!(ArithmeticTerm::Reg(temp_v!(2)),
-              ArithmeticTerm::Integer(BigInt::from(1)),
+              ArithmeticTerm::Number(rc_integer!(1)),
               1),
          query![put_var!(perm_v!(1), 1)],
          is_call!(perm_v!(1), interm!(1)),
@@ -280,67 +281,67 @@ pub fn build_code_dir() -> (Code, CodeDir, OpDir)
 
     let builtin_code = get_builtins();
 
-    op_dir.insert((String::from(":-"), Fixity::In),   (XFX, 1200));
-    op_dir.insert((String::from(":-"), Fixity::Pre),  (FX, 1200));
-    op_dir.insert((String::from("?-"), Fixity::Pre),  (FX, 1200));
+    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));
 
     // control operators.
-    op_dir.insert((String::from("\\+"), Fixity::Pre), (FY, 900));
-    op_dir.insert((String::from("="), Fixity::In), (XFX, 700));
+    op_dir.insert((rc_atom!("\\+"), Fixity::Pre), (FY, 900));
+    op_dir.insert((rc_atom!("="), Fixity::In), (XFX, 700));
 
     // arithmetic operators.
-    op_dir.insert((String::from("is"), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from("+"), Fixity::In), (YFX, 500));
-    op_dir.insert((String::from("-"), Fixity::In), (YFX, 500));
-    op_dir.insert((String::from("/\\"), Fixity::In), (YFX, 500));
-    op_dir.insert((String::from("\\/"), Fixity::In), (YFX, 500));
-    op_dir.insert((String::from("xor"), Fixity::In), (YFX, 500));
-    op_dir.insert((String::from("//"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("/"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("div"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("*"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("-"), Fixity::Pre), (FY, 200));
-    op_dir.insert((String::from("rdiv"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("<<"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from(">>"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("mod"), Fixity::In), (YFX, 400));
-    op_dir.insert((String::from("rem"), Fixity::In), (YFX, 400));
+    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));
 
     // arithmetic comparison operators.
-    op_dir.insert((String::from(">"), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from("<"), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from("=\\="), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from("=:="), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from(">="), Fixity::In), (XFX, 700));
-    op_dir.insert((String::from("=<"), 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((rc_atom!("=<"), Fixity::In), (XFX, 700));
 
     // control operators.
-    op_dir.insert((String::from(";"), Fixity::In), (XFY, 1100));
-    op_dir.insert((String::from("->"), Fixity::In), (XFY, 1050));
+    op_dir.insert((rc_atom!(";"), Fixity::In), (XFY, 1100));
+    op_dir.insert((rc_atom!("->"), 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((String::from("call"), arity), (PredicateKeyType::BuiltIn, 0));
+        code_dir.insert((rc_atom!("call"), arity), (PredicateKeyType::BuiltIn, 0));
     }
 
-    code_dir.insert((String::from("atomic"), 1), (PredicateKeyType::BuiltIn, 1));
-    code_dir.insert((String::from("var"), 1), (PredicateKeyType::BuiltIn, 3));
-    code_dir.insert((String::from("false"), 0), (PredicateKeyType::BuiltIn, 61));
-    code_dir.insert((String::from("\\+"), 1), (PredicateKeyType::BuiltIn, 62));
-    code_dir.insert((String::from("duplicate_term"), 2), (PredicateKeyType::BuiltIn, 71));
-    code_dir.insert((String::from("catch"), 3), (PredicateKeyType::BuiltIn, 5));
-    code_dir.insert((String::from("throw"), 1), (PredicateKeyType::BuiltIn, 59));
-    code_dir.insert((String::from("="), 2), (PredicateKeyType::BuiltIn, 73));
-    code_dir.insert((String::from("true"), 0), (PredicateKeyType::BuiltIn, 75));
+    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((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((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((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));
+    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));
 
     (builtin_code, code_dir, op_dir)
 }
index d3eeab24d32687b99d2d0320296b1929445dfa5d..d2d26fcd7684a31f28599d10645027bbb66fab0d 100644 (file)
@@ -9,6 +9,7 @@ use prolog::targets::*;
 use std::cell::Cell;
 use std::collections::HashMap;
 use std::mem::swap;
+use std::rc::Rc;
 use std::vec::Vec;
 
 pub struct CodeGenerator<'a, TermMarker> {
@@ -330,7 +331,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
                 },
             &InlinedQueryTerm::IsInteger(ref inner_term) =>
                 match inner_term[0].as_ref() {                    
-                    &Term::Constant(_, Constant::Integer(_)) => {
+                    &Term::Constant(_, Constant::Number(Number::Integer(_))) => {
                         code.push(succeed!());
                     },
                     &Term::Var(ref vr, ref name) => {
@@ -404,23 +405,9 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker>
 
                                 code.push(is_call!(r, at.unwrap_or(interm!(1))));
                             },
-                            &Term::Constant(_, Constant::Float(fl)) => {
+                            &Term::Constant(_, ref c @ Constant::Number(_)) => {
                                 code.push(query![put_constant!(Level::Shallow,
-                                                               Constant::Float(fl),
-                                                               temp_v!(1))]);
-                                code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
-                            },
-                            &Term::Constant(_, Constant::Integer(ref bi)) => {
-                                let bi = bi.clone();
-                                code.push(query![put_constant!(Level::Shallow,
-                                                               Constant::Integer(bi),
-                                                               temp_v!(1))]);
-                                code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
-                            },
-                            &Term::Constant(_, Constant::Rational(ref r)) => {
-                                let r = r.clone();
-                                code.push(query![put_constant!(Level::Shallow,
-                                                               Constant::Rational(r),
+                                                               c.clone(),
                                                                temp_v!(1))]);
                                 code.push(is_call!(temp_v!(1), at.unwrap_or(interm!(1))));
                             },
index 3d94ec02c7e9cf9f79cc3e023f2591c536677200..35b100118f8767b8de7f2153100455d3522e2c4d 100644 (file)
@@ -2,6 +2,7 @@ use prolog::ast::*;
 
 use std::collections::{HashMap, VecDeque};
 use std::hash::Hash;
+use std::rc::Rc;
 
 #[derive(Clone, Copy)]
 enum IntIndex {
@@ -11,7 +12,7 @@ enum IntIndex {
 pub struct CodeOffsets {
     pub constants:  HashMap<Constant, ThirdLevelIndex>,
     pub lists: ThirdLevelIndex,
-    pub structures: HashMap<(Atom, usize), ThirdLevelIndex>
+    pub structures: HashMap<(Rc<Atom>, usize), ThirdLevelIndex>
 }
 
 impl CodeOffsets {
@@ -144,7 +145,8 @@ impl CodeOffsets {
         }
     }
 
-    fn switch_on_structure(str_ind: HashMap<(Atom, usize), ThirdLevelIndex>, prelude: &mut CodeDeque)
+    fn switch_on_structure(str_ind: HashMap<(Rc<Atom>, usize), ThirdLevelIndex>,
+                           prelude: &mut CodeDeque)
                            -> IntIndex
     {
         let str_ind = Self::second_level_index(str_ind, prelude);
index e1a6915c2f546686381df4dfc8a9dd7dd298b2a1..2175959f1b572811291e6b8fec7d57363417990b 100644 (file)
@@ -227,8 +227,7 @@ impl fmt::Display for ArithmeticTerm {
         match self {
             &ArithmeticTerm::Reg(r) => write!(f, "{}", r),
             &ArithmeticTerm::Interm(i) => write!(f, "@{}", i),
-            &ArithmeticTerm::Float(fl) => write!(f, "{}", fl),
-            &ArithmeticTerm::Integer(ref bi) => write!(f, "{}", bi)
+            &ArithmeticTerm::Number(ref n) => write!(f, "{}", n),
         }
     }
 }
index 35a36276b3f300bf7e352266dee9405e124a4fa8..314bc71084d8ff9c4112d5d0bbde6eeae1d068d0 100644 (file)
@@ -8,12 +8,12 @@ use prolog::num::{Integer, ToPrimitive, Zero};
 use prolog::num::bigint::{BigInt, BigUint};
 use prolog::num::rational::Ratio;
 use prolog::or_stack::*;
-use prolog::ordered_float::OrderedFloat;
 use prolog::fixtures::*;
 
 use std::cmp::max;
 use std::collections::HashMap;
 use std::ops::{Index, IndexMut};
+use std::rc::Rc;
 use std::vec::Vec;
 
 #[derive(Clone, Copy)]
@@ -226,7 +226,7 @@ impl Machine {
         self.ms.fail
     }
 
-    fn add_user_code<'a>(&mut self, name: Atom, arity: usize, offset: usize) -> EvalSession<'a>
+    fn add_user_code<'a>(&mut self, name: Rc<Atom>, arity: usize, offset: usize) -> EvalSession<'a>
     {
         match self.code_dir.get(&(name.clone(), arity)) {
             Some(&(PredicateKeyType::BuiltIn, _)) =>
@@ -257,13 +257,11 @@ impl Machine {
         match &rule.head.0 {
             &QueryTerm::Term(Term::Clause(_, ref name, _))
           | &QueryTerm::Term(Term::Constant(_, Constant::Atom(ref name))) => {
-                let p = self.code.len();
-
-                let name  = name.clone();
+                let p = self.code.len();                
                 let arity = rule.head.0.arity();
 
                 self.code.append(&mut code);
-                self.add_user_code(name, arity, p)
+                self.add_user_code(name.clone(), arity, p)
             },
             _ => EvalSession::NamelessEntry
         }
@@ -446,7 +444,8 @@ impl Machine {
         }
     }
 
-    pub fn submit_decl<'a>(&mut self, decl: &Declaration) -> EvalSession<'a> {
+    pub fn submit_decl<'a>(&mut self, decl: &Declaration) -> EvalSession<'a>
+    {                
         match decl {
             &Declaration::Op(prec, spec, ref name) => {
                 if is_infix!(spec) {
@@ -631,7 +630,7 @@ impl MachineState {
                        hb: 0,
                        block: 0,
                        ball: (0, Vec::new()),
-                       interms: vec![Number::Float(OrderedFloat(0f64)); 256],
+                       interms: vec![Number::default(); 256],
         }
     }
 
@@ -814,7 +813,7 @@ impl MachineState {
         }
     }
 
-    fn write_constant_to_var(&mut self, addr: Addr, c: &Constant) {
+    fn write_constant_to_var(&mut self, addr: Addr, c: Constant) {
         let addr = self.deref(addr);
 
         match self.store(addr) {
@@ -827,7 +826,7 @@ impl MachineState {
                 self.trail(Ref::StackCell(fr, sc));
             },
             Addr::Con(c1) => {
-                if c1 != *c {
+                if c1 != c {
                     self.fail = true;
                 }
             },
@@ -835,47 +834,40 @@ impl MachineState {
         };
     }
 
-    fn get_rational(&self, at: &ArithmeticTerm) -> Result<Ratio<BigInt>, Vec<HeapCellValue>> {
+    fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, Vec<HeapCellValue>> {
+        match at {
+            &ArithmeticTerm::Reg(r) => {
+                let addr = self[r].clone();
+                let item = self.store(self.deref(addr));
+
+                match item {
+                    Addr::Con(Constant::Number(n)) => Ok(n),
+                    _ => Err(functor!("instantiation_error", 1, [atom!("(is)/2")]))
+                }
+            },
+            &ArithmeticTerm::Interm(i)     => Ok(self.interms[i-1].clone()),
+            &ArithmeticTerm::Number(ref n) => Ok(n.clone()),
+        }
+    }
+
+    fn get_rational(&self, at: &ArithmeticTerm) -> Result<Rc<Ratio<BigInt>>, Vec<HeapCellValue>> {
         let n = self.get_number(at)?;
 
         match n {
             Number::Rational(r) => Ok(r),
             Number::Float(fl) =>
                 if let Some(r) = Ratio::from_float(fl.into_inner()) {
-                    Ok(r)
+                    Ok(Rc::new(r))
                 } else {
                     Err(functor!("instantiation_error", 1, [atom!("(is)/2")]))
                 },
             Number::Integer(bi) =>
-                Ok(Ratio::from_integer(bi))
+                Ok(Rc::new(Ratio::from_integer((*bi).clone())))
         }
     }
 
-    fn get_number(&self, at: &ArithmeticTerm) -> Result<Number, Vec<HeapCellValue>> {
-        match at {
-            &ArithmeticTerm::Reg(r) => {
-                let addr = self[r].clone();
-                let item = self.store(self.deref(addr));
-
-                match item {
-                    Addr::Con(Constant::Integer(bi)) =>
-                        Ok(Number::Integer(bi)),
-                    Addr::Con(Constant::Float(fl)) =>
-                        Ok(Number::Float(fl)),
-                    Addr::Con(Constant::Rational(r)) =>
-                        Ok(Number::Rational(r)),
-                    _ =>
-                        Err(functor!("instantiation_error", 1, [atom!("(is)/2")]))
-                }
-            },
-            &ArithmeticTerm::Interm(i)   => Ok(self.interms[i-1].clone()),
-            &ArithmeticTerm::Float(fl)   => Ok(Number::Float(fl)),
-            &ArithmeticTerm::Integer(ref bi) => Ok(Number::Integer(bi.clone()))
-        }
-    }
-
-    fn signed_bitwise_op<Op>(&mut self, n1: BigInt, n2: BigInt, t: usize, f: Op)
-        where Op: FnOnce(BigUint, BigUint) -> BigUint
+    fn signed_bitwise_op<Op>(&mut self, n1: &BigInt, n2: &BigInt, t: usize, f: Op)
+        where Op: FnOnce(&BigUint, &BigUint) -> BigUint
     {
         let n1_b = n1.to_signed_bytes_le();
         let n2_b = n2.to_signed_bytes_le();
@@ -883,9 +875,9 @@ impl MachineState {
         let u_n1 = BigUint::from_bytes_le(&n1_b);
         let u_n2 = BigUint::from_bytes_le(&n2_b);
 
-        let result = BigInt::from_signed_bytes_le(&f(u_n1, u_n2).to_bytes_le());
+        let result = BigInt::from_signed_bytes_le(&f(&u_n1, &u_n2).to_bytes_le());
 
-        self.interms[t - 1] = Number::Integer(result);
+        self.interms[t - 1] = Number::Integer(Rc::new(result));
     }
 
     fn execute_arith_instr(&mut self, instr: &ArithmeticInstruction) {
@@ -915,14 +907,14 @@ impl MachineState {
                 let r1 = try_or_fail!(self, self.get_rational(a1));
                 let r2 = try_or_fail!(self, self.get_rational(a2));
 
-                if r2 == Ratio::zero() {
+                if *r2 == Ratio::zero() {
                     self.throw_exception(functor!("evaluation_error",
                                                   1,
                                                   [atom!("zero_divisor")]));
                     return;
                 }
 
-                self.interms[t - 1] = Number::Rational(r1 / r2);
+                self.interms[t - 1] = Number::Rational(Rc::new(&*r1 / &*r2));
                 self.p += 1;
             },
             &ArithmeticInstruction::FIDiv(ref a1, ref a2, t) => {
@@ -931,14 +923,14 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) => {
-                        if n2 == BigInt::zero() {
+                        if *n2 == BigInt::zero() {
                             self.throw_exception(functor!("evaluation_error",
                                                           1,
                                                           [atom!("zero_divisor")]));
                             return;
                         }
 
-                        self.interms[t - 1] = Number::Integer(n1.div_floor(&n2));
+                        self.interms[t - 1] = Number::Integer(Rc::new(n1.div_floor(&n2)));
                         self.p += 1;
                     },
                     _ => {
@@ -955,14 +947,14 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) => {
-                        if n2 == BigInt::zero() {
+                        if *n2 == BigInt::zero() {
                             self.throw_exception(functor!("evaluation_error",
                                                           1,
                                                           [atom!("zero_divisor")]));
                             return;
                         }
 
-                        self.interms[t - 1] = Number::Integer(n1 / n2);
+                        self.interms[t - 1] = Number::Integer(Rc::new(&*n1 / &*n2));
                         self.p += 1;
                     },
                     _ => {
@@ -1000,8 +992,8 @@ impl MachineState {
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) =>
                         match n2.to_usize() {
-                            Some(n2) => self.interms[t - 1] = Number::Integer(n1 >> n2),
-                            _ => self.interms[t - 1] = Number::Integer(n1 >> usize::max_value())
+                            Some(n2) => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 >> n2)),
+                            _ => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 >> usize::max_value()))
                         },
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
@@ -1020,8 +1012,8 @@ impl MachineState {
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) =>
                         match n2.to_usize() {
-                            Some(n2) => self.interms[t - 1] = Number::Integer(n1 << n2),
-                            _ => self.interms[t - 1] = Number::Integer(n1 << usize::max_value())
+                            Some(n2) => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 << n2)),
+                            _ => self.interms[t - 1] = Number::Integer(Rc::new(&*n1 << usize::max_value()))
                         },
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
@@ -1039,7 +1031,7 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) =>
-                        self.signed_bitwise_op(n1, n2, t, |u_n1, u_n2| u_n1 ^ u_n2),
+                        self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 ^ u_n2),
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
                                                       1,
@@ -1056,7 +1048,7 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) =>
-                        self.signed_bitwise_op(n1, n2, t, |u_n1, u_n2| u_n1 & u_n2),
+                        self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 & u_n2),
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
                                                       1,
@@ -1073,7 +1065,7 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) =>
-                        self.signed_bitwise_op(n1, n2, t, |u_n1, u_n2| u_n1 | u_n2),
+                        self.signed_bitwise_op(&*n1, &*n2, t, |u_n1, u_n2| u_n1 | u_n2),
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
                                                       1,
@@ -1090,14 +1082,14 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) => {
-                        if n2 == BigInt::zero() {
+                        if *n2 == BigInt::zero() {
                             self.throw_exception(functor!("evaluation_error",
                                                           1,
                                                           [atom!("zero_divisor")]));
                             return;
                         }
 
-                        self.interms[t - 1] = Number::Integer(n1.mod_floor(&n2));
+                        self.interms[t - 1] = Number::Integer(Rc::new(n1.mod_floor(&n2)));
                     },
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
@@ -1115,14 +1107,14 @@ impl MachineState {
 
                 match (n1, n2) {
                     (Number::Integer(n1), Number::Integer(n2)) => {
-                        if n2 == BigInt::zero() {
+                        if *n2 == BigInt::zero() {
                             self.throw_exception(functor!("evaluation_error",
                                                           1,
                                                           [atom!("zero_divisor")]));
                             return;
                         }
 
-                        self.interms[t - 1] = Number::Integer(n1 % n2);
+                        self.interms[t - 1] = Number::Integer(Rc::new(&*n1 % &*n2));
                     },
                     _ => {
                         self.throw_exception(functor!("evaluation_error",
@@ -1141,7 +1133,7 @@ impl MachineState {
         match instr {
             &FactInstruction::GetConstant(_, ref c, reg) => {
                 let addr = self[reg].clone();
-                self.write_constant_to_var(addr, c);
+                self.write_constant_to_var(addr, c.clone());
             },
             &FactInstruction::GetList(_, reg) => {
                 let addr = self.deref(self[reg].clone());
@@ -1211,7 +1203,7 @@ impl MachineState {
                 match self.mode {
                     MachineMode::Read  => {
                         let addr = Addr::HeapCell(self.s);
-                        self.write_constant_to_var(addr, c);
+                        self.write_constant_to_var(addr, c.clone());
                     },
                     MachineMode::Write => {
                         self.heap.push(HeapCellValue::Con(c.clone()));
@@ -1443,7 +1435,7 @@ impl MachineState {
         }
     }
 
-    fn try_call_predicate(&mut self, code_dir: &CodeDir, name: Atom, arity: usize)
+    fn try_call_predicate(&mut self, code_dir: &CodeDir, name: Rc<Atom>, arity: usize)
     {
         let compiled_tl_index = code_dir.get(&(name, arity)).map(|index| index.1);
 
@@ -1458,7 +1450,7 @@ impl MachineState {
         };
     }
 
-    fn try_execute_predicate(&mut self, code_dir: &CodeDir, name: Atom, arity: usize)
+    fn try_execute_predicate(&mut self, code_dir: &CodeDir, name: Rc<Atom>, arity: usize)
     {
         let compiled_tl_index = code_dir.get(&(name, arity)).map(|index| index.1);
 
@@ -1574,7 +1566,7 @@ impl MachineState {
     {
         let a1 = self.store(self.deref(self[temp_v!(1)].clone()));
         
-        if let Addr::Con(Constant::Integer(i)) = a1 {
+        if let Addr::Con(Constant::Number(Number::Integer(i))) = a1 {
             let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
 
             if let Addr::Str(o) = a2 {
@@ -1645,7 +1637,7 @@ impl MachineState {
                 let c = Constant::Usize(self.block);
                 let addr = self[temp_v!(1)].clone();
 
-                self.write_constant_to_var(addr, &c);
+                self.write_constant_to_var(addr, c);
                 self.p += 1;
             },
             &BuiltInInstruction::EraseBall => {
@@ -1728,7 +1720,7 @@ impl MachineState {
                 let c = Constant::Usize(self.block);
                 let addr = self[temp_v!(1)].clone();
 
-                self.write_constant_to_var(addr, &c);
+                self.write_constant_to_var(addr, c);
                 self.p += 1;
             },
             &BuiltInInstruction::ResetBlock => {
@@ -1760,7 +1752,7 @@ impl MachineState {
                 let d = self.store(self.deref(self[r].clone()));
 
                 match d {
-                    Addr::Con(Constant::Integer(_)) => self.p += 1,
+                    Addr::Con(Constant::Number(Number::Integer(_))) => self.p += 1,
                     _ => self.fail = true
                 };
             },
@@ -1799,7 +1791,7 @@ impl MachineState {
                 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 arity = Addr::Con(Constant::Number(rc_integer!(arity)));
 
                         let a2 = self[temp_v!(2)].clone();
                         self.unify(a2, name);
@@ -1816,7 +1808,7 @@ impl MachineState {
                 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 {
+                    if let Addr::Con(Constant::Number(Number::Integer(arity))) = arity {
                         let f_a = Addr::Str(self.heap.h);
                         let arity = match arity.to_usize() {
                             Some(arity) => arity,
@@ -1847,7 +1839,7 @@ impl MachineState {
                 
                 if !self.fail {
                     let a3 = self[temp_v!(3)].clone();
-                    self.unify(a3, Addr::Con(Constant::Integer(BigInt::from(0))));
+                    self.unify(a3, Addr::Con(Constant::Number(rc_integer!(0))));
                 }
             }
         };
@@ -1950,14 +1942,14 @@ impl MachineState {
                 let a1 = self[r].clone();
                 let a2 = try_or_fail!(self, self.get_number(at));
 
-                self.unify(a1, Addr::Con(Constant::from(a2)));
+                self.unify(a1, Addr::Con(Constant::Number(a2)));
                 self.p += 1;
             },
             &ControlInstruction::IsExecute(r, ref at) => {
                 let a1 = self[r].clone();
                 let a2 = try_or_fail!(self, self.get_number(at));
 
-                self.unify(a1, Addr::Con(Constant::from(a2)));                
+                self.unify(a1, Addr::Con(Constant::Number(a2)));                
                 self.p = self.cp;
             },
             &ControlInstruction::Proceed =>
index 0cad85ccb45dacf007bdb5702888c4bcaa9e70dc..3ac2f46a2e31d9fde6e884d100f27ef7bc8220da 100644 (file)
@@ -44,7 +44,7 @@ macro_rules! query {
 macro_rules! functor {
     ($name:expr, $len:expr, [$($args:expr),*]) => {{
         if $len > 0 {
-            vec![ HeapCellValue::NamedStr($len, String::from($name)), $($args),* ]
+            vec![ HeapCellValue::NamedStr($len, Rc::new(String::from($name))), $($args),* ]
         } else {
             vec![ atom!($name) ]
         }
@@ -53,7 +53,7 @@ macro_rules! functor {
 
 macro_rules! atom {
     ($name:expr) => (
-        HeapCellValue::Con(Constant::Atom(String::from($name)))
+        HeapCellValue::Con(Constant::Atom(Rc::new(String::from($name))))
     )
 }
 
@@ -102,7 +102,7 @@ macro_rules! put_var {
 
 macro_rules! put_structure {
     ($lvl:expr, $name:expr, $arity:expr, $r:expr) => (
-        QueryInstruction::PutStructure($lvl, $name, $arity, $r)
+        QueryInstruction::PutStructure($lvl, Rc::new($name), $arity, $r)
     )
 }
 
@@ -318,7 +318,7 @@ macro_rules! get_constant {
 
 macro_rules! get_structure {
     ($atom:expr, $arity:expr, $r:expr) => (
-        FactInstruction::GetStructure(Level::Shallow, $atom, $arity, $r)
+        FactInstruction::GetStructure(Level::Shallow, Rc::new($atom), $arity, $r)
     )
 }
 
@@ -360,7 +360,7 @@ macro_rules! get_cp {
 
 macro_rules! integer {
     ($i:expr) => (
-        Constant::Integer(BigInt::from($i))
+        Constant::Number(Number::Integer(Rc::new(BigInt::from($i))))
     )
 }
 
@@ -375,3 +375,15 @@ macro_rules! get_arg {
         Line::BuiltIn(BuiltInInstruction::GetArg)
     )
 }
+
+macro_rules! rc_integer {
+    ($e:expr) => (
+        Number::Integer(Rc::new(BigInt::from($e)))
+    )
+}
+
+macro_rules! rc_atom {
+    ($e:expr) => (
+        Rc::new(String::from($e))
+    )
+}
index f51fc401fa86fa90136c05e83dee5a5b85e579be..57001ad9911a4a973fae5cf16e4be1273e3ad55f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit f51fc401fa86fa90136c05e83dee5a5b85e579be
+Subproject commit 57001ad9911a4a973fae5cf16e4be1273e3ad55f
index fe2974f969058a43466b30fba5dfae3b39456265..e08d4717f51777fb8036f6de103f6aa0e7aef539 100644 (file)
@@ -1,6 +1,8 @@
 use prolog::ast::*;
 use prolog::iterators::*;
 
+use std::rc::Rc;
+
 pub trait CompilationTarget<'a> {
     type Iterator : Iterator<Item=TermRef<'a>>;
 
@@ -8,7 +10,7 @@ pub trait CompilationTarget<'a> {
 
     fn to_constant(Level, Constant, RegType) -> Self;
     fn to_list(Level, RegType) -> Self;
-    fn to_structure(Level, Atom, usize, RegType) -> Self;
+    fn to_structure(Level, Rc<Atom>, usize, RegType) -> Self;
 
     fn to_void(usize) -> Self;
     fn is_void_instr(&self) -> bool;
@@ -39,7 +41,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
         FactInstruction::GetConstant(lvl, constant, reg)
     }
 
-    fn to_structure(lvl: Level, atom: Atom, arity: usize, reg: RegType) -> Self {
+    fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType) -> Self {
         FactInstruction::GetStructure(lvl, atom, arity, reg)
     }
 
@@ -101,7 +103,7 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
         term.post_order_iter()
     }
 
-    fn to_structure(lvl: Level, atom: Atom, arity: usize, reg: RegType) -> Self {
+    fn to_structure(lvl: Level, atom: Rc<Atom>, arity: usize, reg: RegType) -> Self {
         QueryInstruction::PutStructure(lvl, atom, arity, reg)
     }