Move argv/1 to library(os)

This commit is contained in:
Adrián Arroyo Calle
2024-01-02 13:16:11 +01:00
parent 781f4afe25
commit 47b5ae7984
8 changed files with 79 additions and 43 deletions

View File

@@ -604,6 +604,8 @@ enum SystemClauseType {
KeySortWithConstantVarOrdering, KeySortWithConstantVarOrdering,
#[strum_discriminants(strum(props(Arity = "0", Name = "$inference_limit_exceeded")))] #[strum_discriminants(strum(props(Arity = "0", Name = "$inference_limit_exceeded")))]
InferenceLimitExceeded, InferenceLimitExceeded,
#[strum_discriminants(strum(props(Arity = "1", Name = "$argv")))]
Argv,
REPL(REPLCodePtr), REPL(REPLCodePtr),
} }
@@ -1869,6 +1871,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::CallRemoveModuleExports | &Instruction::CallRemoveModuleExports |
&Instruction::CallAddNonCountedBacktracking | &Instruction::CallAddNonCountedBacktracking |
&Instruction::CallPopCount | &Instruction::CallPopCount |
&Instruction::CallArgv |
&Instruction::CallEd25519SignRaw | &Instruction::CallEd25519SignRaw |
&Instruction::CallEd25519VerifyRaw | &Instruction::CallEd25519VerifyRaw |
&Instruction::CallEd25519SeedToPublicKey => { &Instruction::CallEd25519SeedToPublicKey => {
@@ -2104,6 +2107,7 @@ fn generate_instruction_preface() -> TokenStream {
&Instruction::ExecuteRemoveModuleExports | &Instruction::ExecuteRemoveModuleExports |
&Instruction::ExecuteAddNonCountedBacktracking | &Instruction::ExecuteAddNonCountedBacktracking |
&Instruction::ExecutePopCount | &Instruction::ExecutePopCount |
&Instruction::ExecuteArgv |
&Instruction::ExecuteEd25519SignRaw | &Instruction::ExecuteEd25519SignRaw |
&Instruction::ExecuteEd25519VerifyRaw | &Instruction::ExecuteEd25519VerifyRaw |
&Instruction::ExecuteEd25519SeedToPublicKey => { &Instruction::ExecuteEd25519SeedToPublicKey => {

View File

@@ -23,6 +23,6 @@ fn main() -> std::process::ExitCode {
runtime.block_on(async move { runtime.block_on(async move {
let mut wam = machine::Machine::new(Default::default()); let mut wam = machine::Machine::new(Default::default());
wam.run_top_level(atom!("$toplevel"), (atom!("$repl"), 1)) wam.run_module_predicate(atom!("$toplevel"), (atom!("$repl"), 0))
}) })
} }

View File

@@ -23,7 +23,9 @@ finding out the PID of the running system.
unsetenv/1, unsetenv/1,
shell/1, shell/1,
shell/2, shell/2,
pid/1]). pid/1,
raw_argv/1,
argv/1]).
:- use_module(library(error)). :- use_module(library(error)).
:- use_module(library(charsio)). :- use_module(library(charsio)).
@@ -110,3 +112,32 @@ permitted('_').
must_be_chars(Cs) :- must_be_chars(Cs) :-
must_be(list, Cs), must_be(list, Cs),
maplist(must_be(character), Cs). maplist(must_be(character), Cs).
%% raw_argv(-Argv)
%
% True iff Argv is the list of arguments that this program was started with (usually passed via command line).
% In contrast to `argv/1`, this version includes every argument, without any postprocessing, just as the operating
% system reports it to the system. This includes-flags of Scryer itself, which are not needed in general.
raw_argv(Argv) :-
can_be(list, Argv),
'$argv'(Argv).
%% argv(-Argv)
%
% True if Argv is the list of arguments that this program was started with (usually passed via command line).
% In this version, only arguments specific to the program are passed. To differentiate between the system
% arguments and the program arguments, we use `--` as a separator.
%
% Example:
% ```
% % Call with scryer-prolog -f -- -t hello
% ?- argv(X).
% X = ["-t", "hello"].
% ```
argv(Argv) :-
can_be(list, Argv),
'$argv'(Argv0),
( append(_, ["--"|Argv], Argv0) ->
true
; Argv = []
).

View File

