diff --git a/src/prolog/clause_types.rs b/src/prolog/clause_types.rs index a31eba1a..98a6d902 100644 --- a/src/prolog/clause_types.rs +++ b/src/prolog/clause_types.rs @@ -251,6 +251,7 @@ pub enum SystemClauseType { SetDoubleQuotes, SetSeed, SkipMaxList, + Sleep, Succeed, TermVariables, TruncateLiftedHeapTo, @@ -287,16 +288,16 @@ impl SystemClauseType { &SystemClauseType::CurrentInput => clause_name!("$current_input"), &SystemClauseType::CurrentOutput => clause_name!("$current_output"), &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"), - &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"), - &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => { - clause_name!("$use_qualified_module") - } - &SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile) => { - clause_name!("$use_module_from_file") - } - &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => { - clause_name!("$use_qualified_module_from_file") - } + &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"), + &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => { + clause_name!("$use_qualified_module") + } + &SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile) => { + clause_name!("$use_module_from_file") + } + &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile) => { + clause_name!("$use_qualified_module_from_file") + } &SystemClauseType::CopyToLiftedHeap => clause_name!("$copy_to_lh"), &SystemClauseType::DeleteAttribute => clause_name!("$del_attr_non_head"), &SystemClauseType::DeleteHeadAttribute => clause_name!("$del_attr_head"), @@ -402,6 +403,7 @@ impl SystemClauseType { &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"), &SystemClauseType::SetDoubleQuotes => clause_name!("$set_double_quotes"), &SystemClauseType::SkipMaxList => clause_name!("$skip_max_list"), + &SystemClauseType::Sleep => clause_name!("$sleep"), &SystemClauseType::Succeed => clause_name!("$succeed"), &SystemClauseType::TermVariables => clause_name!("$term_variables"), &SystemClauseType::TruncateLiftedHeapTo => clause_name!("$truncate_lh_to"), @@ -525,6 +527,7 @@ impl SystemClauseType { ("$set_double_quotes", 1) => Some(SystemClauseType::SetDoubleQuotes), ("$set_seed", 1) => Some(SystemClauseType::SetSeed), ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList), + ("$sleep", 1) => Some(SystemClauseType::Sleep), ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar), ("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset), ("$term_variables", 2) => Some(SystemClauseType::TermVariables), @@ -532,13 +535,13 @@ impl SystemClauseType { ("$unwind_environments", 0) => Some(SystemClauseType::UnwindEnvironments), ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack), ("$unify_with_occurs_check", 2) => Some(SystemClauseType::UnifyWithOccursCheck), - ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), - ("$use_module_from_file", 1) => - Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)), - ("$use_qualified_module", 2) => - Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule)), - ("$use_qualified_module_from_file", 2) => - Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile)), + ("$use_module", 1) => Some(SystemClauseType::REPL(REPLCodePtr::UseModule)), + ("$use_module_from_file", 1) => + Some(SystemClauseType::REPL(REPLCodePtr::UseModuleFromFile)), + ("$use_qualified_module", 2) => + Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule)), + ("$use_qualified_module_from_file", 2) => + Some(SystemClauseType::REPL(REPLCodePtr::UseQualifiedModuleFromFile)), ("$variant", 2) => Some(SystemClauseType::Variant), ("$wam_instructions", 3) => Some(SystemClauseType::WAMInstructions), ("$write_term", 6) => Some(SystemClauseType::WriteTerm), diff --git a/src/prolog/lib/time.pl b/src/prolog/lib/time.pl index 97358a7d..b41d958a 100644 --- a/src/prolog/lib/time.pl +++ b/src/prolog/lib/time.pl @@ -3,17 +3,26 @@ Part of Scryer Prolog. This library provides predicates for reasoning about time. - sleep/1 should be implemented here, sleeping for a number of seconds. - In addition, this library should provide reasoning about time stamps. + Reasoning about time stamps would be a useful addition, for example + by obtaining the current time, comparing and formatting it. '$cpu_new' can be replaced by statistics/2 once that is implemented. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -:- module(time, [time/1]). +:- module(time, [sleep/1, time/1]). :- use_module(library(format)). :- use_module(library(iso_ext)). +sleep(T) :- + builtins:must_be_number(T, sleep), + ( T < 0 -> + throw(domain_error(not_less_than_zero, T)) + ; T > 0xfffffffffffffbff -> + throw(domain_error(not_great_than_0xfffffffffffffbff, T)) + ; '$sleep'(T) + ). + time(Goal) :- '$cpu_now'(T0), setup_call_cleanup(true, diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index d838aadf..a9b5688a 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -3092,6 +3092,22 @@ impl MachineState { if let Err(err) = self.skip_max_list() { return Err(err); }, + &SystemClauseType::Sleep => { + let time = self.store(self.deref(self[temp_v!(1)])); + + let time = match Number::try_from((time, &self.heap)) { + Ok(Number::Float(OrderedFloat(n))) => n, + Ok(Number::Fixnum(n)) => n as f64, + Ok(Number::Integer(n)) => n.to_f64(), + _ => { + unreachable!() + } + }; + + let duration = Duration::new(1, 0); + let duration = duration.mul_f64(time); + ::std::thread::sleep(duration); + } &SystemClauseType::StoreGlobalVar => { let key = self[temp_v!(1)];