]> Repositorios git - scryer-prolog.git/commitdiff
add some prolog flags, tabled strings
authorMark Thom <[email protected]>
Sun, 19 Aug 2018 00:03:28 +0000 (18:03 -0600)
committerMark Thom <[email protected]>
Sun, 19 Aug 2018 00:03:28 +0000 (18:03 -0600)
src/prolog/ast.rs
src/prolog/lib/builtins.pl
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/system_calls.rs
src/prolog/parser

index 7c5bc6e1b13502388049cf8a816f7c8d4a852f68..b67c33911c5cf12e98f1a9c74352d3f2bfcdd328 100644 (file)
@@ -531,7 +531,7 @@ pub enum Constant {
     Atom(ClauseName),
     Char(char),
     Number(Number),
-    String(Rc<String>),
+    String(TabledRc<String>),
     Usize(usize),
     EmptyList
 }
@@ -725,10 +725,12 @@ pub enum SystemClauseType {
     GetBall,
     GetCurrentBlock,
     GetCutPoint,
+    GetDoubleQuotes,
     InstallNewBlock,
     ResetBlock,
     SetBall,
     SetCutPointByDefault(RegType),
+    SetDoubleQuotes,
     SkipMaxList,
     Succeed,
     UnwindStack
@@ -743,6 +745,7 @@ impl SystemClauseType {
         match self {
             &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
             &SystemClauseType::GetBValue => clause_name!("$get_b_value"),
+            &SystemClauseType::GetDoubleQuotes => clause_name!("$get_double_quotes"),
             &SystemClauseType::GetSCCCleaner => clause_name!("$get_scc_cleaner"),
             &SystemClauseType::InstallSCCCleaner => clause_name!("$install_scc_cleaner"),
             &SystemClauseType::InstallInferenceCounter =>
@@ -764,6 +767,7 @@ impl SystemClauseType {
             &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
             &SystemClauseType::SetBall => clause_name!("$set_ball"),
             &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
+            &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"),
             &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"),
             &SystemClauseType::Succeed => clause_name!("$succeed"),
             &SystemClauseType::UnwindStack => clause_name!("$unwind_stack"),
@@ -774,6 +778,7 @@ impl SystemClauseType {
         match (name, arity) {
             ("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
             ("$get_b_value", 1) => Some(SystemClauseType::GetBValue),
+            ("$get_double_quotes", 1) => Some(SystemClauseType::GetDoubleQuotes),
             ("$get_scc_cleaner", 1) => Some(SystemClauseType::GetSCCCleaner),
             ("$install_scc_cleaner", 2) =>
                 Some(SystemClauseType::InstallSCCCleaner),
@@ -796,6 +801,7 @@ impl SystemClauseType {
             ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
             ("$set_ball", 1) => Some(SystemClauseType::SetBall),
             ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
+            ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes),
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
             ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
             _ => None
index ace096a0487aa269f46ff1d063fc2a1a3ba59673..d15b3f25b71cd5ea5760c4f6274451ab21b5e7f3 100644 (file)
@@ -6,6 +6,7 @@
        (-)/1, (>=)/2, (=<)/2, (,)/2, (->)/2, (;)/2, (=..)/2, (==)/2,
        (\==)/2, (@=<)/2, (@>=)/2, (@<)/2, (@>)/2, (=@=)/2, (\=@=)/2,
        (:)/2, call_with_inference_limit/3, catch/3,
+       current_prolog_flag/2, set_prolog_flag/2,
        setup_call_cleanup/3, throw/1, true/0, false/0]).
 
 /* this is an implementation specific declarative operator used to implement call_with_inference_limit/3
@@ -70,6 +71,53 @@ true.
 
 false :- '$fail'.
 
+% flags.
+
+current_prolog_flag(Flag, false) :- Flag == bounded, !.
+current_prolog_flag(bounded, false).
+current_prolog_flag(Flag, down) :- Flag == integer_rounding_function, !.
+current_prolog_flag(integer_rounding_function, down).
+current_prolog_flag(Flag, Value) :- Flag == double_quotes, !, '$get_double_quotes'(Value).
+current_prolog_flag(double_quotes, Value) :- '$get_double_quotes'(Value).
+current_prolog_flag(Flag, _) :- Flag == max_integer, !, '$fail'.
+current_prolog_flag(Flag, _) :- Flag == min_integer, !, '$fail'.
+current_prolog_flag(Flag, _) :-
+    atom(Flag),
+    throw(error(domain_error(prolog_flag, Flag), current_prolog_flag/2)). % 8.17.2.3 b
+current_prolog_flag(Flag, _) :-
+    nonvar(Flag),
+    throw(error(type_error(atom, Flag), current_prolog_flag/2)). % 8.17.2.3 a
+
+set_prolog_flag(Flag, Value) :-
+    (var(Flag) ; var(Value)),
+    throw(error(instantiation_error, set_prolog_flag/2)). % 8.17.1.3 a, b
+set_prolog_flag(bounded, false) :- !. % 7.11.1.1
+set_prolog_flag(bounded, true)  :- !, '$fail'. % 7.11.1.1
+set_prolog_flag(bounded, Value) :-
+    throw(error(domain_error(flag_value, bounded + Value), set_prolog_flag/2)). % 8.17.1.3 e
+set_prolog_flag(max_integer, Value) :- integer(Value), !, '$fail'. % 7.11.1.2
+set_prolog_flag(max_integer, Value) :-
+    throw(error(domain_error(flag_value, max_integer + Value), set_prolog_flag/2)). % 8.17.1.3 e
+set_prolog_flag(min_integer, Value) :- integer(Value), !, '$fail'. % 7.11.1.3
+set_prolog_flag(min_integer, Value) :-
+    throw(error(domain_error(flag_value, min_integer + Value), set_prolog_flag/2)). % 8.17.1.3 e
+set_prolog_flag(integer_rounding_function, down) :- !. % 7.11.1.4
+set_prolog_flag(integer_rounding_function, Value) :-
+    throw(error(domain_error(flag_value, integer_rounding_function + Value),
+               set_prolog_flag/2)). % 8.17.1.3 e
+set_prolog_flag(double_quotes, chars) :-
+    !, '$set_double_quotes'(chars). % 7.11.2.5, list of one-char atoms.
+set_prolog_flag(double_quotes, atom) :-
+    !, '$set_double_quotes'(atom). % 7.11.2.5, list of one-char atoms.
+set_prolog_flag(double_quotes, Value) :-
+    throw(error(domain_error(flag_value, double_quotes + Value),
+               set_prolog_flag/2)). % 8.17.1.3 e
+set_prolog_flag(Flag, _) :-
+    atom(Flag),
+    throw(error(domain_error(prolog_flag, Flag), set_prolog_flag/2)). % 8.17.1.3 d
+set_prolog_flag(Flag, _) :-
+    throw(error(type_error(atom, Flag), set_prolog_flag/2)). % 8.17.1.3 c
+
 % control operators.
 
 ','(G1, G2) :- '$get_b_value'(B), ','(G1, G2, B).
index 73be6ceb66ed86d73bd1ce2afa016a7ec39561ae..6403de19766a9267c63f6a82364850a56f7f5e87 100644 (file)
@@ -264,6 +264,28 @@ pub(super) enum MachineMode {
     Write
 }
 
+#[derive(Clone, Copy)]
+pub(super) enum DoubleQuotes {
+    Atom, Chars, // Codes
+}
+
+impl Default for DoubleQuotes {
+    fn default() -> Self {
+        DoubleQuotes::Chars
+    }
+}
+
+#[derive(Clone, Copy)]
+pub(super) struct MachineFlags {
+    pub(super) double_quotes: DoubleQuotes
+}
+
+impl Default for MachineFlags {
+    fn default() -> Self {
+        MachineFlags { double_quotes: DoubleQuotes::default() }
+    }
+}
+
 pub struct MachineState {
     pub(crate) atom_tbl: TabledData<Atom>,
     pub(super) s: usize,
@@ -285,7 +307,8 @@ pub struct MachineState {
     pub(super) block: usize, // an offset into the OR stack.
     pub(super) ball: Ball,
     pub(super) interms: Vec<Number>, // intermediate numbers.
-    pub(super) last_call: bool
+    pub(super) last_call: bool,
+    pub(super) flags: MachineFlags
 }
 
 fn call_at_index(machine_st: &mut MachineState, module_name: ClauseName, arity: usize, idx: usize)
index f199f0585cae93b27be01e57cebd4dcce2d5e01b..a0101fd5b5d6ac1e4946b6aff730b40e310b7337 100644 (file)
@@ -50,7 +50,8 @@ impl MachineState {
             block: 0,
             ball: Ball::new(),
             interms: vec![Number::default(); 256],
-            last_call: false
+            last_call: false,
+            flags: MachineFlags::default()
         }
     }
 
index d4eec16781bcc03688b609e296c1e7ac89b70486..e99d70015bc40bf286b126179b7a04b2c2189fc2 100644 (file)
@@ -195,6 +195,16 @@ impl MachineState {
                     _ => self.fail = true
                 };
             },
+            &SystemClauseType::GetDoubleQuotes => {
+                let a1 = self[temp_v!(1)].clone();
+                
+                match self.flags.double_quotes {
+                    DoubleQuotes::Chars =>
+                        self.unify(a1, Addr::Con(atom!("chars"))),
+                    DoubleQuotes::Atom =>
+                        self.unify(a1, Addr::Con(atom!("atom")))
+                }
+            },
             &SystemClauseType::GetSCCCleaner => {
                 let dest = self[temp_v!(1)].clone();
 
@@ -330,6 +340,14 @@ impl MachineState {
             },
             &SystemClauseType::SetCutPointByDefault(r) =>
                 deref_cut(self, r),
+            &SystemClauseType::SetDoubleQuotes =>
+                match self[temp_v!(1)].clone() {
+                    Addr::Con(Constant::Atom(ref atom)) if atom.as_str() == "chars" =>
+                        self.flags.double_quotes = DoubleQuotes::Chars,
+                    Addr::Con(Constant::Atom(ref atom)) if atom.as_str() == "atom" =>
+                        self.flags.double_quotes = DoubleQuotes::Atom,
+                    _ => self.fail = true
+                },
             &SystemClauseType::InferenceLevel => {
                 let a1 = self[temp_v!(1)].clone();
                 let a2 = self.store(self.deref(self[temp_v!(2)].clone()));
index 6a7545257bbfc660b37a0bc3d7a72edb244dda86..0d10b8e4b736f54940b58cf111ac1f3290b29340 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 6a7545257bbfc660b37a0bc3d7a72edb244dda86
+Subproject commit 0d10b8e4b736f54940b58cf111ac1f3290b29340