@@ -138,7 +138,7 @@ file_load_cleanup(Evacuable, Error) :-
load_context(Module), load_context(Module),
abolish(Module:'$initialization_goals'/1), abolish(Module:'$initialization_goals'/1),
unload_evacuable(Evacuable), unload_evacuable(Evacuable),
( clause('$toplevel':argv(_), _) -> ( clause('$toplevel':started, _) ->
% let the toplevel call loader:write_error/1 % let the toplevel call loader:write_error/1
throw(Error) throw(Error)
; '$print_message_and_fail'(Error) ; '$print_message_and_fail'(Error)

View File

@@ -4147,6 +4147,14 @@ impl Machine {
try_or_throw!(self.machine_st, self.js_eval()); try_or_throw!(self.machine_st, self.js_eval());
step_or_fail!(self, self.machine_st.p = self.machine_st.cp); step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
} }
&Instruction::CallArgv => {
try_or_throw!(self.machine_st, self.argv());
step_or_fail!(self, self.machine_st.p += 1);
}
&Instruction::ExecuteArgv => {
try_or_throw!(self.machine_st, self.argv());
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
}
&Instruction::CallCurrentTime => { &Instruction::CallCurrentTime => {
self.current_time(); self.current_time();
step_or_fail!(self, self.machine_st.p += 1); step_or_fail!(self, self.machine_st.p += 1);

View File

@@ -228,7 +228,7 @@ impl Machine {
self.machine_st.throw_exception(err); self.machine_st.throw_exception(err);
} }
fn run_module_predicate( pub fn run_module_predicate(
&mut self, &mut self,
module_name: Atom, module_name: Atom,
key: PredicateKey, key: PredicateKey,
@@ -307,29 +307,6 @@ impl Machine {
} }
} }
pub fn run_top_level(
&mut self,
module_name: Atom,
key: PredicateKey,
) -> std::process::ExitCode {
let mut arg_pstrs = vec![];
for arg in env::args() {
arg_pstrs.push(put_complete_string(
&mut self.machine_st.heap,
&arg,
&self.machine_st.atom_tbl,
));
}
self.machine_st.registers[1] = heap_loc_as_cell!(iter_to_heap_list(
&mut self.machine_st.heap,
arg_pstrs.into_iter()
));
self.run_module_predicate(module_name, key)
}
pub fn set_user_input(&mut self, input: String) { pub fn set_user_input(&mut self, input: String) {
self.user_input = Stream::from_owned_string(input, &mut self.machine_st.arena); self.user_input = Stream::from_owned_string(input, &mut self.machine_st.arena);
} }

View File

@@ -4950,6 +4950,27 @@ impl Machine {
} }
} }
#[inline(always)]
pub(crate) fn argv(&mut self) -> CallResult {
let args = self.deref_register(1);
let mut args_pstrs = vec![];
for arg in env::args() {
args_pstrs.push(put_complete_string(
&mut self.machine_st.heap,
&arg,
&self.machine_st.atom_tbl,
));
}
let cell = heap_loc_as_cell!(iter_to_heap_list(
&mut self.machine_st.heap,
args_pstrs.into_iter()
));
unify!(self.machine_st, args, cell);
Ok(())
}
#[inline(always)] #[inline(always)]
pub(crate) fn current_time(&mut self) { pub(crate) fn current_time(&mut self) {
let timestamp = self.systemtime_to_timestamp(SystemTime::now()); let timestamp = self.systemtime_to_timestamp(SystemTime::now());

View File

@@ -1,5 +1,4 @@
:- module('$toplevel', [argv/1, :- module('$toplevel', [copy_term/3, started/0]).
copy_term/3]).
:- use_module(library(atts), [call_residue_vars/2]). :- use_module(library(atts), [call_residue_vars/2]).
:- use_module(library(charsio)). :- use_module(library(charsio)).
@@ -9,11 +8,13 @@
:- use_module(library(lambda)). :- use_module(library(lambda)).
:- use_module(library(lists)). :- use_module(library(lists)).
:- use_module(library(si)). :- use_module(library(si)).
:- use_module(library(os)).
:- use_module(library('$project_atts')). :- use_module(library('$project_atts')).
:- use_module(library('$atts')). :- use_module(library('$atts')).
:- dynamic(disabled_init_file/0). :- dynamic(disabled_init_file/0).
:- dynamic(started/0).
load_scryerrc :- load_scryerrc :-
( '$home_directory'(HomeDir) -> ( '$home_directory'(HomeDir) ->
@@ -26,24 +27,18 @@ load_scryerrc :-
; true ; true
). ).
:- dynamic(argv/1). '$repl' :-
asserta('$toplevel':started),
'$repl'([_|Args0]) :- raw_argv(Args0),
\+ argv(_), ( append(Args1, ["--"|_], Args0) ->
( append(Args1, ["--"|Args2], Args0) ->
asserta('$toplevel':argv(Args2)),
Args = Args1 Args = Args1
; asserta('$toplevel':argv([])), ; Args = Args0
Args = Args0
), ),
delegate_task(Args, []), ( Args = [_|TaskArgs] ->
(\+ disabled_init_file -> load_scryerrc ; true), delegate_task(TaskArgs, [])
repl.
'$repl'(_) :-
( \+ argv(_) -> asserta('$toplevel':argv([]))
; true ; true
), ),
load_scryerrc, (\+ disabled_init_file -> load_scryerrc ; true),
repl. repl.
delegate_task([], []). delegate_task([], []).