]> Repositorios git - scryer-prolog.git/commitdiff
add numbered vars to writeq
authorMark Thom <[email protected]>
Tue, 17 Jul 2018 02:12:50 +0000 (20:12 -0600)
committerMark Thom <[email protected]>
Tue, 17 Jul 2018 02:12:50 +0000 (20:12 -0600)
src/prolog/heap_iter.rs
src/prolog/heap_print.rs
src/prolog/io.rs
src/prolog/machine/machine_state.rs

index 58129249bbf04bf830e5771715fd2293ef2378ee..4b9544e1f0ac25651ecb38f2b7b96ddcaebe9ac1 100644 (file)
@@ -5,7 +5,7 @@ use std::collections::HashSet;
 use std::vec::Vec;
 
 pub struct HCPreOrderIterator<'a> {
-    machine_st: &'a MachineState,
+    pub(crate) machine_st: &'a MachineState,
     state_stack: Vec<Addr>
 }
 
index e09cc02019321dd200fe4281c91646e4175b0905..6bbe4ef80775d35a192e0f4a18bd23dcff712562 100644 (file)
@@ -1,4 +1,5 @@
 use prolog::ast::*;
+use prolog::num::*;
 use prolog::heap_iter::*;
 use prolog::machine::machine_state::MachineState;
 use prolog::ordered_float::OrderedFloat;
