Skip to content

Commit

Permalink
add redone partial strings (#24, #95)
Browse files Browse the repository at this point in the history
  • Loading branch information
mthom committed Feb 20, 2020
1 parent 617f803 commit 0457b38
Show file tree
Hide file tree
Showing 16 changed files with 1,420 additions and 288 deletions.
11 changes: 10 additions & 1 deletion src/prolog/clause_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub enum SystemClauseType {
CopyTermWithoutAttrVars,
CheckCutPoint,
CopyToLiftedHeap,
CreatePartialString,
DeleteAttribute,
DeleteHeadAttribute,
DynamicModuleResolution(usize),
Expand All @@ -194,6 +195,7 @@ pub enum SystemClauseType {
GetModuleClause,
GetNextDBRef,
GetNextOpDBRef,
IsPartialString,
LookupDBRef,
LookupOpDBRef,
Halt,
Expand All @@ -215,6 +217,7 @@ pub enum SystemClauseType {
NumberToChars,
NumberToCodes,
OpDeclaration,
PartialStringTail,
PointsToContinuationResetMarker,
REPL(REPLCodePtr),
ReadQueryTerm,
Expand Down Expand Up @@ -275,11 +278,12 @@ impl SystemClauseType {
&SystemClauseType::CallContinuation => clause_name!("$call_continuation"),
&SystemClauseType::CharCode => clause_name!("$char_code"),
&SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
&SystemClauseType::ClearAttributeGoals => clause_name!("$clear_attribute_goals"),
&SystemClauseType::CloneAttributeGoals => clause_name!("$clone_attribute_goals"),
&SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
&SystemClauseType::CopyTermWithoutAttrVars => clause_name!("$copy_term_without_attr_vars"),
&SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
&SystemClauseType::CreatePartialString => clause_name!("$create_partial_string"),
&SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
&SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
&SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
Expand Down Expand Up @@ -339,6 +343,8 @@ impl SystemClauseType {
&SystemClauseType::InstallInferenceCounter => {
clause_name!("$install_inference_counter")
}
&SystemClauseType::IsPartialString => clause_name!("$is_partial_string"),
&SystemClauseType::PartialStringTail => clause_name!("$partial_string_tail"),
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
&SystemClauseType::Maybe => clause_name!("maybe"),
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
Expand Down Expand Up @@ -423,6 +429,7 @@ impl SystemClauseType {
("$clone_attribute_goals", 1) => Some(SystemClauseType::CloneAttributeGoals),
("$codes_to_number", 2) => Some(SystemClauseType::CodesToNumber),
("$copy_term_without_attr_vars", 2) => Some(SystemClauseType::CopyTermWithoutAttrVars),
("$create_partial_string", 3) => Some(SystemClauseType::CreatePartialString),
("$check_cp", 1) => Some(SystemClauseType::CheckCutPoint),
("$compile_batch", 0) => Some(SystemClauseType::REPL(REPLCodePtr::CompileBatch)),
("$copy_to_lh", 2) => Some(SystemClauseType::CopyToLiftedHeap),
Expand All @@ -435,6 +442,8 @@ impl SystemClauseType {
("$module_call", _) => Some(SystemClauseType::DynamicModuleResolution(arity - 2)),
("$enqueue_attribute_goal", 1) => Some(SystemClauseType::EnqueueAttributeGoal),
("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
("$partial_string_tail", 2) => Some(SystemClauseType::PartialStringTail),
("$is_partial_string", 1) => Some(SystemClauseType::IsPartialString),
("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
("$fetch_attribute_goals", 1) => Some(SystemClauseType::FetchAttributeGoals),
Expand Down
62 changes: 56 additions & 6 deletions src/prolog/heap_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,19 @@ impl<'a> HCPreOrderIterator<'a> {

fn follow_heap(&mut self, h: usize) -> Addr {
match &self.machine_st.heap[h] {
&HeapCellValue::NamedStr(arity, _, _) => {
HeapCellValue::NamedStr(arity, _, _) => {
for idx in (1..arity + 1).rev() {
self.state_stack.push(Addr::HeapCell(h + idx));
}

Addr::HeapCell(h)
Addr::Str(h)
}
HeapCellValue::Addr(ref a) => {
self.follow(a.clone())
}
HeapCellValue::PartialString(_) => {
self.follow(Addr::PStrLocation(h, 0))
}
&HeapCellValue::Addr(ref a) => self.follow(a.clone()),
}
}

Expand All @@ -51,7 +56,7 @@ impl<'a> HCPreOrderIterator<'a> {
if s.len() > n {
if let Some(c) = s[n ..].chars().next() {
let o = c.len_utf8();

self.state_stack.push(Addr::Con(Constant::String(n+o, s.clone())));

if self.machine_st.machine_flags().double_quotes.is_codes() {
Expand All @@ -76,7 +81,28 @@ impl<'a> HCPreOrderIterator<'a> {

da
}
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) => {
Addr::PStrLocation(h, n) => {
if let HeapCellValue::PartialString(ref pstr) = &self.machine_st.heap[h] {
let s = pstr.block_as_str();

if let Some(c) = s[n ..].chars().next() {
if pstr.len() > n + c.len_utf8() {
self.state_stack.push(Addr::PStrLocation(h, n + c.len_utf8()));
} else {
self.state_stack.push(Addr::PStrTail(h, n + c.len_utf8()));
}

self.state_stack.push(Addr::Con(Constant::Char(c)));
} else {
unreachable!()
}
} else {
unreachable!()
}

Addr::PStrLocation(h, n)
}
Addr::AttrVar(_) | Addr::HeapCell(_) | Addr::StackCell(_, _) | Addr::PStrTail(..) => {
da
}
Addr::Str(s) => {
Expand All @@ -92,7 +118,31 @@ impl<'a> Iterator for HCPreOrderIterator<'a> {
fn next(&mut self) -> Option<Self::Item> {
self.state_stack.pop().map(|a| match self.follow(a) {
Addr::HeapCell(h) => {
self.machine_st.heap[h].clone()
HeapCellValue::Addr(self.machine_st.heap[h].as_addr(h))
}
Addr::Str(s) => {
match &self.machine_st.heap[s] {
val @ HeapCellValue::NamedStr(..) => {
val.clone()
}
_ => {
unreachable!()
}
}
}
Addr::PStrTail(h, n) => {
match &self.machine_st.heap[h] {
HeapCellValue::PartialString(ref pstr) => {
if pstr.len() > n {
HeapCellValue::Addr(Addr::PStrLocation(h, n))
} else {
HeapCellValue::Addr(pstr.tail_addr().clone())
}
}
_ => {
unreachable!()
}
}
}
Addr::StackCell(fr, sc) => {
HeapCellValue::Addr(self.machine_st.stack.index_and_frame(fr)[sc].clone())
Expand Down
23 changes: 18 additions & 5 deletions src/prolog/heap_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,10 +616,18 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}

match addr {
Addr::AttrVar(h) => Some(format!("_{}", h)),
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) => Some(format!("_{}", h)),
Addr::StackCell(fr, sc) => Some(format!("_s_{}_{}", fr, sc)),
_ => None,
Addr::AttrVar(h) => {
Some(format!("_{}", h))
}
Addr::HeapCell(h) | Addr::Lis(h) | Addr::Str(h) | Addr::PStrTail(h, _) => {
Some(format!("_{}", h))
}
Addr::StackCell(fr, sc) => {
Some(format!("_s_{}_{}", fr, sc))
}
_ => {
None
}
}
}

Expand Down Expand Up @@ -944,7 +952,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
}
}
HeapCellValue::Addr(Addr::Con(c)) => self.print_constant(c, &op),
HeapCellValue::Addr(Addr::Lis(_)) => {
HeapCellValue::Addr(Addr::Lis(_)) | HeapCellValue::Addr(Addr::PStrLocation(..)) => {
if self.ignore_ops {
self.format_struct(2, clause_name!("."));
} else {
Expand All @@ -958,6 +966,11 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
})
}
}
_ => {
// This is the partial string case. We never clone a partial string
// for printing purposes, so.. this.
unreachable!()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/prolog/lib/builtins.pl
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
:- non_counted_backtracking univ_errors/3.
univ_errors(Term, List, N) :-
'$skip_max_list'(N, -1, List, R),
( var(R) ->
( var(R) ->
( var(Term), throw(error(instantiation_error, (=..)/2)) % 8.5.3.3 a)
; true
)
Expand Down
21 changes: 20 additions & 1 deletion src/prolog/lib/non_iso.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

:- module(non_iso, [bb_b_put/2, bb_get/2, bb_put/2, call_cleanup/2,
call_with_inference_limit/3, forall/2, maybe/0,
set_random/1, setup_call_cleanup/3, variant/2]).
partial_string/1, partial_string/3,
partial_string_tail/2, set_random/1,
setup_call_cleanup/3, variant/2]).

forall(Generate, Test) :-
\+ (Generate, \+ Test).
Expand Down Expand Up @@ -154,3 +156,20 @@
)
; throw(error(instantiation_error, set_random/1))
).

partial_string(String, L, L0) :-
( String == [] -> throw(error(type_error(list, []), partial_string/3))
; catch(atom_chars(Atom, String),
error(E, _),
throw(error(E, partial_string/3)))
),
'$create_partial_string'(Atom, L, L0).

partial_string(String) :-
'$is_partial_string'(String).

partial_string_tail(String, Tail) :-
( partial_string(String) ->
'$partial_string_tail'(String, Tail)
; throw(error(type_error(partial_string, String), partial_string_tail/2))
).
Loading

0 comments on commit 0457b38

Please sign in to comment.