]> Repositorios git - scryer-prolog.git/commitdiff
Move argv/1 to library(os)
authorAdrián Arroyo Calle <[email protected]>
Tue, 2 Jan 2024 12:16:11 +0000 (13:16 +0100)
committerAdrián Arroyo Calle <[email protected]>
Tue, 2 Jan 2024 12:16:11 +0000 (13:16 +0100)
build/instructions_template.rs
src/bin/scryer-prolog.rs
src/lib/os.pl
src/loader.pl
src/machine/dispatch.rs
src/machine/mod.rs
src/machine/system_calls.rs
src/toplevel.pl

index fee8e28fa36c819bba15f00d3513b68b9312c293..43c5ffb839816737d18810ddbdc3b9a3f82a239d 100644 (file)
@@ -604,6 +604,8 @@ enum SystemClauseType {
     KeySortWithConstantVarOrdering,
     #[strum_discriminants(strum(props(Arity = "0", Name = "$inference_limit_exceeded")))]
     InferenceLimitExceeded,
+    #[strum_discriminants(strum(props(Arity = "1", Name = "$argv")))]
+    Argv,
     REPL(REPLCodePtr),
 }
 
@@ -1869,6 +1871,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::CallRemoveModuleExports |
                     &Instruction::CallAddNonCountedBacktracking |
                     &Instruction::CallPopCount |
+                    &Instruction::CallArgv |
                     &Instruction::CallEd25519SignRaw |
                     &Instruction::CallEd25519VerifyRaw |
                     &Instruction::CallEd25519SeedToPublicKey => {
@@ -2104,6 +2107,7 @@ fn generate_instruction_preface() -> TokenStream {
                     &Instruction::ExecuteRemoveModuleExports |
                     &Instruction::ExecuteAddNonCountedBacktracking |
                     &Instruction::ExecutePopCount |
+                    &Instruction::ExecuteArgv |
                     &Instruction::ExecuteEd25519SignRaw |
                     &Instruction::ExecuteEd25519VerifyRaw |
                     &Instruction::ExecuteEd25519SeedToPublicKey => {
index 572eb2fa54f2c3dcc8d4b16d0bd1553fbbc1a37c..9ae807731a17a912dd5f24c2c02c05681280afea 100644 (file)
@@ -23,6 +23,6 @@ fn main() -> std::process::ExitCode {
 
     runtime.block_on(async move {
         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))
     })
 }
index 5d31b5ced24cb952b1a353239685eeb2d592cdb4..a991bd6c04d146e71999379f4aa4d0166fc2fbb9 100644 (file)
@@ -23,7 +23,9 @@ finding out the PID of the running system.
                unsetenv/1,
                shell/1,
                shell/2,
-               pid/1]).
+               pid/1,
+              raw_argv/1,
+              argv/1]).
 
 :- use_module(library(error)).
 :- use_module(library(charsio)).
@@ -110,3 +112,32 @@ permitted('_').
 must_be_chars(Cs) :-
         must_be(list, 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 = []
+    ).
index 18b04abf2c007fd67d1921071bfa2537f851abb1..c859fce65429c8c1df86c2b7dfdb90947a99e11c 100644 (file)
@@ -138,7 +138,7 @@ file_load_cleanup(Evacuable, Error) :-
     load_context(Module),
     abolish(Module:'$initialization_goals'/1),
     unload_evacuable(Evacuable),
-    (  clause('$toplevel':argv(_), _) ->
+    (  clause('$toplevel':started, _) ->
        % let the toplevel call loader:write_error/1
        throw(Error)
     ;  '$print_message_and_fail'(Error)
index 29f05401d628ead7880c0e80a5f812c2dd7bdb61..b83b6d520e6939d00922e61ede01e4fa13339604 100644 (file)
@@ -4147,6 +4147,14 @@ impl Machine {
                         try_or_throw!(self.machine_st, self.js_eval());
                         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 => {
                         self.current_time();
                         step_or_fail!(self, self.machine_st.p += 1);
index 431592c8aa92761d3f7f55c13ad6de9c649973bc..6f5bdfe765c3b6afe10eb0eb8c8fbe1271fc8312 100644 (file)
@@ -228,7 +228,7 @@ impl Machine {
         self.machine_st.throw_exception(err);
     }
 
-    fn run_module_predicate(
+    pub fn run_module_predicate(
         &mut self,
         module_name: Atom,
         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) {
         self.user_input = Stream::from_owned_string(input, &mut self.machine_st.arena);
     }
index 631cf6266ffdf455a1e18f6fe94f43827a6f99ba..075e882caa6ad9a0356707266b1578a8131665bb 100644 (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)]
     pub(crate) fn current_time(&mut self) {
         let timestamp = self.systemtime_to_timestamp(SystemTime::now());
index 997ebad9e144d3967532a11e3e3fac8ab3971cdf..1b7e63a705e87f56097cafdd8e3768e6fef44f89 100644 (file)
@@ -1,5 +1,4 @@
-:- module('$toplevel', [argv/1,
-                        copy_term/3]).
+:- module('$toplevel', [copy_term/3, started/0]).
 
 :- use_module(library(atts), [call_residue_vars/2]).
 :- use_module(library(charsio)).
@@ -9,11 +8,13 @@
 :- use_module(library(lambda)).
 :- use_module(library(lists)).
 :- use_module(library(si)).
+:- use_module(library(os)).
 
 :- use_module(library('$project_atts')).
 :- use_module(library('$atts')).
 
 :- dynamic(disabled_init_file/0).
+:- dynamic(started/0).
 
 load_scryerrc :-
     (  '$home_directory'(HomeDir) ->
@@ -26,24 +27,18 @@ load_scryerrc :-
     ;  true
     ).
 
-:- dynamic(argv/1).
-
-'$repl'([_|Args0]) :-
-    \+ argv(_),
-    (   append(Args1, ["--"|Args2], Args0) ->
-        asserta('$toplevel':argv(Args2)),
+'$repl' :-
+    asserta('$toplevel':started),    
+    raw_argv(Args0),
+    (   append(Args1, ["--"|_], Args0) ->
         Args = Args1
-    ;   asserta('$toplevel':argv([])),
-        Args = Args0
+    ;   Args = Args0
     ),
-    delegate_task(Args, []),
-    (\+ disabled_init_file -> load_scryerrc ; true),
-    repl.
-'$repl'(_) :-
-    (   \+ argv(_) -> asserta('$toplevel':argv([]))
+    (   Args = [_|TaskArgs] ->
+       delegate_task(TaskArgs, [])
     ;   true
     ),
-    load_scryerrc,
+    (\+ disabled_init_file -> load_scryerrc ; true),
     repl.
 
 delegate_task([], []).