]> Repositorios git - scryer-prolog.git/commitdiff
library(charsio): add to_upper and to_lower
authorAdrián Arroyo Calle <[email protected]>
Tue, 18 Apr 2023 16:48:59 +0000 (18:48 +0200)
committerAdrián Arroyo Calle <[email protected]>
Tue, 18 Apr 2023 16:58:09 +0000 (18:58 +0200)
src/lib/charsio.pl
src/machine/system_calls.rs

index 6b43cc7d1173700bf82f36f2fd6e0526303e462f..0f19a8db6e68bd2729cc294abe4e08539e7b9af1 100644 (file)
@@ -104,7 +104,32 @@ extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :-
 % - `symbolic_control`
 % - `symbolic_hexadecimal`
 % - `upper`
+% - `to_lower(Lower)`
+% - `to_upper(Upper)`
 % - `whitespace`
+%
+% An example:
+%
+% ```
+% ?- char_type(a, Type).
+%    Type = alnum
+% ;  Type = alpha
+% ;  Type = alphabetic
+% ;  Type = alphanumeric
+% ;  Type = ascii
+% ;  Type = ascii_graphic
+% ;  Type = hexadecimal_digit
+% ;  Type = lower
+% ;  Type = octet
+% ;  Type = prolog
+% ;  Type = symbolic_control
+% ;  Type = to_lower("a")
+% ;  Type = to_upper("A")
+% ;  false.
+% ```
+%
+% Note that uppercase and lowercase transformations use a string. This is because
+% some characters do not map 1:1 between lowercase and uppercase.
 char_type(Char, Type) :-
         must_be(character, Char),
         (   ground(Type) ->
@@ -142,6 +167,8 @@ ctype(sign).
 ctype(solo).
 ctype(symbolic_control).
 ctype(symbolic_hexadecimal).
+ctype(to_lower(_)).
+ctype(to_upper(_)).
 ctype(upper).
 ctype(whitespace).
 
index 70dd649fc8e8f54b05fc5c03d67d6eea3f1ee47d..21f3057c679040966a2480d305dc3156df7d7140 100644 (file)
@@ -2723,69 +2723,100 @@ impl Machine {
                 unreachable!()
             }
         );
-
-        let chars = cell_as_atom!(a2);
+       
         self.machine_st.fail = true; // This predicate fails by default.
 
-        macro_rules! macro_check {
-            ($id:ident, $name:expr) => {
-                if $id!(c) && chars == $name {
-                    self.machine_st.fail = false;
-                    return;
-                }
-            };
-        }
+        read_heap_cell!(a2,
+           (HeapCellValueTag::Atom, (chars, _arity)) => {
+                macro_rules! macro_check {
+                   ($id:ident, $name:expr) => {
+                       if $id!(c) && chars == $name {
+                           self.machine_st.fail = false;
+                           return;
+                       }
+                   };
+               }
 
-        macro_rules! method_check {
-            ($id:ident, $name:expr) => {
-                if c.$id() && chars == $name {
-                    self.machine_st.fail = false;
-                    return;
-                }
-            };
-        }
+               macro_rules! method_check {
+                   ($id:ident, $name:expr) => {
+                       if c.$id() && chars == $name {
+                           self.machine_st.fail = false;
+                           return;
+                       }
+                   };
+               }
+
+               macro_check!(alpha_char, atom!("alpha"));
+               method_check!(is_alphabetic, atom!("alphabetic"));
+               method_check!(is_alphanumeric, atom!("alphanumeric"));
+               macro_check!(alpha_numeric_char, atom!("alnum"));
+               method_check!(is_ascii, atom!("ascii"));
+               method_check!(is_ascii_punctuation, atom!("ascii_ponctuaction"));
+               method_check!(is_ascii_graphic, atom!("ascii_graphic"));
+               // macro_check!(backslash_char, atom!("backslash"));
+               // macro_check!(back_quote_char, atom!("back_quote"));
+               macro_check!(binary_digit_char, atom!("binary_digit"));
+               // macro_check!(capital_letter_char, atom!("upper"));
+               // macro_check!(comment_1_char, "comment_1");
+               // macro_check!(comment_2_char, "comment_2");
+               method_check!(is_control, atom!("control"));
+               // macro_check!(cut_char, atom!("cut"));
+               macro_check!(decimal_digit_char, atom!("decimal_digit"));
+               // macro_check!(decimal_point_char, atom!("decimal_point"));
+               // macro_check!(double_quote_char, atom!("double_quote"));
+               macro_check!(exponent_char, atom!("exponent"));
+               macro_check!(graphic_char, atom!("graphic"));
+               macro_check!(graphic_token_char, atom!("graphic_token"));
+               macro_check!(hexadecimal_digit_char, atom!("hexadecimal_digit"));
+               macro_check!(layout_char, atom!("layout"));
+               method_check!(is_lowercase, atom!("lower"));
+               macro_check!(meta_char, atom!("meta"));
+               // macro_check!(new_line_char, atom!("new_line"));
+               method_check!(is_numeric, atom!("numeric"));
+               macro_check!(octal_digit_char, atom!("octal_digit"));
+               macro_check!(octet_char, atom!("octet"));
+               macro_check!(prolog_char, atom!("prolog"));
+               // macro_check!(semicolon_char, atom!("semicolon"));
+               macro_check!(sign_char, atom!("sign"));
+               // macro_check!(single_quote_char, atom!("single_quote"));
+               // macro_check!(small_letter_char, atom!("lower"));
+               macro_check!(solo_char, atom!("solo"));
+               // macro_check!(space_char, atom!("space"));
+               macro_check!(symbolic_hexadecimal_char, atom!("symbolic_hexadecimal"));
+               macro_check!(symbolic_control_char, atom!("symbolic_control"));
+               method_check!(is_uppercase, atom!("upper"));
+               // macro_check!(variable_indicator_char, atom!("variable_indicator"));
+               method_check!(is_whitespace, atom!("whitespace"));              
+           }
+            (HeapCellValueTag::Str, s) => {
+               let (name, arity) = cell_as_atom_cell!(self.machine_st.heap[s])
+                   .get_name_and_arity();
+               
+               match (name, arity) {
+                   (atom!("to_upper"), 1) => {
+                       let reg = self.machine_st.heap[s+1];
+                       let upper_str = self.machine_st.atom_tbl.build_with(&c.to_uppercase().to_string());
+                       self.machine_st.unify_complete_string(upper_str, reg);
+                       self.machine_st.fail = false;
+                   }
+                   (atom!("to_lower"), 1) => {
+                       let reg = self.machine_st.heap[s+1];
+                       let lower_str = self.machine_st.atom_tbl.build_with(&c.to_lowercase().to_string());
+                       self.machine_st.unify_complete_string(lower_str, reg);
+                       self.machine_st.fail = false;
+                   }               
+                   _ => {
+                       unreachable!()
+                   }
+               };
+           }
+            _ => {
+               unreachable!()
+           }
+       );
+               
 