@@ -10,6 +11,7 @@ use std::rc::Rc;
 #[derive(Clone)]
 pub enum TokenOrRedirect {
     Atom(ClauseName),
+    NumberedVar(String),
     Redirect,
     Open,
     Close,
@@ -40,7 +42,7 @@ pub trait HCValueFormatter {
 
     // this can be overloaded to handle special cases, falling back on the default of
     // format_struct when convenient.
-    fn format_clause(&self, usize, ClauseType, &mut Vec<TokenOrRedirect>);
+    fn format_clause(&self, &mut HCPreOrderIterator, usize, ClauseType, &mut Vec<TokenOrRedirect>);
 }
 
 pub trait HCValueOutputter {
@@ -99,44 +101,81 @@ impl HCValueOutputter for PrinterOutputter {
 }
 
 // the 'classic' display corresponding to the display predicate.
-pub struct DisplayFormatter {}
+pub struct WriteqFormatter {}
 
-impl HCValueFormatter for DisplayFormatter {
-    fn format_clause(&self, arity: usize, ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>)
+fn is_numbered_var(ct: &ClauseType, arity: usize) -> bool {
+    arity == 1 && if let &ClauseType::Named(ref name, _) = ct {
+        name.as_str() == "$VAR"
+    } else {
+        false
+    }
+}
+
+fn print_op(ct: ClauseType, fixity: Fixity, state_stack: &mut Vec<TokenOrRedirect>) {
+    match fixity {
+        Fixity::Post => {
+            state_stack.push(TokenOrRedirect::Atom(ct.name()));
+            state_stack.push(TokenOrRedirect::Redirect);
+        },
+        Fixity::Pre => {
+            state_stack.push(TokenOrRedirect::Redirect);
+            state_stack.push(TokenOrRedirect::Atom(ct.name()));
+        },
+        Fixity::In => {
+            state_stack.push(TokenOrRedirect::Redirect);
+            state_stack.push(TokenOrRedirect::Atom(ct.name()));
+            state_stack.push(TokenOrRedirect::Redirect);
+        }
+    }    
+}
+
+impl HCValueFormatter for WriteqFormatter {
+    fn format_clause(&self, iter: &mut HCPreOrderIterator, arity: usize,
+                     ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>)
     {
-        if ct.fixity().is_some() {
-            let mut new_name = String::from("'");
-            new_name += ct.name().as_str();
-            new_name += "'";
+        static CHAR_CODES: [char; 26] = ['A','B','C','D','E','F','G','H','I','J',
+                                         'K','L','M','N','O','P','Q','R','S','T',
+                                         'U','V','W','X','Y','Z'];
 
-            self.format_struct(arity, ct.name(), state_stack);
-        } else {
-            self.format_struct(arity, ct.name(), state_stack);
+        if let Some(fixity) = ct.fixity() {
+            return print_op(ct, fixity, state_stack);
+        } else if is_numbered_var(&ct, arity) {
+            let addr = iter.stack().last().cloned().unwrap();
+
+            // 7.10.4
+            match iter.machine_st.store(iter.machine_st.deref(addr)) {
+                Addr::Con(Constant::Number(Number::Integer(n))) => {
+                    iter.stack().pop();
+                    
+                    let i = n.mod_floor(&BigInt::from(26)).to_usize().unwrap();
+                    let j = n.div_floor(&BigInt::from(26));
+
+                    let mut result = if j.is_zero() {
+                        CHAR_CODES[i].to_string()
+                    } else {
+                        format!("{}{}", CHAR_CODES[i], j)
+                    };
+                    
+                    state_stack.push(TokenOrRedirect::NumberedVar(result));
+                    
+                    return;
+                }
+                _ => {}
+            };           
         }
+        
+        self.format_struct(arity, ct.name(), state_stack);        
     }
 }
 
 pub struct TermFormatter {}
 
 impl HCValueFormatter for TermFormatter {
-    fn format_clause(&self, arity: usize, ct: ClauseType, state_stack: &mut Vec<TokenOrRedirect>)
+    fn format_clause(&self, _: &mut HCPreOrderIterator, arity: usize, ct: ClauseType,
+                     state_stack: &mut Vec<TokenOrRedirect>)
     {
         if let Some(fixity) = ct.fixity() {
-            match fixity {
-                Fixity::Post => {
-                    state_stack.push(TokenOrRedirect::Atom(ct.name()));
-                    state_stack.push(TokenOrRedirect::Redirect);
-                },
-                Fixity::Pre => {
-                    state_stack.push(TokenOrRedirect::Redirect);
-                    state_stack.push(TokenOrRedirect::Atom(ct.name()));
-                },
-                Fixity::In => {
-                    state_stack.push(TokenOrRedirect::Redirect);
-                    state_stack.push(TokenOrRedirect::Atom(ct.name()));
-                    state_stack.push(TokenOrRedirect::Redirect);
-                }
-            }
+            print_op(ct, fixity, state_stack);
         } else {
             self.format_struct(arity, ct.name(), state_stack);
         }
@@ -303,7 +342,7 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
         match heap_val {
             HeapCellValue::NamedStr(arity, name, fixity) => {
                 let ct = ClauseType::from(name, arity, fixity);
-                self.formatter.format_clause(arity, ct, &mut self.state_stack)
+                self.formatter.format_clause(iter, arity, ct, &mut self.state_stack)
             },
             HeapCellValue::Addr(Addr::Con(Constant::EmptyList)) =>
                 if !self.at_cdr("") {
@@ -349,6 +388,8 @@ impl<'a, Formatter: HCValueFormatter, Outputter: HCValueOutputter>
 //                        self.outputter.append(" "),
                     TokenOrRedirect::Atom(atom) =>
                         self.outputter.append(atom.as_str()),
+                    TokenOrRedirect::NumberedVar(num_var) =>
+                        self.outputter.append(num_var.as_str()),
                     TokenOrRedirect::Redirect =>
                         self.handle_heap_term(&mut iter),
                     TokenOrRedirect::Close =>
index 71fdde36f8fe0ef6c4f9e320b023cb91e26c55e9..6b78785d8a44d113c35bc2e07552df29ab17428e 100644 (file)
@@ -1,7 +1,6 @@
 use prolog::ast::*;
 use prolog::heap_print::*;
 use prolog::machine::*;
-use prolog::ordered_float::OrderedFloat;
 
 use termion::raw::IntoRawMode;
 use termion::input::TermRead;
index 825700996fe63e230b34c81856cd4c8522076cb3..859a6a4055f7fd3462125260f9d6f2e4f46c84d1 100644 (file)
@@ -494,7 +494,7 @@ pub(crate) trait CallPolicy: Any {
             },
             &BuiltInClauseType::Writeq => {
                 let output = machine_st.print_term(machine_st[temp_v!(1)].clone(),
-                                                   DisplayFormatter {},
+                                                   WriteqFormatter {},
                                                    PrinterOutputter::new());
 
                 println!("{}", output.result());