@@ -38,72 +38,51 @@ static bool exit_condition = true;
3838
3939/* -- Methods -- */
4040
41- // void application::parameter_iterator::operator()(const char *parameter)
42- // {
43- // // TODO: Implement a new plugin for parsing command line options
44-
45- // std::string script(parameter);
46-
47- // /* List of file extensions mapped into loader tags */
48- // static std::unordered_map<std::string, std::string> extension_to_tag = {
49- // /* Mock Loader */
50- // { "mock", "mock" },
51- // /* Python Loader */
52- // { "py", "py" },
53- // /* Ruby Loader */
54- // { "rb", "rb" },
55- // /* C# Loader */
56- // { "cs", "cs" },
57- // { "dll", "cs" },
58- // { "vb", "cs" },
59- // /* Cobol Loader */
60- // { "cob", "cob" },
61- // { "cbl", "cob" },
62- // { "cpy", "cob" },
63- // /* NodeJS Loader */
64- // { "js", "node" },
65- // { "node", "node" },
66- // /* TypeScript Loader */
67- // { "ts", "ts" },
68- // { "jsx", "ts" },
69- // { "tsx", "ts" },
70- // /* WASM Loader */
71- // { "wasm", "wasm" },
72- // { "wat", "wasm" },
73- // /* Rust Loader */
74- // { "rs", "rs" },
75- // /* C Loader */
76- // { "c", "c" },
77- // { "h", "c" },
78- // /* Java Loader */
79- // { "java", "java" },
80- // { "jar", "java" },
81- // /* RPC Loader */
82- // { "rpc", "rpc" }
83-
84- // // TODO: Implement handling of duplicated extensions, load the file with all loaders (trial and error)
85-
86- // // /* Extension Loader */
87- // // { "so", "ext" },
88- // // { "dylib", "ext" },
89- // // { "dll", "ext" },
90-
91- // /* Note: By default js extension uses NodeJS loader instead of JavaScript V8 */
92- // /* Probably in the future we can differenciate between them, but it is not trivial */
93- // };
94-
95- // const std::string tag = extension_to_tag[script.substr(script.find_last_of(".") + 1)];
96- // const std::string safe_tag = tag != "" ? tag : "file"; /* Use File Loader if the tag is not found */
97-
98- // /* Load the script */
99- // void *args[2] = {
100- // metacall_value_create_string(safe_tag.c_str(), safe_tag.length()),
101- // metacall_value_create_string(script.c_str(), script.length())
102- // };
103-
104- // app.invoke("load", args, 2);
105- // exit_condition = true;
106- // }
41+ void application::repl ()
42+ {
43+ /* Initialize CLI plugin */
44+ if (!load_path (" cli" , &plugin_cli_handle))
45+ {
46+ /* Do not enter into the main loop */
47+ exit_condition = true ;
48+ return ;
49+ }
50+
51+ /* Register exit function */
52+ auto exit = [](size_t argc, void *args[], void *data) -> void * {
53+ (void )args;
54+ (void )data;
55+
56+ /* Validate function parameters */
57+ if (argc != 0 )
58+ {
59+ std::cout << " Invalid number of arguments passed to exit, expected 0, received: " << argc << std::endl;
60+ }
61+
62+ std::cout << " Exiting ..." << std::endl;
63+
64+ /* Exit from main loop */
65+ exit_condition = true ;
66+
67+ return NULL ;
68+ };
69+
70+ int result = metacall_register_loaderv (metacall_loader (" ext" ), plugin_cli_handle, " exit" , exit, METACALL_INVALID, 0 , NULL );
71+
72+ if (result != 0 )
73+ {
74+ std::cout << " Exit function was not registered properly, return code: " << result << std::endl;
75+ }
76+ else
77+ {
78+ /* Start the main loop */
79+ exit_condition = false ;
80+ }
81+
82+ void *ret = metacallhv_s (plugin_repl_handle, " initialize" , metacall_null_args, 0 );
83+
84+ check_for_exception (ret);
85+ }
10786
10887application::application (int argc, char *argv[]) :
10988 plugin_cli_handle(NULL ), plugin_repl_handle(NULL )
@@ -121,76 +100,55 @@ application::application(int argc, char *argv[]) :
121100 /* Print MetaCall information */
122101 metacall_print_info ();
123102
124- /* Initialize REPL plugins */
103+ /* Initialize REPL plugin */
125104 if (!load_path (" repl" , &plugin_repl_handle))
126105 {
127106 /* Do not enter into the main loop */
128107 exit_condition = true ;
129- plugin_repl_handle = NULL ;
130108 return ;
131109 }
132110
133111 if (argc == 1 )
134112 {
135- void *ret = metacallhv_s (plugin_repl_handle, " initialize" , metacall_null_args, 0 );
136-
137- check_for_exception (ret);
113+ /* Launch the REPL */
114+ repl ();
138115 }
139116 else
140117 {
141118 void *arguments_parse_func = metacall_handle_function (plugin_repl_handle, " arguments_parse" );
142119
143120 if (arguments_parse_func == NULL )
144121 {
122+ std::cout << " Warning: CLI Arguments Parser was not loaded, "
123+ " using fallback argument parser with positional arguments only. "
124+ << std::endl
125+ << " Any command line option like '--help' will result into error. "
126+ " Only files are allowed: $ metacall a.py b.js c.rb"
127+ << std::endl;
128+
145129 /* Use fallback parser, it can execute files but does not support command line arguments as options (i.e: -h, --help) */
146130 /* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */
131+ std::vector<std::string> arguments (argv + 1 , argv + argc);
147132
148- // TODO
149- exit_condition = true ;
150- return ;
133+ arguments_parse_fallback (arguments);
151134 }
152135 else
153136 {
154137 /* TODO: Implement a new plugin for parsing command line options */
155138 std::cout << " TODO: CLI Arguments Parser Plugin is not implemented yet" << std::endl;
156- exit_condition = true ;
157- return ;
158- }
159- }
160-
161- /* Initialize CLI plugins */
162- if (load_path (" cli" , &plugin_cli_handle))
163- {
164- /* Register exit function */
165- auto exit = [](size_t argc, void *args[], void *data) -> void * {
166- (void )args;
167- (void )data;
168-
169- /* Validate function parameters */
170- if (argc != 0 )
171- {
172- std::cout << " Invalid number of arguments passed to exit, expected 0, received: " << argc << std::endl;
173- }
174-
175- std::cout << " Exiting ..." << std::endl;
176139
177- /* Exit from main loop */
178- exit_condition = true ;
179-
180- return NULL ;
181- };
182-
183- int result = metacall_register_loaderv (metacall_loader (" ext" ), plugin_cli_handle, " exit" , exit, METACALL_INVALID, 0 , NULL );
184-
185- if (result != 0 )
186- {
187- std::cout << " Exit function was not registered properly, return code: " << result << std::endl;
188- }
189- else
190- {
191- /* Start the main loop */
192- exit_condition = false ;
140+ /* Note: If it has zero positional arguments, we should also run the repl, for example:
141+ * $ metacall --some-option --another-option --yeet
142+ */
143+ // TODO:
144+ // if (positional_arguments_size == 0)
145+ // {
146+ // /* Initialize the REPL */
147+ // repl();
148+ // }
193149 }
150+
151+ exit_condition = true ;
194152 }
195153}
196154
@@ -204,6 +162,74 @@ application::~application()
204162 }
205163}
206164
165+ void application::arguments_parse_fallback (std::vector<std::string> &arguments)
166+ {
167+ /* List of file extensions mapped into loader tags */
168+ static std::unordered_map<std::string, std::string> extension_to_tag = {
169+ /* Mock Loader */
170+ { " mock" , " mock" },
171+ /* Python Loader */
172+ { " py" , " py" },
173+ /* Ruby Loader */
174+ { " rb" , " rb" },
175+ /* C# Loader */
176+ { " cs" , " cs" },
177+ { " dll" , " cs" },
178+ { " vb" , " cs" },
179+ /* Cobol Loader */
180+ { " cob" , " cob" },
181+ { " cbl" , " cob" },
182+ { " cpy" , " cob" },
183+ /* NodeJS Loader */
184+ { " js" , " node" },
185+ { " node" , " node" },
186+ /* TypeScript Loader */
187+ { " ts" , " ts" },
188+ { " jsx" , " ts" },
189+ { " tsx" , " ts" },
190+ /* WASM Loader */
191+ { " wasm" , " wasm" },
192+ { " wat" , " wasm" },
193+ /* Rust Loader */
194+ { " rs" , " rs" },
195+ /* C Loader */
196+ { " c" , " c" },
197+ { " h" , " c" },
198+ /* Java Loader */
199+ { " java" , " java" },
200+ { " jar" , " java" },
201+ /* RPC Loader */
202+ { " rpc" , " rpc" }
203+
204+ // TODO: Implement handling of duplicated extensions, load the file with all loaders (trial and error)
205+
206+ // /* Extension Loader */
207+ // { "so", "ext" },
208+ // { "dylib", "ext" },
209+ // { "dll", "ext" },
210+
211+ /* Note: By default js extension uses NodeJS loader instead of JavaScript V8 */
212+ /* Probably in the future we can differenciate between them, but it is not trivial */
213+ };
214+
215+ for (std::string script : arguments)
216+ {
217+ const std::string tag = extension_to_tag[script.substr (script.find_last_of (" ." ) + 1 )];
218+ const std::string safe_tag = tag != " " ? tag : " file" ; /* Use File Loader if the tag is not found */
219+
220+ /* Load the script */
221+ const char *scripts[1 ] = {
222+ script.c_str ()
223+ };
224+
225+ if (metacall_load_from_file (safe_tag.c_str (), scripts, 1 , NULL ) != 0 )
226+ {
227+ /* Stop loading more scripts */
228+ return ;
229+ }
230+ }
231+ }
232+
207233bool application::load_path (const char *path, void **handle)
208234{
209235 /* Get core plugin path and handle in order to load cli plugins */
0 commit comments