From 4b882c465c0169e3f11420db6a44751b0468ae75 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Adri=C3=A1n=20Arroyo=20Calle?= Date: Tue, 18 Apr 2023 18:48:59 +0200 Subject: [PATCH] library(charsio): add to_upper and to_lower --- src/lib/charsio.pl | 27 +++++++ src/machine/system_calls.rs | 149 ++++++++++++++++++++++-------------- 2 files changed, 117 insertions(+), 59 deletions(-) diff --git a/src/lib/charsio.pl b/src/lib/charsio.pl index 6b43cc7d..0f19a8db 100644 --- a/src/lib/charsio.pl +++ b/src/lib/charsio.pl @@ -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). diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 70dd649f..21f3057c 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -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)] -- 2.54.0