let stream = current_input_stream.clone();
match addr {
- addr if addr.is_ref() => {
+ addr if addr.is_ref() => {
self.unify(Addr::Stream(stream), addr);
}
Addr::Stream(other_stream) => {
return Err(self.error_form(err, stub));
}
- }
+ }
}
&SystemClauseType::CurrentOutput => {
let addr = self.store(self.deref(self[temp_v!(1)].clone()));
let stream = current_output_stream.clone();
match addr {
- addr if addr.is_ref() => {
+ addr if addr.is_ref() => {
self.unify(Addr::Stream(stream), addr);
}
Addr::Stream(other_stream) => {
Addr::Con(Constant::Atom(name, _)) => {
let c = name.as_str().chars().next().unwrap();
let a2 = self[temp_v!(2)].clone();
+ let c = Integer::from(c as u32);
- self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
+ self.unify(Addr::Con(Constant::Integer(c)), a2);
}
Addr::Con(Constant::Char(c)) => {
let a2 = self[temp_v!(2)].clone();
- self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
+ let c = Integer::from(c as u32);
+
+ self.unify(Addr::Con(Constant::Integer(c)), a2);
}
- ref addr if addr.is_ref() => {
+ addr if addr.is_ref() => {
let a2 = self[temp_v!(2)].clone();
match self.store(self.deref(a2)) {
- Addr::Con(Constant::Char(code)) => {
- self.unify(Addr::Con(Constant::Char(code)), addr.clone())
+ Addr::Con(Constant::CharCode(code)) => {
+ if let Some(c) = std::char::from_u32(code) {
+ self.unify(Addr::Con(Constant::Char(c)), addr);
+ } else {
+ self.fail = true;
+ }
}
Addr::Con(Constant::Integer(n)) => {
let c = self.int_to_char_code(&n, "char_code", 2)?;
- let c = std::char::from_u32(c).unwrap();
- self.unify(Addr::Con(Constant::Char(c)), addr.clone());
+ if let Some(c) = std::char::from_u32(c) {
+ self.unify(Addr::Con(Constant::Char(c)), addr);
+ } else {
+ self.fail = true;
+ }
}
_ => self.fail = true,
};
&SystemClauseType::GetChar => {
let mut iter = parsing_stream(current_input_stream.clone());
let result = iter.next();
-
+
let a1 = self[temp_v!(1)].clone();
match result {
enable_raw_mode().expect("failed to transition into raw mode");
let result = next_keypress();
disable_raw_mode().expect("failed to transition out of raw mode");
-
+
result
};
// get the call site so that the number of active permanent variables can be read
// from it later.
let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
-
+
let p = cp.as_functor(&mut self.heap);
let e = self.stack.index_and_frame(e).prelude.e;
memberchk(EqSpec, [fx,xfx,yfx])
).
+'$fabricate_var_name'(VarName, N) :-
+ char_code('A', AC),
+ LN is N mod 26 + AC,
+ char_code(LC, LN),
+ NN is N // 26,
+ ( NN =:= 0 ->
+ atom_chars(VarName, ['_', LC])
+ ; number_chars(NN, NNChars),
+ atom_chars(VarName, ['_', LC | NNChars])
+ ).
+
+'$var_list_contains_name'([VarName = _ | VarList], VarName0) :-
+ ( VarName == VarName0 -> true
+ ; '$var_list_contains_name'(VarList, VarName0)
+ ).
+
+'$var_list_contains_variable'([_ = Var | VarList], Var0) :-
+ ( Var == Var0 -> true
+ ; '$var_list_contains_variable'(VarList, Var0)
+ ).
+
+'$make_new_var_name'(V, VarName, N, N1, VarList) :-
+ '$fabricate_var_name'(VarName0, N),
+ ( '$var_list_contains_name'(VarList, VarName0) ->
+ N0 is N + 1,
+ '$make_new_var_name'(V, VarName, N0, N1, VarList)
+ ; VarName = VarName0,
+ N1 is N + 1
+ ).
+
+'$extend_var_list'(Value, VarList, NewVarList) :-
+ term_variables(Value, Vars),
+ '$extend_var_list_'(Vars, 0, VarList, NewVarList).
+
+'$extend_var_list_'([], N, VarList, VarList).
+'$extend_var_list_'([V|Vs], N, VarList, NewVarList) :-
+ ( '$var_list_contains_variable'(VarList, V) ->
+ '$extend_var_list_'(Vs, N, VarList, NewVarList)
+ ; '$make_new_var_name'(V, VarName, N, N1, VarList),
+ NewVarList = [VarName = V | NewVarList0],
+ '$extend_var_list_'(Vs, N1, VarList, NewVarList0)
+ ).
+
'$write_goal'(G, VarList) :-
( G = (Var = Value) ->
write(Var),
'$graphic_token_char'(Char).
'$write_eqs_and_read_input'(B, VarList) :-
- sort(VarList, SortedVarList),
+ '$extend_var_list'(VarList, VarList, NewVarList),
+ sort(NewVarList, SortedVarList),
'$get_b_value'(B0),
- '$gather_goals'(SortedVarList, VarList, Goals),
+ '$gather_goals'(SortedVarList, SortedVarList, Goals),
( B0 == B ->
( Goals == [] ->
write('true.'), nl
; thread_goals(Goals, ThreadedGoals, (',')),
- '$write_eq'(ThreadedGoals, VarList),
+ '$write_eq'(ThreadedGoals, NewVarList),
write('.'),
nl
)
; thread_goals(Goals, ThreadedGoals, (',')),
- '$write_eq'(ThreadedGoals, VarList),
+ '$write_eq'(ThreadedGoals, NewVarList),
'$raw_input_read_char'(C),
( C == (';'), !,
write(' ;'), nl, false