From e3a7f9eb7a9db05a67419e8ae64bfdd5ce8163d7 Mon Sep 17 00:00:00 2001 From: notoria Date: Wed, 22 Apr 2020 00:46:54 +0200 Subject: [PATCH] Draft of an implementation of char_type --- src/prolog/clause_types.rs | 3 ++ src/prolog/lib/charsio.pl | 9 ++++- src/prolog/machine/system_calls.rs | 65 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index c3d79b63..53d0f8e1 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -158,6 +158,7 @@ pub enum SystemClauseType { BindFromRegister, CallContinuation, CharCode, + CharType, CharsToNumber, ClearAttributeGoals, CloneAttributeGoals, @@ -278,6 +279,7 @@ impl SystemClauseType { &SystemClauseType::BindFromRegister => clause_name!("$bind_from_register"), &SystemClauseType::CallContinuation => clause_name!("$call_continuation"), &SystemClauseType::CharCode => clause_name!("$char_code"), + &SystemClauseType::CharType => clause_name!("$char_type"), &SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"), &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"), &SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"), @@ -432,6 +434,7 @@ impl SystemClauseType { ("$assertz", 4) => Some(SystemClauseType::AssertDynamicPredicateToBack), ("$call_continuation", 1) => Some(SystemClauseType::CallContinuation), ("$char_code", 2) => Some(SystemClauseType::CharCode), + ("$char_type", 2) => Some(SystemClauseType::CharType), ("$chars_to_number", 2) => Some(SystemClauseType::CharsToNumber), ("$clear_attribute_goals", 0) => Some(SystemClauseType::ClearAttributeGoals), ("$clone_attribute_goals", 1) => Some(SystemClauseType::CloneAttributeGoals), diff --git a/src/prolog/lib/charsio.pl b/src/prolog/lib/charsio.pl index 717bbaaa..0281e832 100644 --- a/src/prolog/lib/charsio.pl +++ b/src/prolog/lib/charsio.pl @@ -1,4 +1,4 @@ -:- module(charsio, [get_single_char/1, +:- module(charsio, [char_type/2, get_single_char/1, read_term_from_chars/2, write_term_to_chars/3]). @@ -57,6 +57,13 @@ extend_var_list_([V|Vs], N, VarList, NewVarList, VarType) :- ). +char_type(C, T) :- + ( var(C) -> throw(error(instantiation_error, char_type/2)) + ; atom_length(C, 1) -> '$char_type'(C, T) + ; throw(error(type_error(in_character, C), char_type/2)) + ). + + get_single_char(C) :- ( var(C) -> '$get_single_char'(C) ; atom_length(C, 1) -> '$get_single_char'(C) diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 63bb8c79..e07c9eb7 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -1337,6 +1337,71 @@ impl MachineState { } }; } + &SystemClauseType::CharType => { + let a1 = self.store(self.deref(self[temp_v!(1)])); + let a2 = self.store(self.deref(self[temp_v!(2)])); + + let c = match a1 { + Addr::Char(c) => c, + Addr::Con(h) if self.heap.atom_at(h) => { + if let HeapCellValue::Atom(name, _) = &self.heap[h] { + name.as_str().chars().next().unwrap() + } + else { + unreachable!() + } + } + _ => unreachable!() + }; + macro_rules! call { + ($id:ident, $name:tt) => { + if $id!(c) { + // let string = $name; + // let chars = + // clause_name!(string.to_string(), indices.atom_tbl); + // let atom = self + // .heap + // .to_unifiable(HeapCellValue::Atom(chars, None)); + let atom = self.heap.to_unifiable( + HeapCellValue::Atom(clause_name!($name.to_string(), indices.atom_tbl), None) + ); + + self.unify(atom, a2); + } + } + } + call!(symbolic_control_char, "symbolic_control"); + call!(space_char, "space"); + call!(layout_char, "layout"); + call!(symbolic_hexadecimal_char, "symbolic_hexadecimal"); + call!(octal_digit_char, "octal_digit"); + call!(binary_digit_char, "binary_digit"); + call!(hexadecimal_digit_char, "hexadecimal_digit"); + call!(exponent_char, "exponent"); + call!(sign_char, "sign"); + //call!(new_line_char, "new_line"); + //call!(comment_1_char, "comment_1"); + //call!(comment_2_char, "comment_2"); + //call!(capital_letter_char, "upper"); + //call!(small_letter_char, "lower"); + //call!(variable_indicator_char, "variable_indicator"); + //call!(graphic_char, "graphic"); + //call!(graphic_token_char, "graphic_token"); + //call!(alpha_char, "alpha"); + //call!(decimal_digit_char, "decimal_digit"); + //call!(decimal_point_char, "decimal_point"); + call!(alpha_numeric_char, "alnum"); + //call!(cut_char, "cut"); + //call!(semicolon_char, "semicolon"); + //call!(backslash_char, "backslash"); + //call!(single_quote_char, "single_quote"); + //call!(double_quote_char, "double_quote"); + //call!(back_quote_char, "back_quote"); + //call!(meta_char, "meta"); + //call!(solo_char, "solo"); + //call!(prolog_char, "prolog"); + //self.fail = true; + } &SystemClauseType::CheckCutPoint => { let addr = self.store(self.deref(self[temp_v!(1)])); -- 2.54.0