-        macro_check!(alpha_char, atom!("alpha"));
-        method_check!(is_alphabetic, atom!("alphabetic"));
-        method_check!(is_alphanumeric, atom!("alphanumeric"));
-        macro_check!(alpha_numeric_char, atom!("alnum"));
-        method_check!(is_ascii, atom!("ascii"));
-        method_check!(is_ascii_punctuation, atom!("ascii_ponctuaction"));
-        method_check!(is_ascii_graphic, atom!("ascii_graphic"));
-        // macro_check!(backslash_char, atom!("backslash"));
-        // macro_check!(back_quote_char, atom!("back_quote"));
-        macro_check!(binary_digit_char, atom!("binary_digit"));
-        // macro_check!(capital_letter_char, atom!("upper"));
-        // macro_check!(comment_1_char, "comment_1");
-        // macro_check!(comment_2_char, "comment_2");
-        method_check!(is_control, atom!("control"));
-        // macro_check!(cut_char, atom!("cut"));
-        macro_check!(decimal_digit_char, atom!("decimal_digit"));
-        // macro_check!(decimal_point_char, atom!("decimal_point"));
-        // macro_check!(double_quote_char, atom!("double_quote"));
-        macro_check!(exponent_char, atom!("exponent"));
-        macro_check!(graphic_char, atom!("graphic"));
-        macro_check!(graphic_token_char, atom!("graphic_token"));
-        macro_check!(hexadecimal_digit_char, atom!("hexadecimal_digit"));
-        macro_check!(layout_char, atom!("layout"));
-        method_check!(is_lowercase, atom!("lower"));
-        macro_check!(meta_char, atom!("meta"));
-        // macro_check!(new_line_char, atom!("new_line"));
-        method_check!(is_numeric, atom!("numeric"));
-        macro_check!(octal_digit_char, atom!("octal_digit"));
-        macro_check!(octet_char, atom!("octet"));
-        macro_check!(prolog_char, atom!("prolog"));
-        // macro_check!(semicolon_char, atom!("semicolon"));
-        macro_check!(sign_char, atom!("sign"));
-        // macro_check!(single_quote_char, atom!("single_quote"));
-        // macro_check!(small_letter_char, atom!("lower"));
-        macro_check!(solo_char, atom!("solo"));
-        // macro_check!(space_char, atom!("space"));
-        macro_check!(symbolic_hexadecimal_char, atom!("symbolic_hexadecimal"));
-        macro_check!(symbolic_control_char, atom!("symbolic_control"));
-        method_check!(is_uppercase, atom!("upper"));
-        // macro_check!(variable_indicator_char, atom!("variable_indicator"));
-        method_check!(is_whitespace, atom!("whitespace"));
+        
     }
 
     #[inline(always)]